Reputation: 313
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
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