Created
September 28, 2016 20:50
-
-
Save c4urself/fd30a579d8b1698317eeeb5ea87d8f9a to your computer and use it in GitHub Desktop.
Wrapper around Terraform
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -e | |
TERRAFORM_BUCKET_REGION='us-east-1' | |
TERRAFORM_BUCKET_NAME='' | |
TERRAFORM_VERSION="0.7.4" | |
actions="plan apply fmt plan-destroy destroy refresh graph validate" | |
usage() { | |
echo "Usage: terraform.sh [account] [region] [component] [action] [[log_level]]" | |
echo | |
echo "account:" | |
echo " - dr" | |
echo " - prod" | |
echo | |
echo "region:" | |
echo " - us-east-1" | |
echo " - us-west-2" | |
echo " - ..." | |
echo | |
echo "component:" | |
echo " - core_networking" | |
echo " - core_infra" | |
echo " - ..." | |
echo | |
echo "action:" | |
for a in $actions ; do | |
help="$(terraform help | \grep -E "^[^\w]+$a" | awk -F' ' '{ $1=""; print $0}')"; | |
if test -z "$help" ; then | |
help="As the name suggests" | |
fi | |
echo " - $a -- $help"; | |
done | |
echo | |
echo "log_level: (optional)" | |
echo " - trace" | |
echo " - debug" | |
echo " - info" | |
echo " - warn" | |
echo " - error" | |
} | |
do_echo() { | |
echo "[terraform wrapper] $(tput setaf 5)$1$(tput sgr0)" | |
} | |
do_warn() { | |
echo "[terraform wrapper] $(tput setaf 3)$1$(tput sgr0)" | |
} | |
original_path="$(pwd)" | |
cleanup() { | |
echo | |
cd $original_path | |
do_echo "Kbye" | |
} | |
trap cleanup 0 1 | |
test -n "$AWS_ACCESS_KEY" || { echo 'Environment variable AWS_ACCESS_KEY not set'; exit 1; } | |
test -n "$AWS_SECRET_KEY" || { echo 'Environment variable AWS_SECRET_KEY not set'; exit 1; } | |
check_version() { | |
user_version="$(terraform --version | awk -F'v' '{ print $2 }')" | |
if test "$user_version" = "$TERRAFORM_VERSION" ; then | |
do_echo "Version $user_version: $(tput setaf 2)OK$(tput sgr0)" | |
else | |
do_warn "Version check failed. You're running $user_version, but $TERRAFORM_VERSION was expected" | |
exit 1 | |
fi | |
} | |
# Validate the input arguments | |
if [ "$#" -lt 3 ] ; then | |
usage | |
exit 1 | |
fi | |
# Make sure we're all on the same version | |
check_version | |
account="$1" | |
region="$2" | |
component="$3" | |
action="$4" | |
log_level="$5" | |
log_env='' | |
# Set up credentials | |
umbrella_account_id="0000000" | |
prod_account_id="1111111" | |
dev_account_id="222222" | |
credentials_file=".temp_credentials.$account" | |
account_id="$(eval echo "\$${account}_account_id")" | |
role_arn="arn:aws:iam::$account_id:role/ops-admin" | |
role_session="ops" | |
do_echo "Running \"$component\" in account: $account region: $region" | |
assume_role() { | |
test -n "$AWS_MFA_SERIAL" || { do_warn 'Environment variable AWS_MFA_SERIAL not set'; exit 1; } | |
read -p "Input your TOTP token: " token | |
aws sts assume-role --output json \ | |
--role-arn ${role_arn} \ | |
--role-session-name ${role_session} \ | |
--serial-number ${AWS_MFA_SERIAL} \ | |
--token-code ${token} > ${credentials_file} | |
do_echo "Got temporary credentials for $account.$region" | |
} | |
check_credentials() { | |
if [ -s "$credentials_file" ] ; then | |
old_expiration=$(cat ${credentials_file} | grep "Expiration" | awk -F'"' '{ print $4 }') | |
if ! python -c "from datetime import datetime; import sys; sys.exit(int(datetime.strptime(\"$old_expiration\", '%Y-%m-%dT%H:%M:%SZ') < datetime.utcnow()))" ; then | |
assume_role | |
else | |
do_echo "Reusing unexpired credentials." | |
fi | |
else | |
assume_role | |
fi | |
export AWS_REGION="${region}" | |
export ASSUMED_ACCESS_KEY_ID="$(cat ${credentials_file} | grep "AccessKeyId" | awk -F'"' '{ print $4 }')" | |
export ASSUMED_SECRET_ACCESS_KEY="$(cat ${credentials_file} | grep "SecretAccessKey" | awk -F'"' '{ print $4 }')" | |
export ASSUMED_SESSION_TOKEN="$(cat ${credentials_file} | grep "SessionToken" | awk -F'"' '{ print $4 }')" | |
access_env="env AWS_ACCESS_KEY_ID=$ASSUMED_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$ASSUMED_SECRET_ACCESS_KEY AWS_SESSION_TOKEN=$ASSUMED_SESSION_TOKEN" | |
expiration=$(cat ${credentials_file} | grep "Expiration" | awk -F'"' '{ print $4 }') | |
do_echo "Retrieved temp access key ${AWS_ACCESS_KEY} for role ${role_arn}. Key will expire at ${expiration}" | |
} | |
check_credentials | |
if [ -z "$log_level" ] ; then | |
log_level=${TF_LOG-unset} # default to env variable if set, otherwise unset so we can have regular output | |
fi | |
if ! [ "$log_level" = 'unset' ] ; then | |
level=$(echo $log_level | tr '[a-z]' '[A-Z]') | |
do_echo "Log level set to: $level" | |
log_env="env TF_LOG=$level" | |
fi | |
# Validate that the environment has a provider and change directory into it so that all paths in | |
# Terraform modules are relative to it | |
test -d "providers/$account/$region/$component" || { do_warn "Component directory 'providers/$account/$region/$component' missing."; exit 1; } | |
cd "providers/$account/$region/$component" | |
case "$action" in | |
plan) ;; | |
apply) ;; | |
refresh) ;; | |
fmt) ;; | |
validate) ;; | |
graph) ;; | |
plan-destroy) ;; | |
destroy) ;; | |
*) | |
do_warn 'Invalid option.' | |
usage | |
exit 1 | |
esac | |
if [ "$action" = "plan-destroy" ] ; then | |
action="plan" | |
destroy="-destroy" | |
elif [ "$action" = "destroy" ] ; then | |
destroy='-destroy' | |
force='-force' | |
fi | |
# Clear the .terraform directory (we want to pull the state from the remote) | |
rm -rf "./.terraform" | |
# Configure remote state storage | |
do_echo "Configuring terraform remote config" | |
terraform remote config \ | |
-backend=S3 \ | |
-backend-config="region=$TERRAFORM_BUCKET_REGION" \ | |
-backend-config="bucket=$TERRAFORM_BUCKET_NAME" \ | |
-backend-config="key=$account.$region/$component.tfstate" \ | |
-backend-config="acl=bucket-owner-full-control" | |
do_echo "Getting latest terraform remote config" | |
terraform get | |
if [ "$action" = "plan" ] ; then | |
do_echo "Creating a plan." | |
$log_env $access_env terraform plan \ | |
-input=false \ | |
-refresh=true \ | |
-module-depth=-1 \ | |
$destroy | |
exit 0 | |
elif [ "$action" = "apply" ] ; then | |
read -p "Are you sure [y/N]: " do_it | |
if [ "$do_it" = "y" ] ; then | |
do_echo "Running apply" | |
$log_env $access_env terraform apply \ | |
-input=false \ | |
-refresh=true \ | |
$force | |
else | |
do_echo "Didn't do anything." | |
fi | |
else | |
do_echo "Running $action" | |
$log_env $access_env terraform "$action" | |
fi | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment