Skip to content

Instantly share code, notes, and snippets.

@johnrengelman
Created May 27, 2016 14:34
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save johnrengelman/fac807d346c4a1a67169e594e627f091 to your computer and use it in GitHub Desktop.
Save johnrengelman/fac807d346c4a1a67169e594e627f091 to your computer and use it in GitHub Desktop.
#!/bin/bash -e
PROJECT="$(basename `pwd`)"
BUCKET="myorgs-infrastructure-state"
init() {
if [ -d .terraform ]; then
if [ -e .terraform/terraform.tfstate ]; then
echo "Remote state already exist!"
if [ -z $IGNORE_INIT ]; then
exit 1
fi
fi
fi
terraform remote config \
-backend=s3 \
-backend-config="bucket=${BUCKET}" \
-backend-config="key=${PROJECT}/terraform.tfstate" \
-backend-config="region=us-east-1"
}
while getopts "i" opt; do
case "$opt" in
i)
IGNORE_INIT="true"
;;
esac
done
shift $((OPTIND-1))
init
node {
// Mark the code checkout 'Checkout'....
stage 'Checkout'
// // Get some code from a GitHub repository
git url: 'git@github.com:myorg/infrastructure.git'
// Get the Terraform tool.
def tfHome = tool name: 'Terraform', type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool'
env.PATH = "${tfHome}:${env.PATH}"
wrap([$class: 'AnsiColorBuildWrapper', colorMapName: 'xterm']) {
dir(project) {
// Mark the code build 'plan'....
stage name: 'Plan', concurrency: 1
// Output Terraform version
sh "terraform --version"
//Remove the terraform state file so we always start from a clean state
if (fileExists(".terraform/terraform.tfstate")) {
sh "rm -rf .terraform/terraform.tfstate"
}
if (fileExists("status")) {
sh "rm status"
}
sh "./init"
sh "terraform get"
sh "terraform plan -out=plan.out -detailed-exitcode; echo \$? > status"
def exitCode = readFile('status').trim()
def apply = false
echo "Terraform Plan Exit Code: ${exitCode}"
if (exitCode == "0") {
currentBuild.result = 'SUCCESS'
}
if (exitCode == "1") {
slackSend channel: '#ci', color: '#0080ff', message: "Plan Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER} (<${env.JOB_URL}|Open>)"
currentBuild.result = 'FAILURE'
}
if (exitCode == "2") {
stash name: "plan", includes: "plan.out"
slackSend channel: '#ci', color: 'good', message: "Plan Awaiting Approval: ${env.JOB_NAME} - ${env.BUILD_NUMBER} (<${env.JOB_URL}|Open>)"
try {
input message: 'Apply Plan?', ok: 'Apply'
apply = true
} catch (err) {
slackSend channel: '#ci', color: 'warning', message: "Plan Discarded: ${env.JOB_NAME} - ${env.BUILD_NUMBER} (<${env.JOB_URL}|Open>)"
apply = false
currentBuild.result = 'UNSTABLE'
}
}
if (apply) {
stage name: 'Apply', concurrency: 1
unstash 'plan'
if (fileExists("status.apply")) {
sh "rm status.apply"
}
sh 'terraform apply plan.out; echo \$? > status.apply'
def applyExitCode = readFile('status.apply').trim()
if (applyExitCode == "0") {
slackSend channel: '#ci', color: 'good', message: "Changes Applied ${env.JOB_NAME} - ${env.BUILD_NUMBER} (<${env.JOB_URL}|Open>)"
} else {
slackSend channel: '#ci', color: 'danger', message: "Apply Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER} (<${env.JOB_URL}|Open>)"
currentBuild.result = 'FAILURE'
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment