Skip to content

Commit

Permalink
adding basic-helm-spring-boot pipeline (#153)
Browse files Browse the repository at this point in the history
* adding basic-helm-spring-boot pipeline

* updating jenkins-agent-helm BC triggers. Adding validation documentation

* adding image trigger annotation to deployment
  • Loading branch information
deweya committed Oct 20, 2020
1 parent b9c8a1f commit ca9e5fd
Show file tree
Hide file tree
Showing 16 changed files with 295 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The following is a list of the pipeline samples available in this repository:

- [Basic Tomcat](./basic-tomcat) - Builds a Java Application like Ticket Monster and deploys it to Tomcat
- [Basic Spring Boot](./basic-spring-boot) - Builds a Spring Boot application and deploys using an Embedded Servlet jar file
- [Basic Helm Spring Boot](./basic-helm-spring-boot) - Builds and deploys a Spring Boot application using Helm charts
- [Blue Green Spring Boot](./blue-green-spring) - Build a Spring Boot application and deploys it using a blue-green deployment
- [Secure Spring Boot](./secure-spring-boot) - Build a Spring Boot app and deploy with a pipeline that includes code coverage reports, dependency scanning, sonarqube analysis
- [Cross Cluster Promotion Pipeline](./multi-cluster-spring-boot) - A [declarative syntax](https://jenkins.io/doc/book/pipeline/syntax/#declarative-pipeline) pipeline that demonstrates promoting a microservice between clusters (i.e. a Non-Production to a Production cluster)
Expand Down
4 changes: 4 additions & 0 deletions basic-helm-spring-boot/.helm/jenkins-agent-helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v2
name: jenkins-agent-helm
description: A chart for building the jenkins-agent-helm Jenkins agent, containing Helm, ct, and oc
version: 1.0.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
labels:
application: {{ .Release.Name }}
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
spec:
output:
to:
kind: ImageStreamTag
name: {{ .Release.Name }}:{{ .Values.destTag }}
source:
type: Git
git:
uri: {{ .Values.uri }}
ref: {{ .Values.ref }}
contextDir: {{ .Values.contextDir }}
strategy:
dockerStrategy:
dockerfilePath: {{ .Values.dockerfilePath }}
type: Docker
triggers:
- type: ConfigChange
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
labels:
application: {{ .Release.Name }}
role: jenkins-slave
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
8 changes: 8 additions & 0 deletions basic-helm-spring-boot/.helm/jenkins-agent-helm/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
destTag: latest

uri: https://github.com/redhat-cop/containers-quickstarts.git
ref: master

contextDir: jenkins-agents/jenkins-agent-helm

dockerfilePath: Dockerfile
4 changes: 4 additions & 0 deletions basic-helm-spring-boot/.helm/spring-boot-build/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v2
name: spring-boot-build
description: A chart for building your Spring Boot app
version: 1.0.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
labels:
app.kubernetes.io/name: {{ .Values.name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
name: {{ .Values.name }}
spec:
output:
to:
kind: ImageStreamTag
name: {{ .Values.name }}:{{ required "value 'tag' is required" .Values.tag }}
source:
type: Binary
binary: {}
strategy:
sourceStrategy:
from:
kind: ImageStreamTag
name: {{ .Values.builderImageStreamTag }}
namespace: {{ .Values.builderImageStreamNamespace }}
type: Source
triggers: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
labels:
app.kubernetes.io/name: {{ .Values.name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
name: {{ .Values.name }}
5 changes: 5 additions & 0 deletions basic-helm-spring-boot/.helm/spring-boot-build/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Required (provided by pipeline)
tag:

builderImageStreamTag: java:8
builderImageStreamNamespace: openshift
4 changes: 4 additions & 0 deletions basic-helm-spring-boot/.helm/spring-boot/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v2
name: spring-boot
description: A chart for deploying your Spring Boot app
version: 1.0.0
40 changes: 40 additions & 0 deletions basic-helm-spring-boot/.helm/spring-boot/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
annotations:
image.openshift.io/triggers: |-
[
{
"from":{
"kind":"ImageStreamTag",
"name":"{{ .Release.Name }}:{{ .Values.tag }}"
},
"fieldPath":"spec.template.spec.containers[0].image"
}
]
spec:
replicas: {{ .Values.replicas }}
selector:
matchLabels:
app.kubernetes.io/name: {{ .Release.Name }}
strategy:
type: {{ .Values.strategy }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Release.Name }}
spec:
containers:
- name: {{ .Release.Name }}
image: {{ .Release.Name }}:{{ .Values.tag }}
imagePullPolicy: Always
{{- if .Values.enableLiveness }}
readinessProbe:
httpGet:
path: /
port: {{ .Values.port }}
{{- end }}
11 changes: 11 additions & 0 deletions basic-helm-spring-boot/.helm/spring-boot/templates/route.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: {{ .Release.Name }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
to:
kind: Service
name: {{ .Release.Name }}
12 changes: 12 additions & 0 deletions basic-helm-spring-boot/.helm/spring-boot/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
labels:
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
ports:
- port: {{ .Values.port }}
selector:
app.kubernetes.io/name: {{ .Release.Name }}
10 changes: 10 additions & 0 deletions basic-helm-spring-boot/.helm/spring-boot/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Required (provided by pipeline)
tag:

replicas: 1

port: 8080

enableReadiness: true

strategy: Recreate
69 changes: 69 additions & 0 deletions basic-helm-spring-boot/Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
library identifier: "pipeline-library@v1.5",
retriever: modernSCM(
[
$class: "GitSCMSource",
remote: "https://github.com/redhat-cop/pipeline-library.git"
]
)

// URL and Ref to the Spring Boot application
appSourceUrl = "https://github.com/redhat-cop/spring-rest.git"
appSourceRef = "master"

// Folder containing the Spring Boot application
appFolder = "spring-rest"

// Folder containing the Helm pipeline
helmFolder = "basic-helm-spring-boot"

// The name you want to give your Spring Boot application
// Each resource related to your app will be given this name
appName = "my-app"

pipeline {
agent { label "jenkins-agent-helm" }
stages {
stage("Checkout") {
steps {
// This creates a separate folder to clone the Spring Boot app to
sh "mkdir ${appFolder}"
dir(appFolder) {
git url: "${appSourceUrl}", branch: "${appSourceRef}"
}
}
}
stage("Get Version from POM") {
steps {
script {
dir(appFolder) {
tag = readMavenPom().getVersion()
}
}
}
}
stage("S2I Build") {
steps {
// This installs or upgrades the spring-boot-build Helm chart.
// It creates or updates your application's BuildConfig and ImageStream
dir(helmFolder) {
sh "helm upgrade --install ${appName}-build .helm/spring-boot-build --set name=${appName} --set tag=${tag}"
}

// This uploads your application's source code and performs a binary build in OpenShift
dir(appFolder) {
binaryBuild(buildConfigName: appName, buildFromPath: ".")
}
}
}
stage("Deploy") {
steps {
// This installs or upgrades the spring-boot Helm chart
// It creates or updates your application's Kubernetes resources
// It also waits until the readiness probe returns successfully
dir(helmFolder) {
sh "helm upgrade --install ${appName} .helm/spring-boot --set tag=${tag} --wait"
}
}
}
}
}
65 changes: 65 additions & 0 deletions basic-helm-spring-boot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# A Sample OpenShift Pipeline for a Spring Boot Application Using Helm

This Jenkins pipeline provides an example of how to build a [basic Spring Boot application](https://github.com/redhat-cop/spring-rest) using Helm. The pipeline runs using the CoP's [jenkins-agent-helm](https://github.com/redhat-cop/containers-quickstarts/tree/master/jenkins-agents/jenkins-agent-helm) agent and contains the following steps:

1. `Checkout`: Checks out the spring-rest application
1. `Get Version From POM`: Gets the version defined in the pom.xml file. This version is used to set your image's tag.
1. `S2I Build`: Performs an [s2i build](https://docs.openshift.com/container-platform/4.5/builds/understanding-image-builds.html#build-strategy-s2i_understanding-image-builds). This stage runs your unit tests, builds your jar file, and builds your container image. You could split this stage like the [basic-spring-boot](../basic-spring-boot) example if desired, but the jenkins-agent-helm agent doesn't have maven on it, so in this case, it's easier to perform an s2i build instead.
1. `Deploy`: Deploys your application to OpenShift.

This pipeline uses two different Helm charts called [spring-boot-build](./spring-boot-build) and [spring-boot](./spring-boot). The `spring-boot-build` chart is used in the `S2I Build` stage to create and update your BuildConfig and ImageStream. The `spring-boot` chart is used in the `Deploy` stage to create and update your application's Kubernetes resources. While you could combine both of these charts into one, splitting into separate charts for building and deploying provides a greater separation of concerns.

Before you configure this pipeline, you must first build a Jenkins agent containing Helm. Let's look at how you can build the [jenkins-agent-helm](https://github.com/redhat-cop/containers-quickstarts/tree/master/jenkins-agents/jenkins-agent-helm) agent.

## Building the jenkins-agent-helm Agent
While the pipeline itself only uses the spring-boot and spring-boot-build Helm charts, a third Helm chart is provided under the `.helm/` folder called `jenkins-agent-helm` that you can use to easily build this Jenkins agent. First, install the jenkins-agent-helm Helm chart, which creates a BuildConfig and ImageStream:

```bash
helm install jenkins-agent-helm .helm/jenkins-agent-helm
```

The first build will automatically run. You can follow this build by running:

```bash
oc logs bc/jenkins-agent-helm -f
```

This ImageStream created by Helm already has the `role: jenkins-slave` label, so Jenkins will see this and automatically use this image to configure a new Jenkins agent.

Next, let's configure the Jenkins pipeline.

## Configuring This Jenkins Pipeline

Because the `JenkinsPipeline` build strategy is deprecated in OpenShift 4.x, this doc will describe how you can configure this pipeline manually within the Jenkins console.

First, deploy a Jenkins instance to OpenShift. You can deploy Jenkins by running this command:

```bash
oc new-app jenkins-persistent
```

Once Jenkins is up, find and access your route URL:

```bash
oc get route jenkins -o jsonpath='{.spec.host}'
```

Then, follow these steps:

1. Click `New Item` on the lefthand side of the screen
1. Enter a name for this pipeline. The suggested name is `basic-helm-spring-boot`.
1. Select `Pipeline` and click `Ok`
1. Scroll down to the bottom of the screen to the `Pipeline` section. Change the "Pipeline script" dropdown to `Pipeline script from SCM`.
1. For "SCM", select `Git` and enter the Repository URL `https://github.com/redhat-cop/container-pipelines.git`
1. For "Script Path", enter `basic-helm-spring-boot/Jenkinsfile`
1. Click `Save`

Once you configure your pipeline, you can click `Build Now` on the lefthand side of your screen to start the pipeline.

## Validating Your Deployment
You can validate your deployment was successful with the following commands:

```bash
ROUTE=$(oc get route my-app -o jsonpath='{.spec.host}')
curl $ROUTE/v1/greeting
```

0 comments on commit ca9e5fd

Please sign in to comment.