Monday, 21 August 2017

OpenShift Pipelines Integration - Tutorial

Welcome to the blog series OpenShift A-Z. If you are new here, please refer to my first blogpost OpenShift A-Z

In this blogpost we will take an real world use case and try to configure an CICD pipeline for a sample app. You may refer this as a step-by-step tutorial to achieve it.

Use case
In the use case for this demonstration, a developer wants to deploy a new CICD pipeline to manage and monitor the application development life cycle.
  • In this scenario, the application goes through different stages and moves between them up to the production stage.
  • Production deployments happen with an user's manual acceptance.
Following diagram shows the overall workflow that we are going to achieve.

1. Prerequisite to implement this demo

This demonstration requires preparation before the demonstration can start.
Please note the following:

1.1. Install Command Line Tools

  1. You can download OpenShift Command Line Tools from OpenShift web console.
  2. Unpack the file and copy the extracted oc file to /usr/bin
  3. You can test your ability to authenticate to OpenShift with the CLI tool:
$export REGION="na" ; export USERNAME=<your-username>
$ oc login https://master.${REGION} --username ${USERNAME}
Password: **********
Login successful.

1.2. Create Projects for Demonstration

  1. Create a few projects for your demonstration:
oc new-project pipeline-${GUID}-dev --description="Cat of the Day Development Environment" --display-name="Cat Of The Day - Dev"
oc new-project pipeline-${GUID}-test --description="Cat of the Day Testing Environment" --display-name="Cat Of The Day - Test"
oc new-project pipeline-${GUID}-prod --description="Cat of the Day Production Environment" --display-name="Cat Of The Day - Prod"
  1. Display your created projects:
oc get projects
Sample Output
oc get projects

NAME                   DISPLAY NAME            STATUS
pipeline-mydemo-dev    Cat Of The Day - Dev    Active
pipeline-mydemo-prod   Cat Of The Day - Prod   Active
pipeline-mydemo-test   Cat Of The Day - Test   Active

  1. Switch back to your dev project where most of the work needs to be done:
oc project pipeline-${GUID}-dev

1.3. Deploy the CICD Environment

  1. Deploy Jenkins to control your builds and deployment pipeline:
oc new-app jenkins-persistent -n pipeline-${GUID}-dev
Sample Output
--> Deploying template "jenkins-persistent" in project "openshift" for "jenkins-persistent"
    With parameters:
     Jenkins Service Name=jenkins
     Jenkins JNLP Service Name=jenkins-jnlp
     Jenkins Password=openshiftpipelines
     Memory Limit=512Mi
     Volume Capacity=1Gi
     Jenkins ImageStream Namespace=openshift
     Jenkins ImageStreamTag=jenkins:latest
--> Creating resources ...
   route "jenkins" created
   persistentvolumeclaim "jenkins" created
   deploymentconfig "jenkins" created
   serviceaccount "jenkins" created
   rolebinding "jenkins_edit" created
   service "jenkins-jnlp" created
   service "jenkins" created
--> Success
   Run 'oc status' to view your app.
  1. You can login to Jenkins with OpenShift
  2. Enable the Jenkins service account to manage resources in the pipeline-${GUID}-test and pipeline-${GUID}-prod projects:
oc policy add-role-to-user edit system:serviceaccount:pipeline-${GUID}-dev:jenkins -n pipeline-${GUID}-test
oc policy add-role-to-user edit system:serviceaccount:pipeline-${GUID}-dev:jenkins -n pipeline-${GUID}-prod
  1. Enable the pulling of images from the pipeline-${GUID}-dev project to the pipeline-${GUID}-test and pipeline-${GUID}-prod projects:
oc policy add-role-to-group system:image-puller system:serviceaccounts:pipeline-${GUID}-test -n pipeline-${GUID}-dev
oc policy add-role-to-group system:image-puller system:serviceaccounts:pipeline-${GUID}-prod -n pipeline-${GUID}-dev

1.4. Deploy Mock Applications

  1. Before creating a pipeline, let’s try deploying an sample application by ourselves.
  2. Deploy the "Cat of The Day" (cotd) application in the dev project:
oc new-app -n pipeline-${GUID}-dev
  1. You can check logs of this build with:
    oc logs -f build/cotd-1 -n pipeline-${GUID}-dev
  2. Check that the build has completed and tag the image:
oc tag cotd:latest cotd:testready -n pipeline-${GUID}-dev
oc tag cotd:testready cotd:prodready -n pipeline-${GUID}-dev
  1. Check the image stream to see that the tags were created:
oc describe is cotd -n pipeline-${GUID}-dev

Name: cotd
Created: About an hour ago
Labels: app=cotd
Docker Pull Spec:

Tag Spec Created PullSpec Image
latest <pushed> About an hour ago <same>
prodready cotd@sha256:21c16f04309942... About an hour ago <same>
testready cotd@sha256:21c16f04309942... About an hour ago <same>
  1. Deploy the cotd application in the test and prod projects:
oc new-app pipeline-${GUID}-dev/cotd:testready --name=cotd -n pipeline-${GUID}-test
oc new-app pipeline-${GUID}-dev/cotd:prodready --name=cotd -n pipeline-${GUID}-prod
  1. Create routes for all three applications:
oc expose service cotd -n pipeline-${GUID}-dev
oc expose service cotd -n pipeline-${GUID}-test
oc expose service cotd -n pipeline-${GUID}-prod
  1. Disable automatic deployment for all deployment configurations in your demonstration:
oc get dc cotd -o yaml -n pipeline-${GUID}-dev | sed 's/automatic: true/automatic: false/g' | oc replace -f -
oc get dc cotd -o yaml -n pipeline-${GUID}-test| sed 's/automatic: true/automatic: false/g' | oc replace -f -
oc get dc cotd -o yaml -n pipeline-${GUID}-prod | sed 's/automatic: true/automatic: false/g' | oc replace -f -

2. Demonstrate OpenShift Pipelines Integration

Before you continue, verify that Jenkins is deployed and make sure you can connect to the Jenkins Web Interface, to find out the route you can use:
oc get routes -n pipeline-${GUID}-dev

CICD Build Config Pipeline
apiVersion: v1
kind: BuildConfig
 name: pipeline-demo
 namespace: pipeline-mydemo-dev
 selfLink: /oapi/v1/namespaces/pipeline-mydemo-dev/buildconfigs/pipeline-demo
 uid: 0a7eb238-83eb-11e7-bbc1-0682973451aa
 resourceVersion: '12249059'
 creationTimestamp: '2017-08-18T07:58:37Z'
   - type: GitHub
       secret: 5Mlic4Le
   - type: Generic
       secret: FiArdDBH
 runPolicy: Serial
   type: None
   type: JenkinsPipeline
     jenkinsfile: |
       node {
           withEnv(['GUID=mydemo']) {

           stage ("Build")
                 echo '*** Build Starting ***'
                 openshiftBuild bldCfg: 'cotd', buildName: '', checkForTriggeredDeployments: 'false', commitID: '', namespace: '', showBuildLogs: 'true', verbose: 'true'
                 openshiftVerifyBuild bldCfg: 'cotd', checkForTriggeredDeployments: 'false', namespace: '', verbose: 'false'
                 echo '*** Build Complete ***'
           stage ("Deploy and Verify in Development Env")
                 echo '*** Deployment Starting ***'
                 openshiftDeploy depCfg: 'cotd', namespace: '', verbose: 'false', waitTime: ''
                 openshiftVerifyDeployment authToken: '', depCfg: 'cotd', namespace: '', replicaCount: '1', verbose: 'false', verifyReplicaCount: 'false', waitTime: ''
                 echo '*** Deployment Complete ***'
                 echo '*** Service Verification Starting ***'
                 openshiftVerifyService apiURL: 'https://openshift.default.svc.cluster.local', authToken: '', namespace: 'pipeline-${GUID}-dev', svcName: 'cotd', verbose: 'false'
                 echo '*** Service Verification Complete ***'
                  openshiftTag(srcStream: 'cotd', srcTag: 'latest', destStream: 'cotd', destTag: 'testready')
           stage ('Deploy and Test in Testing Env')
                 echo '*** Deploy testready build in pipeline-${GUID}-test project  ***'
                 openshiftDeploy apiURL: 'https://openshift.default.svc.cluster.local', authToken: '', depCfg: 'cotd', namespace: 'pipeline-${GUID}-test', verbose: 'false', waitTime: ''

                 openshiftVerifyDeployment apiURL: 'https://openshift.default.svc.cluster.local', authToken: '', depCfg: 'cotd', namespace: 'pipeline-${GUID}-test', replicaCount: '1', verbose: 'false', verifyReplicaCount: 'false', waitTime: '10'
                 sh 'curl http://cotd-pipeline-${GUID} | grep cats -q'
           stage ('Promote and Verify in Production Env')
                 echo '*** Waiting for Input ***'
                 input 'Should we deploy to Production?'
                 openshiftTag(srcStream: 'cotd', srcTag: 'testready', destStream: 'cotd', destTag: 'prodready')
                 echo '*** Deploying to Production ***'
                 openshiftDeploy apiURL: 'https://openshift.default.svc.cluster.local', authToken: '', depCfg: 'cotd', namespace: 'pipeline-${GUID}-prod', verbose: 'false', waitTime: ''
                 openshiftVerifyDeployment apiURL: 'https://openshift.default.svc.cluster.local', authToken: '', depCfg: 'cotd', namespace: 'pipeline-${GUID}-prod', replicaCount: '1', verbose: 'false', verifyReplicaCount: 'false', waitTime: '10'
                 sleep 10
                 sh 'curl http://cotd-pipeline-${GUID} | grep cats -q'
 output: {}
 resources: {}
 postCommit: {}
 nodeSelector: null
 lastVersion: 1

Method 1: Use the command line from any host with the OpenShift client:
  1. Create a file with the contents of the Build Config pipeline sample above.
  2. Use the oc create -f FILENAME.yaml command to create the Build Config pipeline.
Method 2: Use the OpenShift web console.
  1. Log in to the OpenShift web console.
  2. Select your dev project and click Add to Project.
  3. Select the Import YAML/JSON tab, paste the Build Config pipeline text in the text box and click Create:
Import yaml.png

Test the New Pipeline

Go to Builds > Pipelines > Start Pipeline

Whats happening in the pipeline?
  1. Build: OpenShift builds and verifies a successful build.
  2. Deploy and Verify in Development Env: OpenShift deploys the latest application in the development project, verifies that the container and service were deployed correctly, and tags the image as "testready".
  3. Deploy and Test in Testing Env: OpenShift deploys the image tagged "testready" in the testing project, runs different integration tests—in this case, just a cURL command—and tags the image as "prodready" if all tests pass.
  4. Promote and Verify in Production Env: OpenShift waits for a manual approval from authorized user, then deploys and verifies the container and service in the production project.
Jenkins wait.png
Successfull deployment:
Successful deployment.png


In this tutorial, we went through the setup of complete CICD pipeline with jenkins and OpenShift.

May the PaaS be with you.



Amazon EKS - Kubernetes on AWS

By Komal Devgaonkar Amazon Elastic Container Service for Kubernetes (Amazon EKS), which is highly available and scalable AWS service....