This week I started on a new project that needs a Kubernetes cluster and figured it would be a good time to figure out how to spin it up infrastructure in GCP with Terraform.  As with Azure a few months ago, this is not something that I have had a chance to do yet.  I decided to stick with using the storage service of the cloud provider for storing my state files.  As with other cloud providers, there is a little bit of a chicken and egg problem, where a few things need to be in place prior to running terraform.  As usual, I used the CLI to initialize the GCP environment.

Preparing the Environment

The first thing that you need to do is install Google’s Cloud SDK.  Normally I would set up a virtualenv prior to installing the command line tools of a cloud vender.  Unfortunately, there does not seem to be a way to do this with GCP.  Azure and AWS have pip packages, Google does not.  Instead, they have a script to download and run to install the Cloud SDK.

curl https://sdk.cloud.google.com | bash

Once the Cloud SDK is installed you need to initialize the gcloud environment.

gcloud init

Create a Project for Terraform

I decided to created a separate project just for my Terraform state files. This way I can be more restrictive with access and prevent accidental deletion. You can create a new project via the CLI:

# Get the Organization ID (if you are using an organization account)
gcloud organizations list
DISPLAY_NAME            ID  DIRECTORY_CUSTOMER_ID
austincloud.guru  123456789012              X4RfngR5r

# Create the project
gcloud projects create terraform-232323 --name terraform --organization 123456789012

# Select the project
gcloud config set project terraform

Once the project is created you will need to add it to the master billing account.  You can do this either through the web console or via the CLI by installing the beta command set and running the following commands:

# Get the billing account number
gcloud beta billing accounts list --filter open=true

# Attach the project to the billing account
gcloud beta billing projects link $PROJECT_ID --billing-account=$ACCOUNT_ID

Create the Storage Bucket to Use with Terraform

To create the storage bucket you can use the gsutil command. Since it has to be globally unique string between 3 and 63 characters, I generated something unique rather than mess around with trying to figure out a name that works.

cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-z0-9' | head -c 30
4omlc8iehkfl1uo0k8h4p38bh82jkt

gsutil mb gs://4omlc8iehkfl1uo0k8h4p38bh82jkt

Create the Service Account

In order to use Terraform in GCP, you will need to create a service account that has the permissions to create the resources you will be using.  I usually create the user terraform-temp so that my long-term terraform user can be managed via Terraform later.

# Create the Service Account
gcloud iam service-accounts create terraform-temp --display-name terraform-temp

# Add the Policy Binding for storage admin to the user
gcloud projects add-iam-policy-binding terraform --member "serviceAccount:terraform-temp@terraform-232323.iam.gserviceaccount.com" --role "roles/storage.admin"

# Create the JSON keys file
gcloud iam service-accounts keys create ~/.config/gcloud/terraform-temp.json \\
  --iam-account terraform-temp@terraform-232323.iam.gserviceaccount.com

Configure Terraform to use GCP Storage

With the storage for the tfstate files set up, we can now configure Terraform to use it. Start by creating a file called backend.tf and adding the following to it:

terraform {
  backend "gcs" {
    bucket = "4omlc8iehkfl1uo0k8h4p38bh82jkt"
    prefix = "terraform/base"
    project = "terraform-232323"
    region = "us-central1"
  }
}

Next, create a file called provider.tf and add the following:

provider "google" {
  project = "terraform-232323"
  region = "us-central1"
}

Once the files are created, you will need to get the storage access key and then initialize the backend.

export GOOGLE_CREDENTIALS=$(cat ~/.config/gcloud/$FILE.json)

terraform init

That’s it. Now you can start creating resources in your main.tf file and building out your GCP infrastructure.