Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Setting up Terraform GCS remote backend
#!/usr/bin/env bash
set -u
set -e
set -o pipefail
GCP_PROJECT="$(gcloud config list --format 'value(core.project)')"
GCP_SERVICES=(
"storage-api.googleapis.com"
"storage-component.googleapis.com"
)
GCS_CLASS="multi_regional"
GCS_LOCATION="eu"
GCS_BUCKET_NAME="${GCP_PROJECT}-tf"
GCP_SERVICE_ACCOUNT_NAME="terraform"
GCP_SERVICE_ACCOUNT="$GCP_SERVICE_ACCOUNT_NAME@${GCP_PROJECT}.iam.gserviceaccount.com"
GCP_SERVICE_ACCOUNT_ROLES=(
"roles/editor"
"roles/owner"
)
GCP_SERVICE_ACCOUNT_KEY="$HOME/.config/gcloud/tf-${GCP_PROJECT}.key.json"
function service_enabled {
if [[ "${1}" == "$(gcloud services list --filter="serviceName=${1}" --format="csv[no-heading](serviceName)")" ]]; then
true
else
false
fi
}
function service:enable {
if ! service_enabled "${1}"; then
echo " > Enabling ${1} service ..."
(
set -x
gcloud services enable ${1}
)
else
echo " > Service ${1} already seems enabled"
fi
}
function services {
for service in "${GCP_SERVICES[@]}"; do
service:enable "${service}"
done
}
function bucket:exist() {
if gsutil ls gs://${1} &>/dev/null; then
true
else
false
fi
}
function bucket() {
if ! bucket:exist "${GCS_BUCKET_NAME}"; then
echo " > Creating Google Cloud Storage bucket $GCS_BUCKET_NAME ..."
(
set -x
gsutil mb -p ${GCP_PROJECT} -c ${GCS_CLASS} -l ${GCS_LOCATION} gs://${GCS_BUCKET_NAME}
gsutil versioning set on gs://${GCS_BUCKET_NAME}
)
else
echo " > GCS bucket $GCS_BUCKET_NAME already created"
fi
}
function service_account:exist() {
if gcloud iam service-accounts describe "${1}" &>/dev/null; then
true
else
false
fi
}
function service_account() {
if ! service_account:exist "${GCP_SERVICE_ACCOUNT}"; then
echo " > Creating service account ..."
(
set -x
gcloud iam service-accounts create "${GCP_SERVICE_ACCOUNT_NAME}" --display-name="Terraform Service Account"
)
else
echo " > Service account already created"
fi
}
function service_account:has_role() {
if [[ $(gcloud projects get-iam-policy ${GCP_PROJECT} --flatten=bindings --filter="bindings.members=serviceAccount:${1} AND bindings.role=$2" 2>/dev/null | wc -l) -ne 0 ]]; then
true
else
false
fi
}
function roles() {
for role in "${GCP_SERVICE_ACCOUNT_ROLES[@]}"; do
if ! service_account:has_role "${GCP_SERVICE_ACCOUNT}" "${role}" ; then
echo " > Granting ${role##*/} role to service account ..."
(
set -x
gcloud projects add-iam-policy-binding ${GCP_PROJECT} --member="serviceAccount:${GCP_SERVICE_ACCOUNT}" --role="${role}"
) 1>/dev/null
else
echo " > Service account already has ${role##*/} role"
fi
done
}
function credentials:exist() {
if [[ ! -f "${1}" ]]; then
true
else
false
fi
}
function credentials() {
if credentials:exist "${GCP_SERVICE_ACCOUNT_KEY}"; then
(
set -x
gcloud iam service-accounts keys create --iam-account="${GCP_SERVICE_ACCOUNT}" "${GCP_SERVICE_ACCOUNT_KEY}"
)
else
echo " > Private key for service account already exist"
fi
}
echo "--> Setting up Terraform GCS remote backend ..."
echo
services
bucket
service_account
roles
credentials
echo
echo "--> To setup remote state create backend.tf file in your project with following content"
echo "
terraform {
backend "gcs" {
bucket = "${GCS_BUCKET_NAME}"
}
}
"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.