2018-04-26 09:41:22 -07:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
# Color support
|
|
|
|
|
|
|
|
function disable_color() {
|
|
|
|
IS_TTY=false
|
|
|
|
txtrst=
|
|
|
|
txtbld=
|
|
|
|
bldred=
|
|
|
|
bldgrn=
|
|
|
|
bldylw=
|
|
|
|
bldblu=
|
|
|
|
bldmag=
|
|
|
|
bldcyn=
|
|
|
|
}
|
|
|
|
|
|
|
|
IS_TTY=false
|
|
|
|
if [ -t 1 ]; then
|
|
|
|
if command -v tput >/dev/null; then
|
|
|
|
IS_TTY=true
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ "$IS_TTY" = "true" ]; then
|
|
|
|
txtrst=$(tput sgr0 || echo '\e[0m') # Reset
|
|
|
|
txtbld=$(tput bold || echo '\e[1m') # Bold
|
|
|
|
bldred=${txtbld}$(tput setaf 1 || echo '\e[31m') # Red
|
|
|
|
bldgrn=${txtbld}$(tput setaf 2 || echo '\e[32m') # Green
|
|
|
|
bldylw=${txtbld}$(tput setaf 3 || echo '\e[33m') # Yellow
|
|
|
|
bldblu=${txtbld}$(tput setaf 4 || echo '\e[34m') # Blue
|
|
|
|
bldmag=${txtbld}$(tput setaf 5 || echo '\e[35m') # Magenta
|
|
|
|
bldcyn=${txtbld}$(tput setaf 8 || echo '\e[38m') # Cyan
|
|
|
|
else
|
|
|
|
disable_color
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Logging
|
|
|
|
|
|
|
|
# Print the given message in cyan, but only when --verbose was passed
|
|
|
|
function debug() {
|
|
|
|
if [ ! -z "$VERBOSE" ]; then
|
|
|
|
printf '%s%s%s\n' "$bldcyn" "$1" "$txtrst"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Print the given message in blue
|
|
|
|
function info() {
|
|
|
|
printf '%s%s%s\n' "$bldblu" "$1" "$txtrst"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Print the given message in magenta
|
|
|
|
function action() {
|
|
|
|
printf '%s%s%s\n' "$bldmag" "$1" "$txtrst"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Print the given message in yellow
|
|
|
|
function warn() {
|
|
|
|
printf '%s%s%s\n' "$bldylw" "$1" "$txtrst"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Like warn, but expects the message via redirect
|
|
|
|
function warnb() {
|
|
|
|
printf '%s' "$bldylw"
|
|
|
|
while read -r data; do
|
|
|
|
printf '%s\n' "$data"
|
|
|
|
done
|
|
|
|
printf '%s\n' "$txtrst"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Print the given message in red
|
|
|
|
function error() {
|
|
|
|
printf '%s%s%s\n' "$bldred" "$1" "$txtrst"
|
2018-04-27 08:44:45 -07:00
|
|
|
exit 1
|
2018-04-26 09:41:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
# Like error, but expects the message via redirect
|
|
|
|
function errorb() {
|
|
|
|
printf '%s' "$bldred"
|
|
|
|
while read -r data; do
|
|
|
|
printf '%s\n' "$data"
|
|
|
|
done
|
|
|
|
printf '%s\n' "$txtrst"
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Print the given message in green
|
|
|
|
function success() {
|
|
|
|
printf '%s%s%s\n' "$bldgrn" "$1" "$txtrst"
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Print help if requested
|
|
|
|
function help() {
|
|
|
|
cat << EOF
|
|
|
|
POA Infrastructure Management Tool
|
|
|
|
|
|
|
|
Usage:
|
|
|
|
|
|
|
|
./infra [global options] <task> [task args]
|
|
|
|
|
|
|
|
This script will bootstrap required AWS resources, then generate infrastructure via Terraform.
|
|
|
|
|
|
|
|
Tasks:
|
|
|
|
|
|
|
|
help Show help
|
|
|
|
provision Run the provisioner to generate or modify POA infrastructure
|
|
|
|
destroy Tear down any provisioned resources and local state
|
2018-04-28 22:45:42 -07:00
|
|
|
resources List ARNs of any generated resources (* see docs for caveats)
|
2018-04-26 09:41:22 -07:00
|
|
|
|
|
|
|
Global Options:
|
|
|
|
|
|
|
|
-v | --verbose This will print out verbose execution information for debugging
|
|
|
|
-h | --help Print this help message
|
|
|
|
--dry-run Perform as many actions as possible without performing side-effects
|
|
|
|
--no-color Turn off color
|
2018-04-28 22:45:42 -07:00
|
|
|
--skip-approval Automatically accept any prompts for confirmation
|
|
|
|
--profile=<name> Use a specific AWS profile rather than the default
|
2018-04-26 09:41:22 -07:00
|
|
|
EOF
|
|
|
|
exit 2
|
|
|
|
}
|
|
|
|
|
|
|
|
# Verify tools
|
|
|
|
function check_prereqs() {
|
|
|
|
if ! which jq >/dev/null; then
|
|
|
|
warnb << EOF
|
|
|
|
This script requires that the 'jq' utility has been installed and can be found in $PATH
|
|
|
|
|
|
|
|
On macOS, with Homebrew, this is as simple as 'brew install jq'.
|
|
|
|
|
|
|
|
For installs on other platforms, see https://stedolan.github.io/jq/download/
|
|
|
|
EOF
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
|
|
|
|
if ! which aws >/dev/null; then
|
|
|
|
warnb << EOF
|
|
|
|
This script requires that the AWS CLI tool has been installed and can be found in $PATH
|
|
|
|
|
|
|
|
On macOS, with Homebrew, this is as simple as 'brew install awscli'.
|
|
|
|
|
|
|
|
For installs on other platforms, see https://docs.aws.amazon.com/cli/latest/userguide/installing.html
|
|
|
|
EOF
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
|
|
|
|
if ! which terraform >/dev/null; then
|
|
|
|
warnb << EOF
|
|
|
|
This script requires that the Terraform CLI be installed and available in PATH!
|
|
|
|
|
|
|
|
On macOS, with Homebrew, this is as simple as 'brew install terraform'.
|
|
|
|
|
|
|
|
For other platforms, see https://www.terraform.io/intro/getting-started/install.html
|
|
|
|
EOF
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2018-04-28 22:45:42 -07:00
|
|
|
# Load a value which is present in one of the Terraform config
|
|
|
|
# files in the current directory, with precedence such that user-provided
|
|
|
|
# .tfvars are loaded after main.tfvars, allowing one to override those values
|
|
|
|
function get_config() {
|
2018-05-17 10:45:28 -07:00
|
|
|
EXTRA_VARS="$(find . -name '*.tfvars' -and \! \( -name 'backend.tfvars' \))"
|
2018-06-01 07:59:36 -07:00
|
|
|
if [ ! -z "$EXTRA_VARS" ]; then
|
|
|
|
# shellcheck disable=SC2086 disable=2002
|
|
|
|
cat $EXTRA_VARS | \
|
|
|
|
grep -E "^$1 " | \
|
|
|
|
tail -n 1 | \
|
|
|
|
sed -r -e 's/^[^=]*= //' -e 's/"//g'
|
|
|
|
fi
|
2018-04-28 22:45:42 -07:00
|
|
|
}
|
|
|
|
|
2018-04-26 11:55:29 -07:00
|
|
|
function destroy_bucket() {
|
2018-04-27 11:24:11 -07:00
|
|
|
bucket="$(grep 'bucket' backend.tfvars | sed -e 's/bucket = //' -e 's/"//g')"
|
2018-04-26 11:55:29 -07:00
|
|
|
read -r -p "Are you super sure you want to delete the Terraform state bucket and all versions? (y/n) "
|
|
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
# Delete all versions and delete markers first
|
2018-04-27 12:22:40 -07:00
|
|
|
info "Disabling bucket versioning for S3 bucket '$bucket'.."
|
|
|
|
aws s3api put-bucket-versioning --bucket="$bucket" --versioning-configuration="Status=Suspended"
|
|
|
|
info "Deleting old versions of S3 bucket '$bucket'.."
|
|
|
|
# shellcheck disable=SC1004
|
2018-04-26 11:55:29 -07:00
|
|
|
aws s3api list-object-versions --bucket="$bucket" |\
|
|
|
|
jq '.Versions[], .DeleteMarkers[] | "\"\(.Key)\" \"\(.VersionId)\""' --raw-output |\
|
2018-04-27 12:22:40 -07:00
|
|
|
awk -v bucket="$bucket" '{ \
|
|
|
|
print "aws s3api delete-object", \
|
|
|
|
"--bucket=\"" bucket "\"", \
|
|
|
|
"--key=\"" $1 "\"", \
|
|
|
|
"--version-id=\"" $2 "\"" \
|
|
|
|
| "/bin/sh >/dev/null"; \
|
|
|
|
print "Deleted version " $2 "of " $1 " successfully"; \
|
|
|
|
}'
|
2018-04-26 11:55:29 -07:00
|
|
|
# Finally, delete the bucket and all its contents
|
|
|
|
aws s3 rb --force "s3://$bucket"
|
|
|
|
}
|
|
|
|
|
|
|
|
function destroy_dynamo_table() {
|
2018-04-27 11:24:11 -07:00
|
|
|
table="$(grep 'dynamodb_table' backend.tfvars | sed -e 's/dynamodb_table = //' -e 's/"//g')"
|
2018-04-26 11:55:29 -07:00
|
|
|
aws dynamodb delete-table --table-name="$table"
|
|
|
|
}
|
|
|
|
|
|
|
|
function destroy_generated_files() {
|
2018-04-26 09:41:22 -07:00
|
|
|
rm -f ./backend.tfvars
|
|
|
|
rm -f ./main.tfvars
|
2018-04-26 11:55:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
# Tear down all provisioned infra
|
|
|
|
function destroy() {
|
2018-04-27 12:22:40 -07:00
|
|
|
# shellcheck disable=SC2086
|
2018-04-28 22:45:42 -07:00
|
|
|
terraform plan -destroy -var-file=main.tfvars -out plans/destroy.planfile main
|
|
|
|
read -r -p "Are you sure you want to run this plan? (y/n) "
|
|
|
|
if [[ $REPLY =~ ^[yY]$ ]]; then
|
|
|
|
terraform apply plans/destroy.planfile
|
|
|
|
rm -f plans/destroy.planfile
|
|
|
|
else
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
read -r -p "Do you wish to destroy the Terraform state? (y/n) "
|
|
|
|
if [[ $REPLY =~ ^[yY]$ ]]; then
|
|
|
|
destroy_bucket
|
|
|
|
destroy_dynamo_table
|
|
|
|
rm -rf terraform.tfstate.d
|
|
|
|
rm -rf .terraform
|
|
|
|
else
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
read -r -p "Do you want to delete the generated config files? (y/n) "
|
|
|
|
if [[ $REPLY =~ ^[yY]$ ]]; then
|
|
|
|
destroy_generated_files
|
|
|
|
fi
|
2018-04-26 09:41:22 -07:00
|
|
|
success "All generated infrastructure successfully removed!"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Provision infrastructure
|
|
|
|
function provision() {
|
|
|
|
# If INFRA_PREFIX has not been set yet, request it from user
|
|
|
|
if [ -z "$INFRA_PREFIX" ]; then
|
2018-06-21 12:51:40 -07:00
|
|
|
DEFAULT_INFRA_PREFIX=$(LC_ALL=C tr -dc 'a-z0-9' < /dev/urandom | fold -w 5 | head -n 1)
|
2018-04-26 09:41:22 -07:00
|
|
|
|
|
|
|
warnb << EOF
|
|
|
|
# Infrastructure Prefix
|
|
|
|
|
|
|
|
In order to ensure that provisioned resources are unique, this script uses a
|
|
|
|
unique prefix for all resource names and ids.
|
|
|
|
|
2018-05-17 08:14:04 -07:00
|
|
|
By default, a random 5 character alphanumeric string is generated for you, but
|
2018-04-26 09:41:22 -07:00
|
|
|
if you wish to provide your own, now is your chance. This value will be stored
|
2018-04-28 22:45:42 -07:00
|
|
|
in 'main.tfvars' so that you only need provide it once, but make sure you source
|
2018-04-26 09:41:22 -07:00
|
|
|
control the file.
|
|
|
|
EOF
|
|
|
|
|
|
|
|
read -r -p "What prefix should be used? (default is $DEFAULT_INFRA_PREFIX): "
|
|
|
|
INFRA_PREFIX="$REPLY"
|
|
|
|
if [ -z "$INFRA_PREFIX" ]; then
|
|
|
|
INFRA_PREFIX="$DEFAULT_INFRA_PREFIX"
|
|
|
|
fi
|
2018-04-28 22:45:42 -07:00
|
|
|
fi
|
|
|
|
|
2018-04-30 11:28:59 -07:00
|
|
|
if ! echo "$INFRA_PREFIX" | grep -E '^[a-z0-9]{3,5}$'; then
|
2018-04-28 22:45:42 -07:00
|
|
|
errorb << EOF
|
|
|
|
The prefix '$INFRA_PREFIX' is invalid!
|
|
|
|
|
|
|
|
It must consist only of the lowercase characters a-z and digits 0-9,
|
2018-04-30 11:28:59 -07:00
|
|
|
and must be between 3 and 5 characters long.
|
2018-04-28 22:45:42 -07:00
|
|
|
EOF
|
2018-04-26 09:41:22 -07:00
|
|
|
fi
|
|
|
|
|
|
|
|
# EC2 key pairs
|
|
|
|
if [ -z "$KEY_PAIR" ]; then
|
2018-04-28 22:45:42 -07:00
|
|
|
KEY_PAIR="$(get_config 'key_name')"
|
2018-04-26 09:41:22 -07:00
|
|
|
if [ -z "$KEY_PAIR" ]; then
|
2018-04-28 22:45:42 -07:00
|
|
|
read -r -p "Please provide the name of the key pair to use with EC2 hosts: "
|
|
|
|
KEY_PAIR="$REPLY"
|
|
|
|
if [ -z "$KEY_PAIR" ]; then
|
|
|
|
error "You must provide a valid key pair name!"
|
|
|
|
exit 2
|
|
|
|
fi
|
2018-04-26 09:41:22 -07:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
if ! aws ec2 describe-key-pairs --key-names="$KEY_PAIR" 2>/dev/null; then
|
|
|
|
if [ "$DRY_RUN" == "true" ]; then
|
|
|
|
action "DRY RUN: Would have created an EC2 key pair"
|
|
|
|
else
|
|
|
|
info "The key pair '$KEY_PAIR' does not exist, creating..."
|
|
|
|
if ! output=$(aws ec2 create-key-pair --key-name="$KEY_PAIR"); then
|
|
|
|
error "$output\\nFailed to generate key pair!"
|
|
|
|
fi
|
|
|
|
echo "$output" | jq '.KeyMaterial' --raw-output > "$KEY_PAIR.privkey"
|
|
|
|
success "Created keypair successfully! Private key has been saved to ./$KEY_PAIR.privkey"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2018-04-28 22:45:42 -07:00
|
|
|
if [ -z "$SECRET_KEY_BASE" ]; then
|
|
|
|
SECRET_KEY_BASE="$(get_config 'secret_key_base')"
|
|
|
|
if [ -z "$SECRET_KEY_BASE" ]; then
|
2018-10-18 13:37:54 -07:00
|
|
|
SECRET_KEY_BASE="$(openssl rand -base64 64 | tr -d '\n')"
|
2018-04-28 22:45:42 -07:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2018-04-26 09:41:22 -07:00
|
|
|
# Save variables used by Terraform modules
|
2018-05-17 10:45:28 -07:00
|
|
|
if [ ! -f ./backend.tfvars ] && [ ! -f ./main.tfvars ]; then
|
2018-04-26 09:41:22 -07:00
|
|
|
# shellcheck disable=SC2154
|
|
|
|
region="$TF_VAR_region"
|
|
|
|
if [ -z "$region" ]; then
|
|
|
|
# Try to pull region from local config
|
|
|
|
if [ -f "$HOME/.aws/config" ]; then
|
2018-04-27 11:09:50 -07:00
|
|
|
if [ "$AWS_PROFILE" == "default" ]; then
|
|
|
|
region=$(awk '/\[default\]/{a=1;next}; /\[/{a=0}a' ~/.aws/config | grep 'region' | sed -e 's/region = //')
|
|
|
|
else
|
|
|
|
#shellcheck disable=SC1117
|
|
|
|
region=$(awk "/\[profile $AWS_PROFILE\]/{a=1;next}; /\[/{a=0}a" ~/.aws/config | grep 'region' | sed -e 's/region = //')
|
|
|
|
fi
|
2018-04-26 09:41:22 -07:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ -z "$region" ]; then
|
2018-04-28 22:45:42 -07:00
|
|
|
read -r -p "What region should infrastructure be created in (us-east-2): "
|
|
|
|
if [ -z "$REPLY" ]; then
|
|
|
|
region='us-east-2'
|
|
|
|
else
|
|
|
|
region="$REPLY"
|
|
|
|
fi
|
2018-04-26 09:41:22 -07:00
|
|
|
fi
|
2018-06-01 07:59:36 -07:00
|
|
|
bucket="$(get_config 'bucket')"
|
|
|
|
if [ -z "$bucket" ]; then
|
|
|
|
bucket="poa-terraform-state"
|
|
|
|
fi
|
|
|
|
dynamo_table="$(get_config 'dynamodb_table')"
|
|
|
|
if [ -z "$dynamo_table" ]; then
|
|
|
|
dynamo_table="poa-terraform-locks"
|
|
|
|
fi
|
2018-04-26 09:41:22 -07:00
|
|
|
# Backend config only!
|
|
|
|
{
|
|
|
|
echo "region = \"$region\""
|
2018-06-01 07:59:36 -07:00
|
|
|
echo "bucket = \"${INFRA_PREFIX}-$bucket\""
|
|
|
|
echo "dynamodb_table = \"${INFRA_PREFIX}-$dynamo_table\""
|
2018-04-26 09:41:22 -07:00
|
|
|
echo "key = \"terraform.tfstate\""
|
|
|
|
} > ./backend.tfvars
|
|
|
|
# Other configuration needs to go in main.tfvars or init will break
|
|
|
|
{
|
|
|
|
echo "region = \"$region\""
|
2018-06-01 07:59:36 -07:00
|
|
|
echo "bucket = \"$bucket\""
|
|
|
|
echo "dynamodb_table = \"$dynamo_table\""
|
2018-04-26 09:41:22 -07:00
|
|
|
echo "key_name = \"$KEY_PAIR\""
|
|
|
|
echo "prefix = \"$INFRA_PREFIX\""
|
|
|
|
echo "secret_key_base = \"$SECRET_KEY_BASE\""
|
|
|
|
} > ./main.tfvars
|
|
|
|
fi
|
|
|
|
|
2018-04-28 22:45:42 -07:00
|
|
|
# No Terraform state yet, so this is a fresh run
|
|
|
|
if [ ! -d .terraform ]; then
|
|
|
|
terraform workspace new base setup
|
|
|
|
terraform workspace select base setup
|
|
|
|
# shellcheck disable=SC2086
|
2018-05-17 10:45:28 -07:00
|
|
|
terraform init -backend-config=backend.tfvars setup
|
2018-04-28 22:45:42 -07:00
|
|
|
# shellcheck disable=SC2086
|
2018-05-17 10:45:28 -07:00
|
|
|
terraform plan -out plans/setup.planfile setup
|
2018-04-26 09:41:22 -07:00
|
|
|
|
2018-04-28 22:45:42 -07:00
|
|
|
if [ "$DRY_RUN" == "false" ]; then
|
|
|
|
# No need to show the plan, it has already been displayed
|
|
|
|
SKIP_SETUP_PLAN="true"
|
|
|
|
fi
|
|
|
|
fi
|
2018-04-26 09:41:22 -07:00
|
|
|
|
2018-04-28 22:45:42 -07:00
|
|
|
workspace="$(terraform workspace show)"
|
2018-04-26 09:41:22 -07:00
|
|
|
|
2018-04-28 22:45:42 -07:00
|
|
|
# Setup hasn't completed yet, perhaps due to a dry run
|
|
|
|
if [ -f plans/setup.planfile ]; then
|
|
|
|
if [ -z "$SKIP_SETUP_PLAN" ]; then
|
|
|
|
# Regenerate setup plan if not fresh
|
2018-04-27 11:24:11 -07:00
|
|
|
# shellcheck disable=SC2086
|
2018-05-17 10:45:28 -07:00
|
|
|
terraform plan -out plans/setup.planfile setup
|
2018-04-26 09:41:22 -07:00
|
|
|
fi
|
2018-04-28 22:45:42 -07:00
|
|
|
# Wait for user approval if we're going to proceed
|
|
|
|
if [ "$SKIP_APPROVAL" == "false" ]; then
|
|
|
|
read -r -p "Take a moment to review the generated plan, and press ENTER to continue"
|
2018-04-26 09:41:22 -07:00
|
|
|
fi
|
2018-04-28 22:45:42 -07:00
|
|
|
if [ "$DRY_RUN" == "true" ]; then
|
|
|
|
action "DRY RUN: Would have executed Terraform plan for S3 backend as just shown"
|
|
|
|
warn "Unable to dry run further steps until S3 backend has been created!"
|
|
|
|
exit 0
|
2018-04-26 09:41:22 -07:00
|
|
|
fi
|
2018-04-28 22:45:42 -07:00
|
|
|
terraform apply plans/setup.planfile
|
|
|
|
rm plans/setup.planfile
|
|
|
|
# Migrate state to S3
|
|
|
|
# shellcheck disable=SC2086
|
2018-05-17 10:45:28 -07:00
|
|
|
terraform init -force-copy -backend-config=backend.tfvars base
|
2018-04-28 22:45:42 -07:00
|
|
|
fi
|
2018-04-26 09:41:22 -07:00
|
|
|
|
2018-04-28 22:45:42 -07:00
|
|
|
if [ "$workspace" == "base" ]; then
|
|
|
|
# Switch to main workspace
|
|
|
|
terraform workspace new main main
|
2018-04-26 09:41:22 -07:00
|
|
|
terraform workspace select main main
|
|
|
|
fi
|
2018-04-28 22:45:42 -07:00
|
|
|
# shellcheck disable=SC2086
|
|
|
|
terraform init -backend-config=backend.tfvars -var-file=main.tfvars main
|
|
|
|
# Generate the plan for the remaining infra
|
|
|
|
# shellcheck disable=SC2086
|
|
|
|
terraform plan -var-file=main.tfvars -out plans/main.planfile main
|
|
|
|
if [ "$SKIP_APPROVAL" == "false" ]; then
|
|
|
|
read -r -p "Take a moment to review the generated plan, and press ENTER to continue"
|
|
|
|
fi
|
2018-04-26 09:41:22 -07:00
|
|
|
if [ "$DRY_RUN" == "true" ]; then
|
2018-04-28 22:45:42 -07:00
|
|
|
action "DRY RUN: Would have executed the Terraform plan just shown"
|
2018-04-26 09:41:22 -07:00
|
|
|
fi
|
2018-04-28 22:45:42 -07:00
|
|
|
|
|
|
|
# Apply the plan to provision the remaining infra
|
|
|
|
terraform apply plans/main.planfile
|
|
|
|
rm plans/main.planfile
|
|
|
|
success "Infrastructure has been successfully provisioned!"
|
2018-04-26 09:41:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
# Print all resource ARNs tagged with prefix=INFRA_PREFIX
|
|
|
|
function resources() {
|
|
|
|
if [ -z "$INFRA_PREFIX" ]; then
|
|
|
|
error "No prefix set, unable to locate tagged resources"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
# Yes, stagging, blame Amazon
|
|
|
|
aws resourcegroupstaggingapi get-resources \
|
|
|
|
--no-paginate \
|
|
|
|
--tag-filters="Key=prefix,Values=$INFRA_PREFIX" | \
|
|
|
|
jq '.ResourceTagMappingList[].ResourceARN' --raw-output
|
|
|
|
}
|
|
|
|
|
|
|
|
# Provide test data for validation
|
|
|
|
function precheck() {
|
|
|
|
# Save variables used by Terraform modules
|
|
|
|
if [ ! -f ./ignore.tfvars ]; then
|
|
|
|
{
|
|
|
|
echo "bucket = \"poa-terraform-state\""
|
|
|
|
echo "dynamodb_table = \"poa-terraform-locks\""
|
|
|
|
echo "key = \"terraform.tfstate\""
|
|
|
|
echo "key_name = \"poa\""
|
|
|
|
echo "prefix = \"prefix\""
|
|
|
|
} > ./ignore.tfvars
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Parse options for this script
|
|
|
|
VERBOSE=false
|
|
|
|
HELP=false
|
|
|
|
DRY_RUN=false
|
|
|
|
|
2018-04-27 11:09:50 -07:00
|
|
|
# Environment variables for Terraform
|
|
|
|
AWS_PROFILE="${AWS_PROFILE:-default}"
|
|
|
|
|
2018-04-26 09:41:22 -07:00
|
|
|
COMMAND=
|
|
|
|
while [ "$1" != "" ]; do
|
|
|
|
param=$(echo "$1" | sed -re 's/^([^=]*)=/\1/')
|
2018-04-27 11:09:50 -07:00
|
|
|
val=$(echo "$1" | sed -re 's/^([^=]*)=//')
|
2018-04-26 09:41:22 -07:00
|
|
|
case $param in
|
|
|
|
-h | --help)
|
|
|
|
HELP=true
|
|
|
|
;;
|
|
|
|
-v | --verbose)
|
|
|
|
VERBOSE=true
|
|
|
|
;;
|
|
|
|
--dry-run)
|
|
|
|
DRY_RUN=true
|
|
|
|
;;
|
|
|
|
--no-color)
|
|
|
|
disable_color
|
|
|
|
;;
|
2018-04-27 11:09:50 -07:00
|
|
|
--profile)
|
|
|
|
AWS_PROFILE="$val"
|
|
|
|
;;
|
2018-04-28 22:45:42 -07:00
|
|
|
--skip-approval)
|
|
|
|
SKIP_APPROVAL="true"
|
|
|
|
;;
|
2018-04-26 09:41:22 -07:00
|
|
|
--)
|
|
|
|
shift
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
COMMAND="$param"
|
|
|
|
shift
|
|
|
|
break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
|
|
|
# Turn on debug mode if --verbose was set
|
|
|
|
if [ "$VERBOSE" == "true" ]; then
|
|
|
|
set -x
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Set working directory to the project root
|
|
|
|
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
|
|
|
|
2018-04-27 11:09:50 -07:00
|
|
|
# Export AWS_PROFILE if a non-default profile was chosen
|
|
|
|
if [ ! "$AWS_PROFILE" == "default" ]; then
|
|
|
|
export AWS_PROFILE
|
|
|
|
fi
|
|
|
|
|
2018-04-26 09:41:22 -07:00
|
|
|
# If cached prefix is in PREFIX file, then use it
|
2018-05-17 10:45:28 -07:00
|
|
|
if [ -z "$INFRA_PREFIX" ]; then
|
|
|
|
if ls ./*.tfvars >/dev/null; then
|
|
|
|
INFRA_PREFIX="$(get_config 'prefix')"
|
|
|
|
fi
|
2018-04-26 09:41:22 -07:00
|
|
|
fi
|
|
|
|
|
|
|
|
# Override command if --help or -h was passed
|
|
|
|
if [ "$HELP" == "true" ]; then
|
|
|
|
# If we ever want to show help for a specific command we'll need this
|
|
|
|
# HELP_COMMAND="$COMMAND"
|
|
|
|
COMMAND=help
|
|
|
|
fi
|
|
|
|
|
|
|
|
check_prereqs
|
|
|
|
|
|
|
|
case $COMMAND in
|
|
|
|
help)
|
|
|
|
help
|
|
|
|
;;
|
|
|
|
provision)
|
|
|
|
provision
|
|
|
|
;;
|
|
|
|
destroy)
|
|
|
|
destroy
|
|
|
|
;;
|
|
|
|
resources)
|
|
|
|
resources
|
|
|
|
;;
|
|
|
|
precheck)
|
|
|
|
precheck
|
|
|
|
;;
|
2018-04-28 22:45:42 -07:00
|
|
|
destroy_setup)
|
|
|
|
destroy_bucket
|
|
|
|
destroy_dynamo_table
|
|
|
|
;;
|
2018-04-26 09:41:22 -07:00
|
|
|
*)
|
|
|
|
error "Unknown task '$COMMAND'. Try 'help' to see valid tasks"
|
|
|
|
exit 1
|
|
|
|
esac
|
|
|
|
|
|
|
|
exit 0
|