Message Image  

An approach to build a DevOps pipeline for IBM App Connect Designer Flows on Cloud Pak for Integration

 View Only
Tue July 28, 2020 09:46 AM

We had published a blog in developerWorks that discusses an approach to build a DevOps pipeline for IBM App Connect Enterprise on Cloud Pak for Integration. This blog is in continuation to that and discusses how you can extend the same approach to build and deploy IBM App Connect Designer flows on CP4I.

Link to Library article: An approach to build DevOps pipeline for ACE on Cloud Pak for Integration

In most common scenarios, you might need to deploy related App Connect Designer flows and App Connect Enterprise flows on the same integration server. In this blog, we will demonstrate one such scenario.

Here we assume that you have already configured the build server for deploying ACE flows as described in the above blog. If not done yet, you may first follow the steps mentioned in the above blog.

We have published a command line utility to convert App Connect designer yaml files to ACE BAR files. This blog makes use of this utility.
https://github.com/ot4i/bar-build

Look at the link below to understand the pre-requisites for deploying App Connect designer flows onto ACE integration servers.
https://www.ibm.com/support/knowledgecenter/en/SSTTDS_11.0.0/com.ibm.ace.icp.doc/run-designerflow-in-acesoftware/prereqs4apiflows.html

Step 1. Install the bar-build utility

Make sure that you have npm module and required dependencies installed on the build server.
https://www.npmjs.com/package/@ibm-app-connect/bar-build

For example, to install on Ubuntu:

apt install npm
npm install -g npx
npm install @ibm-app-connect/bar-build

npx bar-build <path-to-flow-yaml-file> <path-to-new-bar-file>

Step 2. Configure the App Connect Designer project and Build Job

For this demonstration, we will create two additional folders inside the App Connect project:

  • Properties folder: This folder will contain properties files for different environments, e.g. DEV.properties and QA.properties. These properties files would contain the environment specific parameter values to be used in the mqsiapplybaroverride command to override environment specific properties.
  • Build folder: This folder will contain the Jenkins pipeline script for the App Connect project. So the build script for the App Connect project is also checked-in to source control.

For this demonstration, I have created one App Connect designer project and one ACE toolkit project which are checked-in at the location below:

AppConnect designer project: https://github.com/awasthan/Designer_Slack_Alert_API
AppConnect toolkit project: https://github.com/awasthan/Test.App

Let us examine the ‘jenkinsfile’ script for the App Connect designer project.

When you deploy the exported BAR file for an API flow in your cluster, you can indicate whether you want to use cloud-managed connectors to run API operations on the applications that are referenced in the flow. To use cloud-managed connectors, access to an App Connect on IBM Cloud instance is required.

In this example, I have used a Slack connector, which is a cloud managed connector. Follow the Knowledge Center link below to understand the required configurations for the cloud managed connector:
https://www.ibm.com/support/knowledgecenter/en/SSTTDS_11.0.0/com.ibm.ace.icp.doc/run-designerflow-in-acesoftware/overridebarconfig.html

Let us examine one properties file that is used to override the BAR files for an environment.

You can run the mqsireadbar command to get the list of properties in the BAR file, which can be overridden.

Now let us create the Jenkins build job for this Designer_Slack_Alert_API project.

Create a Jenkins pipeline project with the name ‘Designer_Slack_Alert_API’.

Specify to read the pipeline script from SCM and enter the GitHub project location, credential to access GitHub and the path of the jenkinsfile in the project.

Click on Save.

Now build the project so that it uploads the BAR files on repository and tags the code. The build-output below shows a successful build of Designer_Slack_Alert_API project.

Started by user anand
Obtained build/jenkinsfile from git https://github.ibm.com/anand-awasthi/Designer_Slack_Alert_API.git
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] timestamps
[Pipeline] {
[Pipeline] node
[2020-05-27T11:16:17.928Z] Running on Jenkins in /var/lib/jenkins/jobs/Designer_Slack_Alert_API/workspace
[Pipeline] {
[Pipeline] wrap
[2020-05-27T11:16:17.946Z] Xvfb starting$ /usr/bin/Xvfb :0 -screen 0 1024x768x24 -fbdir /var/lib/jenkins/xvfb-19-..fbdir8000674658225554562
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Designer_Slack_Alert_API - Checkout)
[Pipeline] checkout
[2020-05-27T11:16:17.984Z] using credential jenkins-token
[2020-05-27T11:16:17.987Z] Cloning the remote Git repository
[2020-05-27T11:16:17.987Z] Cloning repository https://github.ibm.com/anand-awasthi/Designer_Slack_Alert_API.git
[2020-05-27T11:16:17.988Z]  > /usr/bin/git init /var/lib/jenkins/jobs/Designer_Slack_Alert_API/workspace # timeout=10
[2020-05-27T11:16:17.995Z] Fetching upstream changes from https://github.ibm.com/anand-awasthi/Designer_Slack_Alert_API.git
[2020-05-27T11:16:17.995Z]  > /usr/bin/git --version # timeout=10
[2020-05-27T11:16:18.000Z] using GIT_ASKPASS to set credentials 
[2020-05-27T11:16:18.001Z]  > /usr/bin/git fetch --tags --progress -- https://github.ibm.com/anand-awasthi/Designer_Slack_Alert_API.git +refs/heads/*:refs/remotes/origin/* # timeout=10
[2020-05-27T11:16:18.428Z]  > /usr/bin/git config remote.origin.url https://github.ibm.com/anand-awasthi/Designer_Slack_Alert_API.git # timeout=10
[2020-05-27T11:16:18.433Z]  > /usr/bin/git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
[2020-05-27T11:16:18.439Z]  > /usr/bin/git config remote.origin.url https://github.ibm.com/anand-awasthi/Designer_Slack_Alert_API.git # timeout=10
[2020-05-27T11:16:18.444Z] Fetching upstream changes from https://github.ibm.com/anand-awasthi/Designer_Slack_Alert_API.git
[2020-05-27T11:16:18.444Z] using GIT_ASKPASS to set credentials 
[2020-05-27T11:16:18.444Z]  > /usr/bin/git fetch --tags --progress -- https://github.ibm.com/anand-awasthi/Designer_Slack_Alert_API.git +refs/heads/*:refs/remotes/origin/* # timeout=10
[2020-05-27T11:16:18.743Z]  > /usr/bin/git rev-parse refs/remotes/origin/master^{commit} # timeout=10
[2020-05-27T11:16:18.749Z]  > /usr/bin/git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
[2020-05-27T11:16:18.754Z] Checking out Revision 444a1e097737d1ac989f82367e2d048961aaaf33 (refs/remotes/origin/master)
[2020-05-27T11:16:18.754Z]  > /usr/bin/git config core.sparsecheckout # timeout=10
[2020-05-27T11:16:18.759Z]  > /usr/bin/git checkout -f 444a1e097737d1ac989f82367e2d048961aaaf33 # timeout=10
[2020-05-27T11:16:18.766Z]  > /usr/bin/git branch -a -v --no-abbrev # timeout=10
[2020-05-27T11:16:18.772Z]  > /usr/bin/git checkout -b master 444a1e097737d1ac989f82367e2d048961aaaf33 # timeout=10
[2020-05-27T11:16:18.781Z] Commit message: "Update jenkinsfile"
[2020-05-27T11:16:18.781Z]  > /usr/bin/git rev-list --no-walk a269ca0004c788caed3fdd41e221b6f022affdc0 # timeout=10
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Designer_Slack_Alert_API - Build)
[Pipeline] sh
[2020-05-27T11:16:21.328Z] WARN engine message-catalog-manager@2.2.2: wanted: {"node":"4.4","npm":"3.x"} (current: {"node":"8.10.0","npm":"3.5.2"})
[2020-05-27T11:16:25.453Z] /var/lib/jenkins/jobs/Designer_Slack_Alert_API/workspace
[2020-05-27T11:16:25.453Z] └─┬ @ibm-app-connect/bar-build@0.0.2 
[2020-05-27T11:16:25.453Z]   ├─┬ archiver@4.0.1 
[2020-05-27T11:16:25.453Z]   │ ├─┬ archiver-utils@2.1.0 
[2020-05-27T11:16:25.453Z]   │ │ ├── graceful-fs@4.2.4 
[2020-05-27T11:16:25.453Z]   │ │ ├─┬ lazystream@1.0.0 
[2020-05-27T11:16:25.453Z]   │ │ │ └── readable-stream@2.3.7 
[2020-05-27T11:16:25.453Z]   │ │ ├── lodash.defaults@4.2.0 
[2020-05-27T11:16:25.453Z]   │ │ ├── lodash.difference@4.5.0 
[2020-05-27T11:16:25.453Z]   │ │ ├── lodash.flatten@4.4.0 
[2020-05-27T11:16:25.453Z]   │ │ ├── lodash.isplainobject@4.0.6 
[2020-05-27T11:16:25.453Z]   │ │ ├── lodash.union@4.6.0 
[2020-05-27T11:16:25.453Z]   │ │ ├── normalize-path@3.0.0 
[2020-05-27T11:16:25.453Z]   │ │ └─┬ readable-stream@2.3.7 
[2020-05-27T11:16:25.453Z]   │ │   ├── core-util-is@1.0.2 
[2020-05-27T11:16:25.453Z]   │ │   ├── isarray@1.0.0 
[2020-05-27T11:16:25.453Z]   │ │   ├── process-nextick-args@2.0.1 
[2020-05-27T11:16:25.453Z]   │ │   └── safe-buffer@5.1.2 
[2020-05-27T11:16:25.453Z]   │ ├─┬ async@2.6.3 
[2020-05-27T11:16:25.453Z]   │ │ └── lodash@4.17.15 
[2020-05-27T11:16:25.453Z]   │ ├── buffer-crc32@0.2.13 
[2020-05-27T11:16:25.453Z]   │ ├─┬ glob@7.1.6 
[2020-05-27T11:16:25.453Z]   │ │ ├── fs.realpath@1.0.0 
[2020-05-27T11:16:25.453Z]   │ │ ├─┬ inflight@1.0.6 
[2020-05-27T11:16:25.453Z]   │ │ │ └── wrappy@1.0.2 
[2020-05-27T11:16:25.453Z]   │ │ ├── inherits@2.0.4 
[2020-05-27T11:16:25.453Z]   │ │ ├─┬ minimatch@3.0.4 
[2020-05-27T11:16:25.453Z]   │ │ │ └─┬ brace-expansion@1.1.11 
[2020-05-27T11:16:25.453Z]   │ │ │   ├── balanced-match@1.0.0 
[2020-05-27T11:16:25.453Z]   │ │ │   └── concat-map@0.0.1 
[2020-05-27T11:16:25.453Z]   │ │ ├── once@1.4.0 
[2020-05-27T11:16:25.453Z]   │ │ └── path-is-absolute@1.0.1 
[2020-05-27T11:16:25.453Z]   │ ├─┬ readable-stream@3.6.0 
[2020-05-27T11:16:25.453Z]   │ │ ├── string_decoder@1.1.1 
[2020-05-27T11:16:25.453Z]   │ │ └── util-deprecate@1.0.2 
[2020-05-27T11:16:25.453Z]   │ ├─┬ tar-stream@2.1.2 
[2020-05-27T11:16:25.453Z]   │ │ ├─┬ bl@4.0.2 
[2020-05-27T11:16:25.453Z]   │ │ │ └─┬ buffer@5.6.0 
[2020-05-27T11:16:25.453Z]   │ │ │   ├── base64-js@1.3.1 
[2020-05-27T11:16:25.453Z]   │ │ │   └── ieee754@1.1.13 
[2020-05-27T11:16:25.453Z]   │ │ ├── end-of-stream@1.4.4 
[2020-05-27T11:16:25.453Z]   │ │ └── fs-constants@1.0.0 
[2020-05-27T11:16:25.453Z]   │ └─┬ zip-stream@3.0.1 
[2020-05-27T11:16:25.453Z]   │   └─┬ compress-commons@3.0.0 
[2020-05-27T11:16:25.453Z]   │     ├─┬ crc32-stream@3.0.1 
[2020-05-27T11:16:25.453Z]   │     │ └── crc@3.8.0 
[2020-05-27T11:16:25.453Z]   │     └── readable-stream@2.3.7 
[2020-05-27T11:16:25.453Z]   ├─┬ handlebars@4.7.6 
[2020-05-27T11:16:25.453Z]   │ ├── minimist@1.2.5 
[2020-05-27T11:16:25.453Z]   │ ├── neo-async@2.6.1 
[2020-05-27T11:16:25.453Z]   │ ├── source-map@0.6.1 
[2020-05-27T11:16:25.453Z]   │ ├─┬ uglify-js@3.9.4 
[2020-05-27T11:16:25.453Z]   │ │ └── commander@2.20.3 
[2020-05-27T11:16:25.453Z]   │ └── wordwrap@1.0.0 
[2020-05-27T11:16:25.453Z]   ├─┬ js-yaml@3.14.0 
[2020-05-27T11:16:25.453Z]   │ ├─┬ argparse@1.0.10 
[2020-05-27T11:16:25.453Z]   │ │ └── sprintf-js@1.0.3 
[2020-05-27T11:16:25.453Z]   │ └── esprima@4.0.1 
[2020-05-27T11:16:25.453Z]   ├── jsonata@1.8.3 
[2020-05-27T11:16:25.453Z]   ├─┬ message-catalog-manager@2.2.2 
[2020-05-27T11:16:25.453Z]   │ ├── fs@0.0.2 
[2020-05-27T11:16:25.453Z]   │ └── underscore@1.10.2 
[2020-05-27T11:16:25.453Z]   └── yazl@2.5.1 
[2020-05-27T11:16:25.453Z] 
[2020-05-27T11:16:25.453Z] npm WARN enoent ENOENT: no such file or directory, open '/var/lib/jenkins/jobs/Designer_Slack_Alert_API/workspace/package.json'
[2020-05-27T11:16:25.453Z] npm WARN workspace No description
[2020-05-27T11:16:25.453Z] npm WARN workspace No repository field.
[2020-05-27T11:16:25.453Z] npm WARN workspace No README data
[2020-05-27T11:16:25.453Z] npm WARN workspace No license field.
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Designer_Slack_Alert_API - Deploy)
[Pipeline] sh
[2020-05-27T11:16:26.975Z] BIP1138I: Applying overrides using runtime mqsiapplybaroverride...
[2020-05-27T11:16:26.975Z] BIP1140I: Overriding property gen.Designer_Slack_Alert_API#connectorServiceInstanceId with 'a6kv05h8' in 'Designer_Slack_Alert_API.appzip/META-INF/broker.xml' ...
[2020-05-27T11:16:26.975Z] BIP1140I: Overriding property gen.Designer_Slack_Alert_API#connectorServiceUrl with 'https://firefly-api-produk.eu-gb.appconnect.ibm.com' in 'Designer_Slack_Alert_API.appzip/META-INF/broker.xml' ...
[2020-05-27T11:16:26.975Z] BIP1143I: Saving Bar file Designer_Slack_Alert_API_DEV_19.bar...
[2020-05-27T11:16:26.975Z] 
[2020-05-27T11:16:26.975Z] BIP8071I: Successful command completion.
[2020-05-27T11:16:27.227Z]   adding: Designer_Slack_Alert_API_DEV_19.bar (deflated 5%)
[Pipeline] }
[Pipeline] // stage
[Pipeline] nexusArtifactUploader
[2020-05-27T11:16:27.259Z] Uploading artifact Designer_Slack_Alert_API.zip started....
[2020-05-27T11:16:27.259Z] GroupId: com.ibm.esb
[2020-05-27T11:16:27.260Z] ArtifactId: com.ibm.esb
[2020-05-27T11:16:27.260Z] Classifier: 
[2020-05-27T11:16:27.260Z] Type: zip
[2020-05-27T11:16:27.260Z] Version: 19
[2020-05-27T11:16:27.260Z] File: Designer_Slack_Alert_API.zip
[2020-05-27T11:16:27.260Z] Repository:releases
[2020-05-27T11:16:27.261Z] Uploading: https://127.0.0.1:8444/nexus/repository/releases/com/ibm/esb/Designer_Slack_Alert_API/19/Designer_Slack_Alert_API-19.zip
[2020-05-27T11:16:27.263Z] 51 % completed (4.1 kB / 7.9 kB).
[2020-05-27T11:16:27.275Z] 100 % completed (7.9 kB / 7.9 kB).
[2020-05-27T11:16:27.323Z] Uploaded: https://127.0.0.1:8444/nexus/repository/releases/com/ibm/esb/Designer_Slack_Alert_API/19/Designer_Slack_Alert_API-19.zip (7.9 kB at 127 kB/s)
[2020-05-27T11:16:27.323Z] Uploading artifact Designer_Slack_Alert_API.zip completed.
[Pipeline] sshagent
[2020-05-27T11:16:27.338Z] FATAL: [ssh-agent] Could not find specified credentials
[2020-05-27T11:16:27.338Z] [ssh-agent] Looking for ssh-agent implementation...
[2020-05-27T11:16:27.343Z] [ssh-agent]   Exec ssh-agent (binary ssh-agent on a remote machine)
[2020-05-27T11:16:27.344Z] $ ssh-agent
[2020-05-27T11:16:27.349Z] SSH_AUTH_SOCK=/tmp/ssh-7dQbDEMej02f/agent.64700
[2020-05-27T11:16:27.349Z] SSH_AGENT_PID=64703
[2020-05-27T11:16:27.349Z] [ssh-agent] Started.
[Pipeline] {
[Pipeline] sh
[2020-05-27T11:16:27.626Z] + git tag -a Designer_Slack_Alert_API_19 -m Tagged by Jenkins build
[Pipeline] sh
[2020-05-27T11:16:27.894Z] + git push git@github.ibm.com:anand-awasthi/Designer_Slack_Alert_API.git --tags
[2020-05-27T11:16:30.380Z] remote: detect-secrets-stream (beta) ver=164-1ac7e673b9acf31ed1ba86a8422cf59cb8a848be FAQ: https://ibm.biz/detect-secrets-stream-faq        
[2020-05-27T11:16:30.380Z] remote: 
[2020-05-27T11:16:30.380Z] remote: Successfully send push metadata.        
[2020-05-27T11:16:30.380Z] remote: Push info collect pre-receive hook finished within 3 seconds.        
[2020-05-27T11:16:30.630Z] To github.ibm.com:anand-awasthi/Designer_Slack_Alert_API.git
[2020-05-27T11:16:30.630Z]  * [new tag]         Designer_Slack_Alert_API_19 -> Designer_Slack_Alert_API_19
[Pipeline] }
[2020-05-27T11:16:30.638Z] $ ssh-agent -k
[2020-05-27T11:16:30.642Z] unset SSH_AUTH_SOCK;
[2020-05-27T11:16:30.642Z] unset SSH_AGENT_PID;
[2020-05-27T11:16:30.642Z] echo Agent pid 64703 killed;
[2020-05-27T11:16:30.644Z] [ssh-agent] Stopped.
[Pipeline] // sshagent
[Pipeline] }
[2020-05-27T11:16:30.661Z] Xvfb stopping
[Pipeline] // wrap
[Pipeline] cleanWs
[2020-05-27T11:16:30.710Z] [WS-CLEANUP] Deleting project workspace...
[2020-05-27T11:16:30.710Z] [WS-CLEANUP] Deferred wipeout is used...
[2020-05-27T11:16:30.713Z] [WS-CLEANUP] done
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // timestamps
[Pipeline] End of Pipeline
Finished: SUCCESS

Now let us look at the Nexus repository to see if BAR files for this version (version 19 here) have been uploaded. The snapshot below shows the zip file containing the version 19 BAR files.

Now let us look at Github if the Designer_Slack_Alert_API source code has been tagged with version 19. The snippet below shows the tag.

We will deploy this ACE designer project with the ACE toolkit ‘Test.App’ project that we created for the demo in the blog mentioned below. Refer to the article below to look at the ‘Test.App’ example project.
An approach to build DevOps pipeline for ACE on Cloud Pak for Integration

Step 3. Configure Deployment Job

Now configure the deployment jobs for each environment. You may have a single parameterized job to deploy to different CP4I environments; however due to security and compliance reasons, you would probably have different deployment jobs for respective environments.

Before the Integration Server starts, the container is checked for the folder /home/aceuser/initial-config.
Refer to https://github.com/ot4i/ace-docker to understand how to supply the required configuration information for Integration Server.

Since we are going to deploy an ACE designer project and an ACE toolkit project on one integration server, we need to make sure integration server configurations are done for both projects as appropriate.
We can have a deployment project containing configuration information, Dockerfile and Jenkinsfile as depicted in the diagram below.

I have a sample deployment job that contains these two files and a Configurations folder.

The sample deployment job is checked-in to Github:
https://github.com/awasthan/Deploy_Slack_API_CP4I.git

  • Dockerfile: This file will have instructions to build the image baked with BAR files
  • Jenkinsfile: This file will have the pipeline script to deploy to the CP4I environment, and create the Horizontal Pod autoscalar policy etc…
  • Configurations: To do other configurations on IntegrationServer, you must pre-install the configuration secret containing the required configurations. A generic template for configuration parameters and a script to generate secrets can be downloaded from the platform navigator while doing manual deployment.

In this sample project, I have done integration server configuration to connect to the cloud managed connector (for Slack connector used in designer flow) and have also configured the Integration server to connect to an IBM EventStreams instance.
Let us look at the setdbparms.txt file inside ‘Configurations’ folder.

The first two lines are for setting-up the truststore password and securityIdentity to be used by the ACE flow; while the third line is to setup security identity for the designer flow to connect to the Cloud managed connector. Follow the below link to create IBM Cloud API key:
https://www.ibm.com/support/knowledgecenter/en/SSTTDS_11.0.0/com.ibm.ace.icp.doc/run-designerflow-in-acesoftware/creatingapikey.html

Let us examine the Dockerfile.

Let us examine the parts of jenkinsfile. This pipeline has been parameterized to accept some parameters dynamically. It does following tasks:

  • Checks-out the deployment project
  • Pulls the specified versions (ACE_APP1_VERSION and ACE_APP2_VERSION) of BAR files from Nexus repository for ACE_APP1 and ACE_APP2.
  • Logs-in to the OCP registry of a specified CP4I instance
  • Builds the docker image using the Dockerfile and DEV BAR files and pushes to the OCP registry
  • Executes the generateSecrets.sh script to create secret using the configuration files inside ‘Configurations’ folder
  • Performs helm deployment. Notice the name of ACE image (image.aceonly) in helm install command. Since we are using ace only image, so value of ‘imageType’ has been specified as ‘ace’. If you are using ACE with MQ client or ACE with MQ server, the value of ‘imageType’ would be ‘acemqclient’ and ‘acemqserver’ respectively. Make sure to specify the image parameter based on imageType. Also notice that ‘designerFlowsOperationMode=all’ enables for local and cloud managed connectors.
  • If it is a new helm release being installed, horizontal autoscalar policy (hpa) is being created
  • If it is an upgrade to existing helm release, it only upgrades the helm release and horizontal autoscalar policy is left unchanged
  • Performs the clean-up
timestamps {

node () {

wrap([$class: 'Xvfb']) {
	stage ('Deploy_Slack_API_CP4I - Checkout') {
 	 checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'jenkins-token', url: 'https://github.com/awasthan/Deploy_Slack_API_CP4I.git']]]) 
	}
	stage ('Deploy_Slack_API_CP4I - Build') {
 	
artifactResolver artifacts: [artifact(artifactId: '${ACE_APP1}', extension: 'zip', groupId: 'com.ibm.esb', version: '${ACE_APP1_VERSION}'), artifact(artifactId: '${ACE_APP2}', extension: 'zip', groupId: 'com.ibm.esb', version: '${ACE_APP2_VERSION}')], targetDirectory: '/var/icp-builds/${ACE_APP1}'
sh label: '', script: '''#!/bin/sh
cd /var/icp-builds/${ACE_APP1}
unzip ${ACE_APP1}-${ACE_APP1_VERSION}.zip
chmod 777 *
cp ${ACE_APP1}_DEV_${ACE_APP1_VERSION}.bar /var/lib/jenkins/jobs/${JOB_NAME}/workspace
unzip ${ACE_APP2}-${ACE_APP2_VERSION}.zip
chmod 777 *
cp ${ACE_APP2}_DEV_${ACE_APP2_VERSION}.bar /var/lib/jenkins/jobs/${JOB_NAME}/workspace
cd ${WORKSPACE}
#cloudctl login -a ${ICP_CONSOLE_URL} -n ${Namespace} -u ${CP4I_User} -p ${CP4I_Password} –-skip-ssl-validation
oc login ${OCP_API_URL} -u ${OCP_USER} -p ${OCP_PASSWORD} --insecure-skip-tls-verify
oc project ${Namespace}
docker login ${OCP_Registry_External_URL} -u $(oc whoami) -p $(oc whoami -t)
docker build -t ${imagename}:${BUILD_NUMBER} .
docker tag ${imagename}:${BUILD_NUMBER} ${OCP_Registry_External_URL}/${Namespace}/${imagename}:${tag}-amd64
docker push ${OCP_Registry_External_URL}/${Namespace}/${imagename}:${tag}-amd64
cd Configurations
#Delete the secret if already exists. It would exist in case of upgrading the release
oc delete secret ${ReleaseName}-secret
./generateSecrets.sh ${ReleaseName}-secret
source /etc/profile
cd /opt/certs
helm init --client-only
helm repo add ibm-entitled-charts https://raw.githubusercontent.com/IBM/charts/master/repo/entitled/
if test ${DeploymentType} = \'install\'; then
helm ${DeploymentType} --name $ReleaseName ibm-entitled-charts/ibm-ace-server-icp4i-prod --version v3.1.0 --namespace ${Namespace} --set imageType=ace --set designerFlowsOperationMode=all --set image.aceonly=${OCP_Registry_Internal_URL}/${Namespace}/${imagename}:${tag} --set image.acemqclient=${OCP_Registry_Internal_URL}/${Namespace}/ibm-ace-mqclient-server-prod:11.0.0.8-r1 --set image.acemq=${OCP_Registry_Internal_URL}/${Namespace}/ibm-ace-mq-server-prod:11.0.0.8-r1 --set image.configurator=${OCP_Registry_Internal_URL}/${Namespace}/ibm-ace-icp-configurator-prod:11.0.0.8-r1 --set image.connectors=${OCP_Registry_Internal_URL}/${Namespace}/ibm-ace-lcp-prod:11.0.0.8-r1 --set image.designerflows=${OCP_Registry_Internal_URL}/${Namespace}/ibm-ace-designer-flows-prod:11.0.0.8-r1 --set image.pullSecret=${IMAGE_PULL_SECRET} --set persistence.enabled=false --set persistence.useDynamicProvisioning=false --set integrationServer.name=${IntegrationServerName} --set integrationServer.configurationSecret=${ReleaseName}-secret --set integrationServer.truststoreCertNames=mykey --set aceonly.replicaCount=1 --set odTracingConfig.enabled=true --set odTracingConfig.odAgentImageRepository=${OCP_Registry_Internal_URL}/${Namespace}/icp4i-od-agent --set odTracingConfig.odAgentImageTag=1.0.2 --set odTracingConfig.odCollectorImageRepository=${OCP_Registry_Internal_URL}/${Namespace}/icp4i-od-collector --set odTracingConfig.odCollectorImageTag=1.0.2 --set odTracingConfig.odTracingNamespace=tracing --set license=accept --tls
oc project ${Namespace}
#Helm chart version 3.1.0 creates route, so commenting out below command to expose route
#oc expose svc ${ReleaseName}-ibm-ace-server-icp4i-prod --port=7800
oc autoscale deployment/${ReleaseName}-ibm-ace-server-icp4i-prod --min 1 --max 3 --cpu-percent=25
else
helm ${DeploymentType} $ReleaseName ibm-entitled-charts/ibm-ace-server-icp4i-prod --version v3.1.0 --namespace ${Namespace} --set imageType=ace --set designerFlowsOperationMode=all --set image.aceonly=${OCP_Registry_Internal_URL}/${Namespace}/${imagename}:${tag} --set image.acemqclient=${OCP_Registry_Internal_URL}/${Namespace}/ibm-ace-mqclient-server-prod:11.0.0.8-r1 --set image.acemq=${OCP_Registry_Internal_URL}/${Namespace}/ibm-ace-mq-server-prod:11.0.0.8-r1 --set image.configurator=${OCP_Registry_Internal_URL}/${Namespace}/ibm-ace-icp-configurator-prod:11.0.0.8-r1 --set image.connectors=${OCP_Registry_Internal_URL}/${Namespace}/ibm-ace-lcp-prod:11.0.0.8-r1 --set image.designerflows=${OCP_Registry_Internal_URL}/${Namespace}/ibm-ace-designer-flows-prod:11.0.0.8-r1 --set image.pullSecret=${IMAGE_PULL_SECRET} --set persistence.enabled=false --set persistence.useDynamicProvisioning=false --set integrationServer.name=${IntegrationServerName} --set integrationServer.configurationSecret=${ReleaseName}-secret --set integrationServer.truststoreCertNames=mykey --set aceonly.replicaCount=1 --set odTracingConfig.enabled=true --set odTracingConfig.odAgentImageRepository=${OCP_Registry_Internal_URL}/${Namespace}/icp4i-od-agent --set odTracingConfig.odAgentImageTag=1.0.2 --set odTracingConfig.odCollectorImageRepository=${OCP_Registry_Internal_URL}/${Namespace}/icp4i-od-collector --set odTracingConfig.odCollectorImageTag=1.0.2 --set odTracingConfig.odTracingNamespace=tracing --set license=accept --tls
fi
cd /var/icp-builds
rm -rf ${ACE_APP1}
rm -rf ${ACE_APP2}''' 
	}
}
cleanWs()
}
}

Now let us look at the Jenkins pipeline Job for this.
Parameters have been defined for all the placeholders in above jenkinsfile.

Pipeline script has been configured to pull from Github.

Similarly you can configure deployment job for QA environment and so on.

Step 4. Perform Deployment

Now let us deploy an IntegrationServer that contains version 18 of ‘Designer_Slack_Alert_API’ and version 20 for ‘Test.App’. Also note that, the base image of ACE being pulled in docker file is version 11.0.0.8.

Click on ‘Build with Parameters’ for the deployment job and supply the values for parameters.

Click on Build.

Below is the snippet of build logs.

Started by user anand
Obtained jenkinsfile from git https://github.ibm.com/anand-awasthi/Deploy_Slack_API_CP4I.git
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] timestamps
[Pipeline] {
[Pipeline] node
[2020-05-27T07:09:14.586Z] Running on Jenkins in /var/lib/jenkins/jobs/Deploy_Slack_API_CP4I/workspace
[Pipeline] {
[Pipeline] wrap
[2020-05-27T07:09:14.606Z] Xvfb starting$ /usr/bin/Xvfb :0 -screen 0 1024x768x24 -fbdir /var/lib/jenkins/xvfb-6-..fbdir5015161639313609410
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Deploy_Slack_API_CP4I - Checkout)
[Pipeline] checkout
[2020-05-27T07:09:14.649Z] using credential jenkins-token
[2020-05-27T07:09:14.655Z] Cloning the remote Git repository
[2020-05-27T07:09:14.655Z] Cloning repository https://github.ibm.com/anand-awasthi/Deploy_Slack_API_CP4I.git
[2020-05-27T07:09:14.655Z]  > /usr/bin/git init /var/lib/jenkins/jobs/Deploy_Slack_API_CP4I/workspace # timeout=10
[2020-05-27T07:09:14.664Z] Fetching upstream changes from https://github.ibm.com/anand-awasthi/Deploy_Slack_API_CP4I.git
[2020-05-27T07:09:14.664Z]  > /usr/bin/git --version # timeout=10
[2020-05-27T07:09:14.669Z] using GIT_ASKPASS to set credentials 
[2020-05-27T07:09:14.670Z]  > /usr/bin/git fetch --tags --progress -- https://github.ibm.com/anand-awasthi/Deploy_Slack_API_CP4I.git +refs/heads/*:refs/remotes/origin/* # timeout=10
[2020-05-27T07:09:15.068Z]  > /usr/bin/git config remote.origin.url https://github.ibm.com/anand-awasthi/Deploy_Slack_API_CP4I.git # timeout=10
[2020-05-27T07:09:15.074Z]  > /usr/bin/git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
[2020-05-27T07:09:15.083Z]  > /usr/bin/git config remote.origin.url https://github.ibm.com/anand-awasthi/Deploy_Slack_API_CP4I.git # timeout=10
[2020-05-27T07:09:15.088Z] Fetching upstream changes from https://github.ibm.com/anand-awasthi/Deploy_Slack_API_CP4I.git
[2020-05-27T07:09:15.088Z] using GIT_ASKPASS to set credentials 
[2020-05-27T07:09:15.088Z]  > /usr/bin/git fetch --tags --progress -- https://github.ibm.com/anand-awasthi/Deploy_Slack_API_CP4I.git +refs/heads/*:refs/remotes/origin/* # timeout=10
[2020-05-27T07:09:15.394Z]  > /usr/bin/git rev-parse refs/remotes/origin/master^{commit} # timeout=10
[2020-05-27T07:09:15.404Z]  > /usr/bin/git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
[2020-05-27T07:09:15.411Z] Checking out Revision ed1ed7e424c5b363649b905b68742cd826dc387f (refs/remotes/origin/master)
[2020-05-27T07:09:15.411Z]  > /usr/bin/git config core.sparsecheckout # timeout=10
[2020-05-27T07:09:15.416Z]  > /usr/bin/git checkout -f ed1ed7e424c5b363649b905b68742cd826dc387f # timeout=10
[2020-05-27T07:09:15.425Z] Commit message: "Update setdbparms.txt"
[2020-05-27T07:09:15.426Z]  > /usr/bin/git rev-list --no-walk 2ba014c20a475bf33ba2b35a0469034dd3b7903f # timeout=10
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Deploy_Slack_API_CP4I - Build)
[Pipeline] artifactResolver
[2020-05-27T07:09:15.496Z] INFO: define repo: [Repository id=nexus-release, type=default, url=http://127.0.0.1:8044/nexus/repository/releases/, isRepositoryManager=false]
[2020-05-27T07:09:15.496Z] INFO: set authentication for admin
[2020-05-27T07:09:15.509Z] deleted file:/var/icp-builds/Designer_Slack_Alert_API/Designer_Slack_Alert_API-18.zip
[2020-05-27T07:09:15.509Z] copy /var/nexus_repo/com/ibm/esb/Designer_Slack_Alert_API/18/Designer_Slack_Alert_API-18.zip to file:/var/icp-builds/Designer_Slack_Alert_API/Designer_Slack_Alert_API-18.zip
[2020-05-27T07:09:15.524Z] deleted file:/var/icp-builds/Designer_Slack_Alert_API/Test.App-20.zip
[2020-05-27T07:09:15.524Z] copy /var/nexus_repo/com/ibm/esb/Test.App/20/Test.App-20.zip to file:/var/icp-builds/Designer_Slack_Alert_API/Test.App-20.zip
[Pipeline] sh
[2020-05-27T07:09:15.793Z] Archive:  Designer_Slack_Alert_API-18.zip
[2020-05-27T07:09:15.793Z]   inflating: Designer_Slack_Alert_API_DEV_18.bar  
[2020-05-27T07:09:15.793Z] Archive:  Test.App-20.zip
[2020-05-27T07:09:15.793Z]   inflating: Test.App_DEV_20.bar     
[2020-05-27T07:09:15.793Z]   inflating: Test.App_QA_20.bar      
[2020-05-27T07:09:20.990Z] Login successful.
[2020-05-27T07:09:20.990Z] 
[2020-05-27T07:09:20.990Z] You have access to 72 projects, the list has been suppressed. You can list all projects with 'oc projects'
[2020-05-27T07:09:20.990Z] 
[2020-05-27T07:09:20.990Z] Using project "ace".
[2020-05-27T07:09:21.241Z] Already on project "ace" on server "redacted the value".
[2020-05-27T07:09:21.792Z] WARNING! Using --password via the CLI is insecure. Use --password-stdin.
[2020-05-27T07:09:22.343Z] WARNING! Your password will be stored unencrypted in /var/lib/jenkins/.docker/config.json.
[2020-05-27T07:09:22.343Z] Configure a credential helper to remove this warning. See
[2020-05-27T07:09:22.343Z] https://docs.docker.com/engine/reference/commandline/login/#credentials-store
[2020-05-27T07:09:22.343Z] 
[2020-05-27T07:09:22.343Z] Login Succeeded
[2020-05-27T07:09:22.343Z] Sending build context to Docker daemon  180.7kB

[2020-05-27T07:09:22.343Z] Step 1/4 : FROM redacted the value /ace/ibm-ace-server-prod:11.0.0.8-r1-amd64

[2020-05-27T07:09:22.343Z]  ---> 50a1cbd42ca5
[2020-05-27T07:09:22.343Z] Step 2/4 : COPY *DEV*.bar /home/aceuser/initial-config/bars/
[2020-05-27T07:09:22.343Z]  ---> Using cache
[2020-05-27T07:09:22.343Z]  ---> 373147049480
[2020-05-27T07:09:22.343Z] Step 3/4 : EXPOSE 7600 7800 7843 9483
[2020-05-27T07:09:22.343Z]  ---> Using cache
[2020-05-27T07:09:22.343Z]  ---> 64a19443506e
[2020-05-27T07:09:22.343Z] Step 4/4 : ENV LICENSE accept
[2020-05-27T07:09:22.343Z]  ---> Using cache
[2020-05-27T07:09:22.343Z]  ---> 8b572918434d
[2020-05-27T07:09:22.343Z] Successfully built 8b572918434d
[2020-05-27T07:09:22.343Z] Successfully tagged slackalertace:6
[2020-05-27T07:09:22.593Z] The push refers to repository [redacted the value/ace/slackalertace]

[2020-05-27T07:09:22.844Z] 793ad17cc0df: Preparing
[2020-05-27T07:09:22.844Z] cc462519999e: Preparing
[2020-05-27T07:09:22.844Z] 434b83712593: Preparing
[2020-05-27T07:09:22.844Z] d120f8762989: Preparing
[2020-05-27T07:09:23.095Z] cc462519999e: Layer already exists
[2020-05-27T07:09:23.095Z] d120f8762989: Layer already exists
[2020-05-27T07:09:23.095Z] 793ad17cc0df: Layer already exists
[2020-05-27T07:09:23.095Z] 434b83712593: Layer already exists
[2020-05-27T07:09:23.646Z] 6-amd64: digest: sha256:af0be5f1180d68a37bee2a71d2c82fa2c07f45acb44b252992c18e74bd9e64fb size: 1159
[2020-05-27T07:09:24.557Z] Error from server (NotFound): secrets "slackalertace-rel6-secret" not found
[2020-05-27T07:09:24.557Z] Creating secret
[2020-05-27T07:09:24.557Z] oc create secret generic slackalertace-rel6-secret --from-literal=mqsc= --from-literal=adminPassword= --from-literal=appPassword= --from-literal=keystorePassword= --from-literal=keystoreKey-mykey= --from-literal=keystoreCert-mykey= --from-literal=keystorePass-mykey= --from-file=truststorePassword=./truststorePassword.txt --from-file=truststoreCert-mykey=./truststoreCert-mykey.crt --from-literal=odbcini= --from-file=policy=./policy.xml  --from-literal=policyDescriptor= --from-file=serverconf=./server.conf.yaml  --from-file=setdbparms=./setdbparms.txt 
[2020-05-27T07:09:25.469Z] secret/slackalertace-rel6-secret created
[2020-05-27T07:09:25.469Z] /var/lib/jenkins/jobs/Deploy_Slack_API_CP4I/workspace@tmp/durable-769894d3/script.sh: 21: /var/lib/jenkins/jobs/Deploy_Slack_API_CP4I/workspace@tmp/durable-769894d3/script.sh: source: not found
[2020-05-27T07:09:25.469Z] $HELM_HOME has been configured at /var/lib/jenkins/.helm.
[2020-05-27T07:09:25.469Z] Not installing Tiller due to 'client-only' flag having been set
[2020-05-27T07:09:25.469Z] Happy Helming!
[2020-05-27T07:09:25.469Z] "ibm-entitled-charts" has been added to your repositories
[2020-05-27T07:09:29.592Z] NAME:   slackalertace-rel6
[2020-05-27T07:09:29.592Z] E0527 07:09:29.408641   57608 portforward.go:303] error copying from remote stream to local connection: readfrom tcp4 127.0.0.1:44995->127.0.0.1:37758: write tcp4 127.0.0.1:44995->127.0.0.1:37758: write: broken pipe
[2020-05-27T07:09:30.504Z] LAST DEPLOYED: Wed May 27 07:09:27 2020
[2020-05-27T07:09:30.504Z] NAMESPACE: ace
[2020-05-27T07:09:30.504Z] STATUS: DEPLOYED
[2020-05-27T07:09:30.504Z] 
[2020-05-27T07:09:30.504Z] RESOURCES:
[2020-05-27T07:09:30.504Z] ==> v1/Role
[2020-05-27T07:09:30.504Z] NAME                                               AGE
[2020-05-27T07:09:30.504Z] slackalertace-rel6-ibm-ace-server-icp4i-prod-role  3s
[2020-05-27T07:09:30.504Z] 
[2020-05-27T07:09:30.504Z] ==> v1/RoleBinding
[2020-05-27T07:09:30.504Z] NAME                                                      AGE
[2020-05-27T07:09:30.504Z] slackalertace-rel6-ibm-ace-server-icp4i-prod-rolebinding  3s
[2020-05-27T07:09:30.504Z] 
[2020-05-27T07:09:30.504Z] ==> v1/Job
[2020-05-27T07:09:30.504Z] NAME                                           COMPLETIONS  DURATION  AGE
[2020-05-27T07:09:30.504Z] slackalertace-rel6-ibm-ace--623f-icp4i-o-f857  0/1          2s        2s
[2020-05-27T07:09:30.504Z] 
[2020-05-27T07:09:30.504Z] ==> v1/Route
[2020-05-27T07:09:30.504Z] NAME                      AGE
[2020-05-27T07:09:30.504Z] slackalertace-rel6-http   2s
[2020-05-27T07:09:30.504Z] slackalertace-rel6-https  2s
[2020-05-27T07:09:30.504Z] 
[2020-05-27T07:09:30.504Z] ==> v1/ConfigMap
[2020-05-27T07:09:30.504Z] NAME                                           DATA  AGE
[2020-05-27T07:09:30.504Z] slackalertace-rel6-ibm-ace--623f-create--d350  2     3s
[2020-05-27T07:09:30.504Z] 
[2020-05-27T07:09:30.504Z] ==> v1/Service
[2020-05-27T07:09:30.504Z] NAME                                                      TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)                     AGE
[2020-05-27T07:09:30.504Z] slackalertace-rel6-ibm-ace-server-icp4i-prod-ace-metrics  ClusterIP  172.21.105.71  

The sample Github projects used in this demo are attached here.

Designer_Slack_Alert_API-master.zip
Test_App-master_.zip
Deploy_Slack_API_CP4I-master.zip

2 comments on"An approach to build a DevOps pipeline for IBM App Connect Designer Flows on Cloud Pak for Integration"

  1. Nasroht May 28, 2020

    Jenkins pipelines and demos like this are wonderful for current Cp4i installations. Thanks for sharing. Beware that Jenkins is being replaced in OpenShift going forward, looking forward to a similar blog for Tekton (preview on Openshift 3.4).

    Reply (Edit)
    • Anand.Awasthi May 29, 2020

      Thanks for the feedback, Thor. The next release of CP4I (2020.2.1) will completely use Operator model and will be based on OCP 4.4. We intend to cover both Jenkins and Tekton in similar blog series.

      Reply (Edit)




#AppConnect
#App-Connect-Designer
#DevOps
#IBMCloudPakforIntegration(ICP4I)