Technical Articles
Continuous Integration & Deployment on SAP Cloud Platform – Part 3
Creating your own CI/CD environment
Introduction
If the predefined environment from our previous blog doesn’t fit your needs, you can also setup your own CI/CD environment including some helpers/predefined content from SAP. This allows you to leverage existing content as well as to adapt the environment to your own needs.
Requirements
You need a SAP Cloud Platform Account, a Git Repository (e.g. GitHub or an On-Premise Git) as well as an environment to run Jenkins (Cloud or On-Premise). Most steps we refer to are described in the Project Piper documentation.
Set up docker
On the base we will use docker to run the tools we are going to use. This allows us to use many different tools and connect them the way we want. Also, we can refer to project Piper which created a Jenkins and other integrated tools we will use as docker containers. To install docker follow the instructions on the official docker side or use the installation from your distribution.
Set up Jenkins
The central unit of our environment will be Jenkins. It manages the configuration for our project including all tools we will add to our environment.
We will use the preferred style of installation which includes the cx-server Life-cycle Management for Jenkins. Therefore, we will follow the instruction given by the project piper documentation:
- First, we run the following command on the terminal:
docker run -it --rm -u $(id -u):$(id -g) -v "${PWD}":/cx-server/mount/ ppiper/cx-server-companion:latest init-cx-server
. This will setup the preconfigured cx-server. Next, we need to give permission to he cx-server by running:chmod +x ./cx-server
on the terminal. To start the server run./cx-server start.
. - During the first start of the Jenkins container the initial admin password will be written in the terminal. Otherwise you can print it by running
./cx-server initial-admin password
. Now you can open Jenkins inside your browser. The preconfigured address islocalhost:8080
. - First open Jenkins and create an user for your ongoing work.
- Also, you need to define credentials for tools you are going to use but need your username and password. If you do not want to write them down in your code as you should not do you can use the credential tool.
Create pipeline configuration in your project
Create a new file called Jenkinsfile. Open the file and use this as the basic:
@Library('piper-lib-os') _
pipeline {
agent any
stages{
stage('prepare') {
checkout scm
setupCommonPipelineEnvironment script:this
}
}
}
This script will import the piper-lib-os library to your pipeline. Also, this script sets the default pipeline environment to the piper preconfigured setting.
Now you can add more pipeline steps by adding more stage elements to your pipeline file. You find all available steps and actions you can implement in the piper documentation.
Next create a new folder in the root section of your project named .pipeline. This will create a hidden folder. Open this folder and create a new file named config.yaml. Be aware this is a hidden folder and will not be handled the same way as a normal folder by git. This file is necessary if you want to store configuration outside of the pipeline file to keep it cleaner.
Create first Jenkins Pipeline
Log in to Jenkins using the previous created account to enable all features.
Create a new Item and select Multibranch pipeline. Now the configuration window will open. First add a Branch Source and the select the source matching you code repository. To finish click apply and then save to finish the process.
This creates a folder where every branch will be shown as a single pipeline so you can trigger pipelines branch based. To start the analysis, select Scan Multibranch pipeline now.
Add build step to your pipeline
The first step we want to include to our pipeline is the build step. We will use the mtb build tool. Open your Jenkinsfile and extend your script by new step:
stage(‘build’){ steps{ mtaBuild script: this, mtaBuildTool: 'cloudMbt' } }
And add this to your config.yaml:
steps: mtaBuild: buildTarget: 'CF'
This will build an mta file out of your project which is addressed to CF.
Add deploy step to your pipeline
Next step for our pipeline is the deploy step. As already described in the previous step we need to modify both files.
Jenkinsfile:
stage('deploy'){ steps{ cloudFoundryDeploy script:this, deployTool:'mtaDeployPlugin', verbose: true } }
config.yaml
cloudFoundryDeploy: cloudFoundry: credentialsId: <name of the credentials>' apiEndpoint: '<api endpoint>’ org: '<org>' space: '<space>'
Make sure you added your Cloud platform credentials to the Jenkins credential storage so you can refer to them in the config.yaml.
Add TMS
If you prefer to use TMS to deploy the artefacts to test and production environment you can also add this instead of the deployment step described in the previous section.
We will use the landscape created at the beginning of this documentation. Open your Jenkinsfile and create a new Step for the TMS code. You need to create a sevice key for the TMS and store this key in your jenkins credential service as secret text:
tmsUpload script:this, verbose: true, nodeName: 'Develop', credentialsId: 'TMS_Credential', mtaPath: 'Path to the mtar', customDescription: 'JobName: '+ env.JOB_NAME+' Build Nr: '+ env.BUILD_NUMBER
This will add a transport into TMS similar to this one:
Summary
With this you can enable Jenkins to build your projects using the pipelines provided by the Project Piper and deploy the result to a cloud-foundry account in the SAP Cloud Platform.
Next part of the series will describe how to include Nexus as an archive cache, Sonatype for source-code checks and integration with TMS.
Thank you for the great sum up of information @Marco Lommatzsch
I can imagine we can use kyma to store and use the Jenkins image, would be excellent 🙂
Hi Marco,
I am trying the "SAP Continuous Integration and Delivery for SAP Integration Suite Artifacts"
Upload step is failing when I include the Upload step in the Job. If I only include the Deploy step it is running successfully.
I tried with and without having the Integration Flow in the package. In both cases Upload step is failing. But the zip file in the github has the correct manifest file.
<error>
<code>Bad Request</code>
<message xml:lang="en">INVALID_INTEGRATION_PROJECT_NO_MANIFEST</message></error>
Log looks like as follows:
Hi Mani Rajendran ,
Were you able to resolve this issue.I am also facing the same error.
If you were able to resolve it,please let me know ,it would be a great help.
Thanks and Regards,
Keerthana