Skip to content

Instantly share code, notes, and snippets.

@gheppner
Last active April 8, 2024 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gheppner/01f9a52f2b83f5e08b8cace4163eea4d to your computer and use it in GitHub Desktop.
Save gheppner/01f9a52f2b83f5e08b8cace4163eea4d to your computer and use it in GitHub Desktop.
def call(body) {
def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()
def render_env = {
try {
stage("Generate TF plan for ${config.target_env}") {
withCredentials(bindings: [sshUserPrivateKey(credentialsId: 'pixability-git-jenkins', keyFileVariable: 'PIX_GH_SSH_KEY')]) {
sh """
## Run the hashicorp docker terraform container in the background so we can interact with it ##
## Everything prefaced with 'config.' has been passed in from the invoking build.
docker run -w /root -v \"`pwd`:/workdir\" --entrypoint sh --name tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver} --rm -d -t hashicorp/terraform:$config.tf_ver
## Following required to give the container access to our Github repository. Copies the SSH Key stored in Jenkins into the image ##
docker exec tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver} mkdir -p /root/.ssh
docker cp \"$PIX_GH_SSH_KEY\" tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver}:/root/.ssh/id_rsa
docker exec tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver} chmod 600 /root/.ssh/id_rsa
## Copy the scm checkout (terraform files) into the container so they will persist beyond the commit ##
docker exec tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver} sh -c 'cp -r /workdir/* .'
"""
}
withEnv(['AWS_REGION=us-east-1']) {
withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'pixability-aws-devops', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sh """
## Pull down modules, initialize backend, same as you typically would, but from within the container ##
docker exec -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \\
tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver} terraform init
## Switch to the workspace for this build since that is how we manage multiple environments ##
docker exec -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \\
tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver} sh -c 'terraform workspace select ${config.target_env} || terraform workspace new ${config.target_env}'
## Generate the plan file - feed in appropriate variables for tagging, etc ##
docker exec -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \\
tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver} terraform plan -var 'app=${config.app_name}' -var 'branch=${config.branch_name}' -var 'build=${config.build_number}' \\
-out ${config.app_name}-${config.target_env}-${config.artifact_ver}.tfplan
## Cleanup the SSH key we uploaded into the image - not longer needed and we don't want it laying around in the container ##
docker exec tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver} rm /root/.ssh/id_rsa
## Commit the container, tag and push ! ##
docker commit --change='ENTRYPOINT [\"terraform\"]' tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver} ${config.docker_repo}:${config.app_name}-${config.target_env}-${config.artifact_ver}
docker tag ${config.docker_repo}:${config.app_name}-${config.target_env}-${config.artifact_ver} ${config.docker_repo}:${config.app_name}-${config.target_env}-${config.branch_name}-latest
docker tag ${config.docker_repo}:${config.app_name}-${config.target_env}-${config.artifact_ver} ${config.docker_repo}:${config.app_name}-${config.target_env}-${config.artifact_ver}
docker push ${config.docker_repo}:${config.app_name}-${config.target_env}-${config.artifact_ver}
docker push ${config.docker_repo}:${config.app_name}-${config.target_env}-${config.branch_name}-latest
## Do some cleanup ##
docker stop tf-builder-${config.app_name}-${config.target_env}-${config.artifact_ver}
docker rmi ${config.docker_repo}:${config.app_name}-${config.target_env}-${config.artifact_ver}
"""
}
}
}
} catch (e) {
currentBuild.result = 'FAILED'
throw e
}
}
return render_env
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment