Skip to content

Commit

Permalink
Add blue/green spring boot app
Browse files Browse the repository at this point in the history
  • Loading branch information
malacourse committed Aug 31, 2017
1 parent af5dfd5 commit 011be57
Show file tree
Hide file tree
Showing 10 changed files with 644 additions and 11 deletions.
40 changes: 29 additions & 11 deletions blue-green-spring/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# A Sample OpenShift Pipeline for Blue Green deployments

This example demonstrates how to implement a full end-to-end Jenkins Pipeline for a Java application in OpenShift Container Platform. This sample demonstrates the following capabilities:
This example demonstrates how to implement a full end-to-end Jenkins Pipeline for a Java application in a Blue/Green deployment in the OpenShift Container Platform. This sample demonstrates the following capabilities:

* Deploying an integrated Jenkins server inside of OpenShift
* Running both custom and oob Jenkins slaves as pods in OpenShift
* "One Click" instantiation of a Jenkins Pipeline using OpenShift's Jenkins Pipeline Strategy feature
* Promotion of an application's container image within an OpenShift Cluster (using `oc tag`)
* Tagging images with the current version of the artifact defined in the pom.xml file
* Promotion of an application's container image to a blue/green production configuration
* Switching production routes between blue and green deployments after confirmation

## Quickstart

Expand All @@ -26,22 +28,28 @@ oc process -f build/basic-java-template.yml --param-file build/dev/params | oc a

### OpenShift Templates

The components of this pipeline are divided into two templates.
The components of this pipeline are divided into three templates.

The first template, `build/simple-spring-boot-template.yml` is what we are calling the "Build" template. It contains:

* A `jenkinsPipelineStrategy` BuildConfig
* An `s2i` BuildConfig
* An ImageStream for the s2i build config to push to

The build template contains a default source code repo for a java application compatible with this pipelines architecture (https://github.com/etsauer/ticket-monster).
The build template contains a default source code repo for a java application compatible with this pipelines architecture (https://github.com/malacourse/simple-spring-boot-web).

The second template, `deploy/simple-spring-boot-template.yml` is the "Deploy" template. It contains:

* A tomcat8 DeploymentConfig
* A openjdk8 DeploymentConfig
* A Service definition
* A Route

The third template, `deploy/simple-spring-boot-template-prod.yml` is the "Deploy" template for a blue/green project. It contains:

* Two openjdk8 DeploymentConfig's
* Two Service definition's
* A Route

The idea behind the split between the templates is that I can deploy the build template only once (to my dev project) and that the pipeline will promote my image through all of the various stages of my application's lifecycle. The deployment template gets deployed once to each of the stages of the application lifecycle (once per OpenShift project).

### Pipeline Script
Expand All @@ -52,13 +60,13 @@ This project includes a sample `pipeline.groovy` Jenkins Pipeline script that co
* The `pipeline.groovy` script is placed in the same directory as the `pom.xml` file in the git source.
* The OpenShift projects that represent the Application's lifecycle stages are of the naming format: `<app-name>-dev`, `<app-name>-stage`, `<app-name>-prod`.

For convenience, this pipeline script is already included in the following git repository, based on the [JBoss Developers Ticket Monster](https://github.com/jboss-developer/ticket-monster) app.
For convenience, this pipeline script is already included in the following git repository, based on a [Simple Spring Boot Web app](https://github.com/malacourse/simple-spring-boot-web) app. The app displays a message that will change color based on which deployment is live in the production project.

https://github.com/etsauer/ticket-monster
https://github.com/malacourse/simple-spring-boot-web

## Bill of Materials

* One or Two OpenShift Container Platform Clusters
* One OpenShift Container Platform Clusters
* OpenShift 3.5+ is required.
* Access to GitHub

Expand Down Expand Up @@ -97,15 +105,25 @@ service "jenkins" created

### 4. Instantiate Pipeline

A _deploy template_ is provided at `deploy/simple-spring-boot-template.yml` that defines all of the resources required to run our Tomcat application. It includes:
A _deploy template_ is provided at `deploy/simple-spring-boot-template.yml` that defines all of the resources required to run the openjdk8 application. It includes:

* A `Service`
* A `Route`
* An `ImageStream`
* A `DeploymentConfig`
* A `RoleBinding` to allow Jenkins to deploy in each namespace.

This template should be instantiated once in each of the namespaces that our app will be deployed to. For this purpose, we have created a param file to be fed to `oc process` to customize the template for each environment.
This template should be instantiated once in each of the lower level namespaces (dev, stage,qa) that our app will be deployed to. For this purpose, we have created a param file to be fed to `oc process` to customize the template for each environment.

A production blue/green_deploy template_ is provided at `deploy/simple-spring-boot-template-prod.yml` that defines all of the resources required to run the openjdk8 application. It includes:

* Two `Service's`
* A `Route`
* Two `ImageStream's`
* Two `DeploymentConfig's`
* A `RoleBinding` to allow Jenkins to deploy in each namespace.

This template should be instantiated in the production blue/green namespace that our app will be deployed to. For this purpose, we have created a param file to be fed to `oc process` to customize the template for each environment.

Deploy the deployment template to all three projects.
```
Expand All @@ -121,7 +139,7 @@ route "simple-spring-boot" created
imagestream "simple-spring-boot" created
deploymentconfig "simple-spring-boot" created
rolebinding "jenkins_edit" created
$ oc process -f deploy/simple-spring-boot-template.yml --param-file=deploy/prod/params | oc apply -f-
$ oc process -f deploy/simple-spring-boot-template-prod.yml --param-file=deploy/prod/params | oc apply -f-
service "simple-spring-boot" created
route "simple-spring-boot" created
imagestream "simple-spring-boot" created
Expand All @@ -141,7 +159,7 @@ buildconfig "simple-spring-boot-pipeline" created
buildconfig "simple-spring-boot" created
```

At this point you should be able to go to the Web Console and follow the pipeline by clicking in your `myapp-dev` project, and going to *Builds* -> *Pipelines*. At several points you will be prompted for input on the pipeline. You can interact with it by clicking on the _input required_ link, which takes you to Jenkins, where you can click the *Proceed* button. By the time you get through the end of the pipeline you should be able to visit the Route for your app deployed to the `myapp-prod` project to confirm that your image has been promoted through all stages.
At this point you should be able to go to the Web Console and follow the pipeline by clicking in your `myapp-dev` project, and going to *Builds* -> *Pipelines*. There is a prompt for input on the pipeline before the production route is switched to the new deployment. You can interact with it by clicking on the _input required_ link, which takes you to Jenkins, where you can click the *Proceed* button. By the time you get through the end of the pipeline you should be able to visit the Route for your app deployed to the `myapp-prod` project to confirm that your image has been promoted through all stages.

## Cleanup

Expand Down
102 changes: 102 additions & 0 deletions blue-green-spring/build/basic-java-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
apiVersion: v1
kind: Template
labels:
template: generic-java-jenkins-pipeline
metadata:
annotations:
description: Application template for JWS applications built using a Jenkins Pipeline
iconClass: icon-tomcat
tags: tomcat,tomcat8,java,jboss,xpaas,jenkins-ci
version: 1.2.0
name: generic-java-jenkins-pipeline
objects:
- kind: "BuildConfig"
apiVersion: "v1"
metadata:
labels:
application: ${APPLICATION_NAME}
name: "${APPLICATION_NAME}-pipeline"
namespace: "${NAMESPACE}"
spec:
source:
type: Git
git:
uri: ${SOURCE_REPOSITORY_URL}
ref: ${SOURCE_REPOSITORY_REF}
contextDir: ${CONTEXT_DIR}
triggers:
- type: "GitHub"
github:
secret: ${GITHUB_WEBHOOK_SECRET}
- type: "ConfigChange"
strategy:
type: "JenkinsPipeline"
jenkinsPipelineStrategy:
jenkinsfilePath: ${PIPELINE_SCRIPT}
env:
- name: "BUILD_CONTEXT_DIR"
value: "demo"
- apiVersion: v1
kind: BuildConfig
metadata:
labels:
application: ${APPLICATION_NAME}
name: ${APPLICATION_NAME}
namespace: "${NAMESPACE}"
spec:
output:
to:
kind: ImageStreamTag
name: ${APPLICATION_NAME}:latest
source:
binary: {}
type: Binary
strategy:
sourceStrategy:
from:
kind: ImageStreamTag
name: ${IMAGE_STREAM_TAG_NAME}
namespace: ${IMAGE_STREAM_NAMESPACE}
type: Source
parameters:
- description: The name for the application.
name: APPLICATION_NAME
required: true
value: simple-spring-boot
- description: The namespace to deploy into
name: NAMESPACE
required: true
- description: Git source URI for application
name: SOURCE_REPOSITORY_URL
required: true
value: https://github.com/malacourse/simple-spring-boot-web.git
- description: Git branch/tag reference
name: SOURCE_REPOSITORY_REF
value: "master"
- description: Path within Git project to build; empty for root project directory.
name: CONTEXT_DIR
value:
- description: Path within Git project pointing to the pipeline run script
name: PIPELINE_SCRIPT
value: pipeline.groovy
- description: GitHub trigger secret
from: '[a-zA-Z0-9]{8}'
generate: expression
name: GITHUB_WEBHOOK_SECRET
required: true
- description: Generic build trigger secret
from: '[a-zA-Z0-9]{8}'
generate: expression
name: GENERIC_WEBHOOK_SECRET
required: true
- description: Namespace in which the ImageStreams for Red Hat Middleware images are
installed. These ImageStreams are normally installed in the openshift namespace.
You should only need to modify this if you've installed the ImageStreams in a
different namespace/project.
name: IMAGE_STREAM_NAMESPACE
required: true
value: openshift
- description: Image stream tag for the image you'd like to use to build the application
name: IMAGE_STREAM_TAG_NAME
required: true
value: redhat-openjdk18-openshift:1.1
3 changes: 3 additions & 0 deletions blue-green-spring/build/dev/params
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
APPLICATION_NAME=spring-boot-web
NAMESPACE=simple-spring-boot-dev
IMAGE_STREAM_TAG_NAME=redhat-openjdk18-openshift:1.1
3 changes: 3 additions & 0 deletions blue-green-spring/deploy/dev/params
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
APPLICATION_NAME=spring-boot-web
NAMESPACE=simple-spring-boot-dev
SA_NAMESPACE=simple-spring-boot-dev
4 changes: 4 additions & 0 deletions blue-green-spring/deploy/prod/params
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
APPLICATION_NAME=spring-boot-web
NAMESPACE=simple-spring-boot-prod
SA_NAME=jenkins
SA_NAMESPACE=simple-spring-boot-dev
Loading

0 comments on commit 011be57

Please sign in to comment.