hashim vayalar
hashim vayalar

Reputation: 313

Delete the jenkins deploy jobs that are created by build pipeline if a condition is true or empty deployments in terraform.yaml

My build job will call this deploy job to create other pipeline jobs based on terraform.yaml

If I am archiving or deleting the repo, main build job/repo will be removed from jenkins but not the additional/deploy/child/seed jobs created by this repo will not get deleted.

So If the deployment is empty in terraform.yaml, All the seed jobs that are already created by this repo should be removed from jenkins.

How can I achieve?

/*
    Create Terraform deploy jobs based on content of terraform.yaml
*/
def call(Map terraformConfig, String repoPath, Map inlineParams = [:]) {
    dslScripts = []

    deployments = terraformConfig["deployments"]
    latestVersion = terraformConfig["version"]

    deployments.each { deployment ->
        deployment["environments"].each { environment, setting ->
        if (deployment.subcomponent) {
            deploymentPath = "${deployment.namespace}/${deployment.application}/${deployment.component}-${deployment.subcomponent}-${environment}"
        } else {
            deploymentPath = "${deployment.namespace}/${deployment.application}/${deployment.component}-${environment}"
            // set to empty string because subcomponent is `null` if not present in terraform.yaml
            deployment.subcomponent = ""
        }
        if (setting.approvers) {
            approvers = setting.approvers.join(',')
        } else {
            approvers = "authenticated"
        }
        // Creating a list of repos that need to pass tfvars through Jenkins parameters
        repo_list_for_tfvars_param = [
            "neoload-infra",
            "devops-ec2-infra"
        ]
        repo_name = repoPath.replace("DET/","").toString().trim()
        repo_exists = repo_list_for_tfvars_param.contains(repo_name)
        // Check if the current Infra project (repo) needs the Terraform variables parameter => Only requested jobs that doesn't affect production are allowed for this feature
        if (repo_exists) {
            tfVarsJobScript = """
                pipelineJob("${deploymentPath}") {
                    parameters {
                        stringParam('Version', 'master', 'Infrastructure Version to deploy (e.g. 0.1.0, master, dev, feature/foobar, etc.')
                        stringParam('ExtraArgs', '', 'Extra terraform arguments, for example "-parallelism=1" or "-target=random_id.managed_8bytes". Applicable for all stages: plan/apply/destroy')
                        stringParam('tfVars', '', "Terraform variables, for example -var='instance_count=3' -var='instance_type=t3.small'. The variables must have been defined in Terraform code and is Applied to all stages: plan/apply/destroy")
                        choiceParam('DebugLogLevel', ['disabled', 'TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'], 'Terraform debug log level. Applicable for all stages: plan/apply/destroy')
                        stringParam('Destroy', '', 'To destroy this environment, enter "Please destroy all resources" or "Please destroy all resources with force" into this text box. First option worklow: plan -destroy => apply. Second: plan => destroy.')
                        stringParam('AutoApprove', '', 'To build or destroy this environment with auto approve, enter "Please run with auto approve" into this text box.')
                    }
                    environmentVariables {
                        env('namespace', '${deployment.namespace}')
                        env('application', '${deployment.application}')
                        env('environment', '${environment}')
                        env('component', '${deployment.component}')
                        env('subcomponent', '${deployment.subcomponent}')
                        env('aws_account_id', '${setting.aws_account_id}')
                        env('aws_region', '${setting.aws_region}')
                        env('deploymentPath', '${deploymentPath}')
                        env('buildJobUrl', '${JOB_URL}')
                        env('repoPath', '${repoPath}')
                        env('WEBEX_SPACE_ID', '${WEBEX_SPACE_ID}')
                        env('approvers', '${approvers}')
                    }
                    logRotator {
                        numToKeep(50)
                    }
                    definition {
                        cps {
                            script(\"\"\"
                                @Library(value='tls-lib@master', changelog=false) _
                                TerraformDeployPipeline(params, ${inlineParams})
                            \"\"\".stripIndent())
                        sandbox(true)
                        }
                    }
                }
            """.stripIndent()
                dslScripts.add(tfVarsJobScript)
        } else {
            jobScript = """
                pipelineJob("${deploymentPath}") {
                    parameters {
                        stringParam('Version', 'master', 'Infrastructure Version to deploy (e.g. 0.1.0, master, dev, feature/foobar, etc.')
                        stringParam('ExtraArgs', '', 'Extra terraform arguments, for example "-parallelism=1" or "-target=random_id.managed_8bytes". Applicable for all stages: plan/apply/destroy')
                        choiceParam('DebugLogLevel', ['disabled', 'TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'], 'Terraform debug log level. Applicable for all stages: plan/apply/destroy')
                        stringParam('Destroy', '', 'To destroy this environment, enter "Please destroy all resources" or "Please destroy all resources with force" into this text box. First option worklow: plan -destroy => apply. Second: plan => destroy.')
                        stringParam('AutoApprove', '', 'To build or destroy this environment with auto approve, enter "Please run with auto approve" into this text box.')
                    }
                    environmentVariables {
                        env('namespace', '${deployment.namespace}')
                        env('application', '${deployment.application}')
                        env('environment', '${environment}')
                        env('component', '${deployment.component}')
                        env('subcomponent', '${deployment.subcomponent}')
                        env('aws_account_id', '${setting.aws_account_id}')
                        env('aws_region', '${setting.aws_region}')
                        env('deploymentPath', '${deploymentPath}')
                        env('buildJobUrl', '${JOB_URL}')
                        env('repoPath', '${repoPath}')
                        env('WEBEX_SPACE_ID', '${WEBEX_SPACE_ID}')
                        env('approvers', '${approvers}')
                    }
                    logRotator {
                        numToKeep(50)
                    }
                    definition {
                        cps {
                            script(\"\"\"
                                @Library(value='tls-lib@master', changelog=false) _
                                TerraformDeployPipeline(params, ${inlineParams})
                            \"\"\".stripIndent())
                        sandbox(true)
                        }
                    }
                }
            """.stripIndent()
                dslScripts.add(jobScript)
            }
        }
    }

    jobDsl(
        scriptText: dslScripts.join('\n'),
        removedJobAction: 'DELETE',
        removedViewAction: 'DELETE',
        lookupStrategy: 'JENKINS_ROOT'
    )
}`

Build Pipeline

/*
    Terraform Build Pipeline
*/
def call(Map params = [:]) {
    pipeline {
        agent {
            label 'terraform-agent'
        }

        options {
            buildDiscarder(logRotator(numToKeepStr: '30'))
            ansiColor('xterm')
            disableConcurrentBuilds()
        }

        stages {
            stage("Build") {
                when {
                    not {
                        buildingTag()
                    }
                }
                steps {
                    script {
                        terraformConfig = readYaml(file: 'terraform.yaml')
                        terraformVersion =  terraformConfig["terraform_version"]
                        containerName = "tf-${terraformVersion.replace('.', '-')}"
                        TF_TAG_JOB_URL = "${env.JOB_URL}".replace("${env.BRANCH_NAME}", "master")

                        // write files from terraform lib (resources/)
                        
                        sh label: 'Lint terraform.yaml', script: 'yamllint terraform.yaml'
                        sh label: 'Validate schema of terraform.yaml', script: 'python3 validate-schema.py terraform.yaml tf-schema.yaml'
                        sh label: 'Read tf-schema.yaml', script: 'cat tf-schema.yaml'
                        env.repoName =  "${GIT_URL.replaceFirst(/^.*\/([^\/]+?).git$/, '$1')}"

                    }
                }
            }

            stage ("Seed") {
                when {
                    branch 'master'
                }
                environment {
                    repoPath = "${GIT_URL.split(':')[1].replace('.git', '')}"
                }
                steps {
                    // custom step from terraform lib
                    CreateTerraformDeployJobs(terraformConfig, repoPath, params)
                }
            }

            stage ("Commit") {
                when {
                    not {
                        anyOf {
                            buildingTag()
                            // changeRequest()
                            expression {
                                env.CHANGE_ID ? true : false
                            }
                        }
                    }
                }

                steps {
                    commitTerraformFiles()
                }
            }

            stage ("Upload") {
              
                environment {
                    version = "${env.TAG_NAME == NULL ? env.GIT_BRANCH : env.TAG_NAME}"
                    repoPath = "${GIT_URL.split(':')[1].replace('.git', '')}"
                }

                steps {
                    zip zipFile: 'package.zip'
                    withAWS(role: "${env.UPLOAD_ROLE}", roleAccount: "${env.AWS_ACCOUNT_ID}", region: 'us-east-1') {
                        sh 'aws s3 cp package.zip s3://${ARTIFACTS_BUCKET}/infrastructure/${repoPath}/${version}/package.zip'
                    
                    }
                    sh 'rm -rf package.zip'
                }
            }

            stage ("Release") {
                when {
                   branch 'master'
                }
                steps {
                    releaseTerraformTag()
                }
            }
        } // stages

        post {
            always {
                script {
                    // custom step from terraform lib
                    if(params.WEBHOOK != null) {
                        msteamsNotify("", "${params.WEBHOOK}")
                    } else {
                        msteamsNotify("", "${WEBHOOK}")
                    }
                }
            }
            cleanup {
                cleanWs()
            }
        }
    }
}

Upvotes: 0

Views: 156

Answers (1)

hashim vayalar
hashim vayalar

Reputation: 313

Achieved by adding below code at the end, new variable in terraform.yaml

if (terraformConfig["remove_all_deploy_jobs"] ) {
        jobDsl(
            scriptText: 'job("/wdc/null")',
            removedJobAction: 'DELETE',
            removedViewAction: 'DELETE',
            lookupStrategy: 'JENKINS_ROOT'
        )
    } else {
        jobDsl(
            scriptText: dslScripts.join('\n'),
            removedJobAction: 'DELETE',
            removedViewAction: 'DELETE',
            lookupStrategy: 'JENKINS_ROOT'
        )
    }

It is not possible with empty script

Upvotes: 1

Related Questions