-
Notifications
You must be signed in to change notification settings - Fork 0
/
poutine
executable file
·172 lines (139 loc) · 4.85 KB
/
poutine
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#! /usr/bin/env bash
# Description:
# This script is a wrapper for Terraform, ostensibly to manage tfstate, but
# mostly just to make your life more difficult.
#
# Maintainer: Chris Scholz <[email protected]
# Author: Chris Scholz <[email protected]> // Don't blame plz
[[ $DEBUG ]] && set -x
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TF_DIR="${SCRIPT_DIR}/resources/terraform"
# Hardcode exclusions
EXCLUDE=(modules templates)
ROLES=()
pushd "$TF_DIR" > /dev/null
for f in *; do
if [[ -d "$f" ]]; then
if ! [[ "$f" =~ $EXCLUDE ]]; then
ROLES+=("$f")
fi
fi
done
popd > /dev/null
[[ $DEBUG ]] && echo "DEBUG: Valid ROLES: ${ROLES[@]}"
HELP=("help" "-h" "--help" "-?")
function help {
echo "USAGE: ${0} <action> <environment> <build option> <tfstate identifier key>"
echo "Valid build options are: ${ROLES[*]}"
exit 1
}
function get_variable() {
# Take in a key="value" and echo the value
echo "$1" | awk -F\" '{print $2}'
}
function check_element_exists() {
local elem
for elem in "${@:2}"; do
# If the arg is in the array, short circuit with success
if [[ "$elem" == "$1" ]]; then
return 0
fi
done
# otherwise, bail with error
return 1
}
# Check for help request, lack of arguments, and valid arguments
check_element_exists "$1" "${HELP[@]}"
if [[ "${1}test" == "test" ]]; then
help
fi
if [[ $# -gt 4 ]] || [[ $# -lt 3 ]]; then
help
fi
check_element_exists "$3" "${ROLES[@]}"
if [ $? -ne 0 ]; then
echo "${3} is not a valid build option."
help
fi
ACTION="$1"
ENVIRONMENT="$2"
ROLE="$3"
TFSTATE_IDENTIFER_KEY="$4"
TFVARS="${TF_DIR}/${ROLE}/terraform.tfvars"
# Get the bucket name from the TFVARs file
BUCKET=$(grep secret_bucket $TFVARS 2>/dev/null)
if [[ "$?" != "0" ]]; then
echo "ERROR: Did not get valid secret_bucket name from $TFVARS"
exit 1
else
BUCKET=$(get_variable $BUCKET)
fi
STATE_DIR=$(grep tf_state_bucket_prefix $TFVARS 2>/dev/null)
# Set terraform remote config:
TF_REMOTE_STATE_KEY="${ROLE}_${ENVIRONMENT}"
if [[ $TFSTATE_IDENTIFER_KEY ]]; then
TF_REMOTE_STATE_KEY="${ROLE}_${ENVIRONMENT}_${TFSTATE_IDENTIFER_KEY}"
fi
if [[ "$?" == 0 ]]; then
TF_REMOTE_STATE_KEY="${TF_REMOTE_STATE_KEY}/$(get_variable "$STATE_DIR")"
fi
[[ $DEBUG ]] && echo "DEBUG: Storing remote state in ${BUCKET}:${TF_REMOTE_STATE_KEY}..."
AWS_ACCESS_KEY_ID=$(grep -m1 access_key "$TFVARS" 2>/dev/null)
if [[ "$?" == "0" ]]; then
export AWS_ACCESS_KEY_ID=$(get_variable "$AWS_ACCESS_KEY_ID")
if [[ -z "$AWS_ACCESS_KEY_ID" ]]; then
echo "AWS_ACCESS_KEY_ID not set and access_key not found in $TFVARS"
exit 1
fi
fi
AWS_SECRET_ACCESS_KEY=$(grep -m1 secret_key "$TFVARS" 2>/dev/null)
if [[ "$?" == "0" ]]; then
export AWS_SECRET_ACCESS_KEY=$(get_variable "$AWS_SECRET_ACCESS_KEY")
if [[ -z "$AWS_SECRET_ACCESS_KEY" ]]; then
echo "AWS_SECRET_ACCESS_KEY not set and secret_key not found in $TFVARS"
exit 1
fi
fi
if [[ -z "$AWS_DEFAULT_REGION" ]]; then
AWS_DEFAULT_REGION=$(grep -m1 region "$TFVARS" 2>/dev/null)
export AWS_DEFAULT_REGION=$(get_variable "$AWS_DEFAULT_REGION")
if [[ -z "$AWS_DEFAULT_REGION" ]]; then
echo "AWS_DEFAULT_REGION not set and region not found in $TFVARS"
exit 1
fi
fi
# Fail on errors and be verbose
set -ex
# change to $ROLE directory
pushd "${TF_DIR}/${ROLE}" > /dev/null
[[ $DEBUG ]] && echo "\tAWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID\n\tAWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY\n\tAWS_DEFAULT_REGION: $AWS_DEFAULT_REGION"
# Remove any traces of local tfstate files. I think those are screwing up
# cross-environment builds
if [[ -f ".terraform/terraform.tfstate" ]]; then
echo "=== Moving .terraform/*.tfstate* to .terraform/tf-backup/ ==="
mkdir -p ./.terraform/tf-backup
mv .terraform/*.tfstate* .terraform/tf-backup/
fi
[[ $DEBUG ]] && export TF_LOG=$DEBUG
echo "=== Configuring remote state management for $ENVIRONMENT-$ROLE in $BUCKET bucket. ==="
terraform remote config -backend="S3" -backend-config="bucket=${BUCKET}" -backend-config="key=${TF_REMOTE_STATE_KEY}"
# Run Terraform, but don't fail if TF fails.
set +e
TF_VAR_environment_name="${ENVIRONMENT}" terraform $ACTION
TF_EXIT_CODE=$?
# Fail on errors again.
set -e
# Backup tfstate for versioning here, just in case the world blows up
echo "=== Backing up state to cloud storage (just in case) ==="
if [[ $TFSTATE_IDENTIFER_KEY ]]; then
aws s3 cp .terraform/terraform.tfstate "s3://${BUCKET}/tfstate/${ENVIRONMENT}/${ROLE}_${TFSTATE_IDENTIFER_KEY}/terraform.${USER}.tfstate"
else
aws s3 cp .terraform/terraform.tfstate "s3://${BUCKET}/tfstate/${ENVIRONMENT}/${ROLE}/terraform.${USER}.tfstate"
fi
# remove all state files
echo "=== Deleting local terraform.tfstate files ==="
rm -rf .terraform/terraform.tfstate*
rm -rf .terraform/tf-backup
# GTFO
popd > /dev/null
exit $TF_EXIT_CODE