Strategies for integrating Deployment Manager with Jenkins pipelines

From PegaWiki
Strategies for integrating Deployment Manager with Jenkins / This is the approved revision of this page, as well as being the most recent.
Jump to navigation Jump to search

Strategies for integrating Deployment Manager with Jenkins pipelines

Description Strategies for integrating Deployment Manager with Jenkins
Version as of 8.1
Application Pega Platform
Capability/Industry Area DevOps

Deployment Manager provides a suite of APIs for a wide variety of implementation strategies with third-party orchestration tools, including Jenkins. These design patterns outline various strategies to begin incorporating a Deployment Manager pipeline in Jenkins. Although this document is specific to Jenkins, you can apply the same concepts to other third-party tools.

Use case examples[edit]

Approach 1: Deployment Manager as primary orchestrator[edit]

  • In this approach, the application uses a typical Deployment Manager configuration consisting of merge and deployment pipelines. However, each deployment triggers a Jenkins job that collects deployment metrics for consolidated reporting.
  • This approach is easier to set up, but provides less visibility into the status of ongoing deployments in Deployment Manager.
Using Deployment Manager as primary orchestrator.

Approach 2: Jenkins as Primary Orchestrator[edit]

  • In this approach, Jenkins is the primary orchestrator of the entire process, delegating all Pega-specific tasks to Deployment Manager.
  • Merge pipelines trigger the Jenkins job, allowing Pega developers to trigger deployments directly from Dev studio without any additional configuration.
  • This approach requires additional effort to set up, but provides greater visibility into the status of ongoing deployments in Deployment Manager.
Using Jenkins as primary orchestrator.

Before you begin[edit]

Review the following documentation before proceeding with these approaches.

Process/Steps to achieve objective[edit]

Approach 1: Deployment Manager as Primary Orchestrator[edit]

Create a deployment pipeline and a merge pipeline in Deployment Manager to promote your application. See Creating pipelines in Deployment Manager for more information. Next, call a Jenkins job as the final step of a deployment pipeline. This Jenkins job will connect to Deployment Manager using the APIs to collect information, such as:

  • Agile workbench items
  • Branch names
  • Test coverage percentages
  • Test executions
  • Artifact locations
  • Approvers

See the code from the Jenkins approach below as a starting point for metric collection.

Approach 2: Jenkins as Primary Orchestrator[edit]

Although this approach requires more effort, using Jenkins provides greater visibility of your deployment status.

  1. Create a deployment pipeline in Deployment Manager, and capture the pipeline ID.
  2. Create a Jenkins pipeline project and follow all the guidance from the Jenkins configuration document.
  3. Add additional parameters:
    • DeployPipelineId - Set the default value to the pipeline ID from step 1.
    • BranchName
    • CallBackURL
  4. Populate the pipeline definition as a script using the boilerplate code below.
  5. Trigger the pipeline and ensure that the Deployment Manager pipeline starts.
  6. Abort the Deployment Manager pipeline and the Jenkins pipeline should end.
  7. Create a merge pipeline and add a Jenkins task to the final step, invoking the Jenkins job from step #2.
  8. Trigger the merge pipeline, starting the deployment process in Jenkins when it completes.

The following boilerplate code can be added to a Jenkins pipeline definition to get you started.

 1import groovy.json.JsonSlurper
 3def deploymentStatus
 4def deploymentId
 5pipeline {
 6    agent any
 7    environment {
 8        DM_AUTH = credentials('DM_AUTH')
 9    }
10    stages {
11        stage('Trigger Deployment') {
12            steps{
13                script {
14                    if(env.BranchName != ""){
15                        echo "Completing the merge deployment"
16                            resolveMergeDeployment(env.CallBackURL)
17                    }
18                    deploymentId = startDeployment(env.DeployPipelineId)
19                }
20            }   
21        }
23        stage('Wait for deployment complete'){
24            steps{
25                waitUntil{
26                    script{
27                        deploymentStatus = getDeploymentStatus("Pipeline-CNVQW", deploymentId)
28                        if(deploymentStatus.contains("Resolved-")){
29                            return true
30                        }
31                        return false
32                    }
33                }
34                script{
35                    if(deploymentStatus.contains("Resolved-Aborted")){
36                        error('The deployment manager deployment was aborted')
37                    }    
38                }
39            }
40        }
41        stage('Collect deploment metrics'){
42            steps{
43                echo 'TODO'
44            }   
45        }
46    }
49def getPipeline() {
50    def token = getToken();
51    def pipelineDef = sh(script: "curl --insecure -H \"Content-Type: application/json\" -H \"Accept: application/json\" -H \"Authorization:Bearer ${token}\" -k -X GET $OrchestratorURL/PRRestService/DeploymentManager/v1/pipelines/${pipelineId}",  returnStdout:true).trim()
52    return pipelineDef
55def addStagesFromPipeline(){
56    def stagesJSON = getPipelineStages()
57    new JsonSlurper().parseText(stagesJSON).each { pipelineStage ->  
58        stage( {
59            steps{
60                echo                                    
61            }
62        }
63    }
66def startDeployment(pipelineId){
67    def token = getToken();
68    deploymentId = sh(script: "curl -H \"Content-Type: application/json\" -H \"Accept: application/json\" -H \"Authorization:Bearer ${token}\" -k -X POST $OrchestratorURL/PRRestService/DeploymentManager/v1/pipelines/${pipelineId}/deployments | jq -r .deploymentID",  returnStdout:true).trim()
69    return deploymentId
72def getDeployment(pipelineId, deploymentId){
73    def token = getToken();
74    deployment = sh(script:"curl -H \"Content-Type: application/json\" -H \"Accept: application/json\" -H \"Authorization:Bearer ${token}\" -k -X GET $OrchestratorURL/PRRestService/DeploymentManager/v1/pipelines/${pipelineId}/deployments/${deploymentId}",  returnStdout:true)
75    return deployment
78def getDeploymentStatus(pipelineId, deploymentId){
79    deployment = getDeployment(pipelineId, deploymentId)
80    deploymentStatus = sh(script:"jq .status <<<'${deployment}'",  returnStdout:true)
81    return deploymentStatus
84def getToken(){
85    sh(script: "curl -d \"client_id=$DM_AUTH_USR&client_secret=$DM_AUTH_PSW&grant_type=client_credentials\" $OrchestratorURL/PRRestService/oauth2/v1/token | jq -r .access_token",  returnStdout:true).trim()
88def resolveMergeDeployment(CallBackURL){
89    def token = getToken();
90    sh(script:"curl -H \"Content-Type: application/json\" -H \"Accept: application/json\" -H \"Authorization:Bearer ${token}\" -k -X PUT --data '{\"taskStatus\":\"Resolved-Completed\",\"taskInfo\":{\"outputParameters\":[{\"name\": \"BuildNumber\",\"type\": \"Text\",\"value\": \"%BUILD_NUMBER%\"},{\"name\": \"JenkinsBuildURL\",\"type\": \"Text\",\"value\": \"%BUILD_URL%\"}]}}' ${CallBackURL}",  returnStdout:true)


You now have everything you need to create a simple Jenkins pipeline to expose ongoing Pega deployments from within the Jenkins dashboard.