Skip to content

Instantly share code, notes, and snippets.

@danielscholl
Last active December 11, 2019 15:11
Show Gist options
  • Save danielscholl/5974a8f3e6c0ecfb45444b690f4299cd to your computer and use it in GitHub Desktop.
Save danielscholl/5974a8f3e6c0ecfb45444b690f4299cd to your computer and use it in GitHub Desktop.
Terraform Backend State Manage
#!/usr/bin/env bash
#
# Purpose: Initialize the terraform backend-state
# Usage:
# init-backend-state.sh <resourcegroup> <storageaccount> <keyvault>
# curl https://gist.githubusercontent.com/danielscholl/5974a8f3e6c0ecfb45444b690f4299cd/raw/30356cb760c489cbff922c473864edef8779a059/init-backend-state.sh | bash -s <rg> <sa> <kv>
set -e
###############################
## ARGUMENT INPUT ##
###############################
usage() { echo "Usage: init.sh <resourcegroup> <storageaccount> <keyvault>" 1>&2; exit 1; }
if [ -f ~/.azure/.env ]; then source ~/.azure/.env; fi
if [ -f ../../.env ]; then source ../../.env; fi
if [ -f ./.env ]; then source ./.env; fi
if [ -z $ARM_SUBSCRIPTION_ID ]; then
tput setaf 1; echo 'ERROR: ARM_SUBSCRIPTION_ID not provided' ; tput sgr0
usage;
fi
if [ -z $AZURE_VAULT_SECRET ]; then
AZURE_VAULT_SECRET="tfstate-storage-key"
fi
if [ -z $AZURE_LOCATION ]; then
AZURE_LOCATION="eastus2"
fi
if [ ! -z $1 ]; then AZURE_GROUP=$1; fi
if [ -z $AZURE_GROUP ]; then
tput setaf 1; echo 'ERROR: AZURE_GROUP not provided' ; tput sgr0
usage;
fi
if [ ! -z $2 ]; then AZURE_STORAGE=$2; fi
if [ -z $AZURE_STORAGE ]; then
tput setaf 1; echo 'ERROR: AZURE_STORAGE not provided' ; tput sgr0
usage;
fi
if [ ! -z $3 ]; then AZURE_VAULT=$3; fi
if [ -z $AZURE_VAULT ]; then
tput setaf 1; echo 'ERROR: AZURE_VAULT not provided' ; tput sgr0
usage;
fi
if [ ! -z $4 ]; then REMOTE_STATE_CONTAINER=$4; fi
if [ -z $REMOTE_STATE_CONTAINER ]; then
REMOTE_STATE_CONTAINER="remote-state-container"
fi
###############################
## FUNCTIONS ##
###############################
function CreateResourceGroup() {
# Required Argument $1 = RESOURCE_GROUP
# Required Argument $2 = LOCATION
if [ -z $1 ]; then
tput setaf 1; echo 'ERROR: Argument $1 (RESOURCE_GROUP) not received'; tput sgr0
exit 1;
fi
if [ -z $2 ]; then
tput setaf 1; echo 'ERROR: Argument $2 (LOCATION) not received'; tput sgr0
exit 1;
fi
local _result=$(az group show --name $1)
if [ "$_result" == "" ]
then
OUTPUT=$(az group create --name $1 \
--location $2 \
-ojsonc)
else
tput setaf 3; echo "Resource Group $1 already exists."; tput sgr0
fi
}
function CreateKeyVault() {
# Required Argument $1 = KV_NAME
# Required Argument $2 = RESOURCE_GROUP
# Required Argument $3 = LOCATION
if [ -z $1 ]; then
tput setaf 1; echo 'ERROR: Argument $1 (KV_NAME) not received' ; tput sgr0
exit 1;
fi
if [ -z $2 ]; then
tput setaf 1; echo 'ERROR: Argument $2 (RESOURCE_GROUP) not received' ; tput sgr0
exit 1;
fi
if [ -z $3 ]; then
tput setaf 1; echo 'ERROR: Argument $3 (LOCATION) not received' ; tput sgr0
exit 1;
fi
local _vault=$(az keyvault list --resource-group $2 --query [].name -otsv)
if [ "$_vault" == "" ]
then
OUTPUT=$(az keyvault create --name $1 --resource-group $2 --location $3 --query [].name -otsv)
else
tput setaf 3; echo "Key Vault $1 already exists."; tput sgr0
fi
}
function CreateStorageAccount() {
# Required Argument $1 = STORAGE_ACCOUNT
# Required Argument $2 = RESOURCE_GROUP
# Required Argument $3 = LOCATION
if [ -z $1 ]; then
tput setaf 1; echo 'ERROR: Argument $1 (STORAGE_ACCOUNT) not received' ; tput sgr0
exit 1;
fi
if [ -z $2 ]; then
tput setaf 1; echo 'ERROR: Argument $2 (RESOURCE_GROUP) not received' ; tput sgr0
exit 1;
fi
if [ -z $3 ]; then
tput setaf 1; echo 'ERROR: Argument $3 (LOCATION) not received' ; tput sgr0
exit 1;
fi
local _storage=$(az storage account show --name $1 --resource-group $2 --query name -otsv)
if [ "$_storage" == "" ]
then
OUTPUT=$(az storage account create \
--name $1 \
--resource-group $2 \
--location $3 \
--sku Standard_LRS \
--encryption-services blob \
--query name -otsv)
else
tput setaf 3; echo "Storage Account $1 already exists."; tput sgr0
fi
}
function GetStorageAccountKey() {
# Required Argument $1 = STORAGE_ACCOUNT
# Required Argument $2 = RESOURCE_GROUP
if [ -z $1 ]; then
tput setaf 1; echo 'ERROR: Argument $1 (STORAGE_ACCOUNT) not received'; tput sgr0
exit 1;
fi
if [ -z $2 ]; then
tput setaf 1; echo 'ERROR: Argument $2 (RESOURCE_GROUP) not received'; tput sgr0
exit 1;
fi
local _result=$(az storage account keys list \
--account-name $1 \
--resource-group $2 \
--query '[0].value' \
--output tsv)
echo ${_result}
}
function CreateBlobContainer() {
# Required Argument $1 = CONTAINER_NAME
# Required Argument $2 = STORAGE_ACCOUNT
# Required Argument $3 = STORAGE_KEY
if [ -z $1 ]; then
tput setaf 1; echo 'ERROR: Argument $1 (CONTAINER_NAME) not received' ; tput sgr0
exit 1;
fi
if [ -z $2 ]; then
tput setaf 1; echo 'ERROR: Argument $2 (STORAGE_ACCOUNT) not received' ; tput sgr0
exit 1;
fi
if [ -z $3 ]; then
tput setaf 1; echo 'ERROR: Argument $3 (STORAGE_KEY) not received' ; tput sgr0
exit 1;
fi
local _container=$(az storage container show --name $1 --account-name $2 --account-key $3 --query name -otsv)
if [ "$_container" == "" ]
then
OUTPUT=$(az storage container create \
--name $1 \
--account-name $2 \
--account-key $3 -otsv)
if [ $OUTPUT == true ]; then
tput setaf 3; echo "Storage Container $1 created."; tput sgr0
else
tput setaf 1; echo "Storage Container $1 not created."; tput sgr0
fi
else
tput setaf 3; echo "Storage Container $1 already exists."; tput sgr0
fi
}
function AddKeyToVault() {
# Required Argument $1 = KEY_VAULT
# Required Argument $2 = SECRET_NAME
# Required Argument $3 = SECRET_VALUE
if [ -z $1 ]; then
tput setaf 1; echo 'ERROR: Argument $1 (KEY_VAULT) not received' ; tput sgr0
exit 1;
fi
if [ -z $2 ]; then
tput setaf 1; echo 'ERROR: Argument $2 (SECRET_NAME) not received' ; tput sgr0
exit 1;
fi
if [ -z $3 ]; then
tput setaf 1; echo 'ERROR: Argument $3 (SECRET_VALUE) not received' ; tput sgr0
exit 1;
fi
local _secret=$(az keyvault secret set --vault-name $1 --name $2 --value $3)
echo ${_secret}
}
###############################
## Azure Intialize ##
###############################
printf "\n"
tput setaf 2; echo "Creating Terraform Backend Store" ; tput sgr0
tput setaf 3; echo "------------------------------------" ; tput sgr0
tput setaf 2; echo 'Logging in and setting subscription...' ; tput sgr0
az account set --subscription ${ARM_SUBSCRIPTION_ID}
tput setaf 2; echo 'Creating the Resource Group...' ; tput sgr0
CreateResourceGroup $AZURE_GROUP $AZURE_LOCATION
tput setaf 2; echo "Creating the Storage Account..." ; tput sgr0
CreateStorageAccount $AZURE_STORAGE $AZURE_GROUP $AZURE_LOCATION
tput setaf 2; echo "Retrieving the Storage Account Key..." ; tput sgr0
STORAGE_KEY=$(GetStorageAccountKey $AZURE_STORAGE $AZURE_GROUP)
tput setaf 2; echo "Creating the Storage Account Container..." ; tput sgr0
CreateBlobContainer $REMOTE_STATE_CONTAINER $AZURE_STORAGE $STORAGE_KEY
tput setaf 2; echo "Creating the Key Vault..." ; tput sgr0
CreateKeyVault $AZURE_VAULT $AZURE_GROUP $AZURE_LOCATION
tput setaf 2; echo "Adding Storage Key to Vault..." ; tput sgr0
SECRET=$(AddKeyToVault $AZURE_VAULT $AZURE_VAULT_SECRET $STORAGE_KEY)
tput setaf 3; echo "------------------------------------" ; tput sgr0
printf "\n"
# Display information
tput setaf 3; echo "Run the following command to initialize Terraform to store its state into Azure Storage:" ; tput sgr0
tput setaf 6; echo "TF_VAR_remote_state_account=$AZURE_STORAGE" ; tput sgr0
tput setaf 6; echo "TF_VAR_remote_state_container=$REMOTE_STATE_CONTAINER" ; tput sgr0
printf "\n"
tput setaf 6; echo "terraform init \\" ; tput sgr0
tput setaf 6; echo " -backend-config=\"storage_account_name=$AZURE_STORAGE\" \\"
tput setaf 6; echo " -backend-config=\"container_name=$REMOTE_STATE_CONTAINER\" \\"
tput setaf 6; echo " -backend-config=\"access_key=\$(az keyvault secret show --name $AZURE_VAULT_SECRET --vault-name $AZURE_VAULT --query value -o tsv)\" \\"
tput setaf 6; echo " -backend-config=\"key=terraform-ref-architecture-tfstate\"" ; tput sgr0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment