Skip to content

Instantly share code, notes, and snippets.

@tomasbasham
Created May 22, 2023 23:07
Show Gist options
  • Save tomasbasham/81fb328f0797a98d864da75f4246827d to your computer and use it in GitHub Desktop.
Save tomasbasham/81fb328f0797a98d864da75f4246827d to your computer and use it in GitHub Desktop.
Bootstrap Google Cloud Platform for Terraform
#!/usr/bin/env bash
set -eou pipefail
if [[ "${TRACE-0}" == "1" ]]; then
set -o xtrace
fi
COMMAND=${0##*/}
DIRNAME=$(dirname "$0")
usage() {
echo "
$COMMAND --organisation=ORGANISATION
--organisation-id=ORGANISATION_ID
--billing-account-id=BILLING_ACCOUNT_ID
Setup a terraform Admin project on Google Cloud Platform
--organisation
Organisation name to associate with Google Cloud Resources.
--organisation-id
Organisation ID to associate with Google Cloud Resources.
--billing-account-id
Billing account ID to associate with Google Cloud Resources.
" >&2
exit 2
}
if [[ "$#" -eq 0 ]]; then
usage
fi
organisation=""
organisation_id=""
billing_account_id=""
while true; do
case $# in
0) break;;
esac
case $1 in
--organisation)
shift
case $# in
0)
echo "$COMMAND: --organisation: ORGANISATION argument expected." >&2
exit 1
;;
esac
organisation=$1
;;
--organisation=*)
organisation=${1#*=}
;;
--organisation-id)
shift
case $# in
0)
echo "$COMMAND: --organisation-id: ORGANISATION_ID argument expected." >&2
exit 1
;;
esac
organisation_id=$1
;;
--organisation-id=*)
organisation_id=${1#*=}
;;
--billing-account-id)
shift
case $# in
0)
echo "$COMMAND: --billing-account-id: BILLING_ACCOUNT_ID argument expected." >&2
exit 1
;;
esac
billing_account_id=$1
;;
--billing-account-id=*)
billing_account_id=${1#*=}
;;
*)
usage
;;
esac
shift
done
# Validate required variables.
[[ -z $organisation ]] && echo "$COMMAND --organisation is required" && exit 1
[[ -z $organisation_id ]] && echo "$COMMAND --organisation-id is required" && exit 1
[[ -z $billing_account_id ]] && echo "$COMMAND --billing-account-id is required" && exit 1
tf_admin=${organisation}-terraform-admin
tf_creds=${HOME}/.config/gcloud/${tf_admin}.json
tf_service_account=terraform@${tf_admin}.iam.gserviceaccount.com
echo "An administrative project will be created with the following details:
Organisation: ${organisation}
Organisation ID: ${organisation_id}
Billing Account: ${billing_account_id}
Terraform Admin Project: ${tf_admin}
Terraform Admin Service Account: ${tf_service_account}
"
read -p "Continue? [N/y]: " -n 1 -r
echo
echo
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
exit 0
fi
# Create a Terraform admin project and link it to a billing account.
gcloud projects create ${tf_admin} \
--organization ${organisation_id} \
--set-as-default
gcloud beta billing projects link ${tf_admin} \
--billing-account ${billing_account_id}
# Create a Terraform service account in the Terraform admin project and
# download the JSON credentials.
gcloud iam service-accounts create terraform \
--display-name "Terraform admin account"
gcloud iam service-accounts keys create ${tf_creds} \
--iam-account ${tf_service_account}
# Grant the service account permission to create service accounts for the admin
# project.
gcloud projects add-iam-policy-binding ${tf_admin} \
--member serviceAccount:${tf_service_account} \
--role roles/iam.serviceAccountCreator
# Grant the service account permission to manage workload identity pools.
gcloud projects add-iam-policy-binding ${tf_admin} \
--member serviceAccount:${tf_service_account} \
--role roles/iam.workloadIdentityPoolAdmin
# Grant the service account permission to create projects and assign billing
# accounts.
gcloud organizations add-iam-policy-binding ${organisations_id} \
--member serviceAccount:${tf_service_account} \
--role roles/resourcemanager.projectCreator
gcloud organizations add-iam-policy-binding ${organisation_id} \
--member serviceAccount:${tf_service_account} \
--role roles/billing.user
echo "An administrative project was successfully created. You have been set as
the project owner but are likely to want to remove this in future. You can
access the project here:
https://console.cloud.google.com/home/dashboard?project=${tf_admin}
The service account credentials have been downloaded to:
${tf_creds}
"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment