How to Create a Service Account for Terraform in GCP

Service Account is a special kind of account used by an application (Terraform in this case) to make authorized API calls. It is identified by its email address, which is unique to the account.

In this guide we will learn how to create and manage service accounts using the Identity and Access Management (IAM) API, the Google Cloud console, and the gcloud command-line tool. By default, each project can have up to 100 service accounts that control access to your resources. You can request a quota increase if necessary.

These are the main differences between service accounts and normal user accounts:

  • Service Accounts don’t have passwords, and cannot log in via browsers.
  • Service Accounts are associated with **private/public RSA key-pairs **that are used for authentication to Google.

Before we start deploying our Terraform code for GCP (Google Cloud Platform), we will need to create and configure a Service Account in the Google Console and set up a terraform provider to use it.

In this example, we will create a master Service Account with permissions at Organization-level and Project-level.

For our example, we will grant a lot of permissions to the service account that you might not need in your case. Feel free to limit the permissions.

Related posts:

Prerequisites

To follow along, ensure that you have the following:

  • A Project to create the Service Account
  • If you are using a service account, Install or update to the latest version of the Google Cloud CLI.
  • The account you are using should also have enough role permissions to create the service account
Required roles

To get the permissions that you need to manage service accounts, ask your administrator to grant you the following IAM roles on the project:

  • To view service accounts and service account metadata: View Service Accounts (roles/iam.serviceAccountViewer)
  • To view and create service accounts: Create Service Accounts (roles/iam.serviceAccountCreator)
  • To view and delete service accounts: Delete Service Accounts (roles/iam.serviceAccountDeleter)
  • To fully manage (view, create, update, disable, enable, delete, undelete, and manage access to) service accounts: Service Account Admin (roles/iam.serviceAccountAdmin)

Creating a Service Account

When you create a service account, you must provide an alphanumeric ID (<var>SA_NAME</var> in the samples below), such as terraform-user. The ID must be between 6 and 30 characters, and can contain lowercase alphanumeric characters and dashes. After you create a service account, you cannot change its name.

The service account’s name appears in the email address that is provisioned during creation, in the format <var>SA_NAME</var>@<var>PROJECT_ID</var>.iam.gserviceaccount.com.

Each service account also has a permanent, unique numeric ID, which is generated automatically.

To create a service account in Console, click on the IAM & Admin menu, Service Accounts option, and finally, on the **+ Create Service Account **button.

Enter a name and description for the Service Account and click the CREATE button.

Citizix Create Service Account

Next, I will grant the Service Account access to the project. I will add the following Roles and click the CONTINUE button. Feel free to add more or remove more permissions in your case if you do not need them

  • Compute Storage Admin → Full access to Google Cloud Storage
  • Compute Admin → Full control of Compute Engine resources (Virtual Machines)
  • Kubernetes Engine Admin → Full management of Kubernetes Clusters

Citizix – GCP Service Account Permissions

Finally, grant users access to the service account. After you create a service account, you might need to wait for 60 seconds or more before you use the service account. 

Once the user is created, click on the + CREATE KEY button to generate our authentication key file. This key in JSON format will be used by Terraform to authenticate to GCP. Download the JSON file and store it in a secure folder or vault.

Creating a Service account using gcloud in terminal

For this step, you will need gcloud command installed and then log in to gcloud using these commands:

$ gcloud auth login
$ gcloud auth application-default login

To create the service account in terminal, run the gcloud iam service-accounts create command:

gcloud iam --project PROJECT_ID service-accounts create SERVICE_ACCOUNT_ID \
    --description="DESCRIPTION" \
    --display-name="DISPLAY_NAME"

Replace the following values:

  • PROJECT_ID: the project ID
  • SERVICE_ACCOUNT_ID: the ID for the service account
  • DESCRIPTION: an optional description of the service account
  • DISPLAY_NAME: a service account name to display in the Google Cloud console

This is the output on my system

➜ gcloud iam --project citizix-one service-accounts create terraform-user0 \
    --description="Citizix Terraform User" \
    --display-name="Terraform User0"
Created service account [terraform-user0].

To grant your service account an IAM role on your project, run the gcloud projects add-iam-policy-binding command:

gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com" \
    --role="ROLE_NAME"

Replace the following values:

  • PROJECT_ID: the project ID
  • SERVICE_ACCOUNT_ID: the service account ID
  • ROLE_NAME: a role name, such as roles/compute.osLogin

This is the output on my machine

➜ gcloud projects add-iam-policy-binding citizix-one \
    --member="serviceAccount:terraform-user0@citizix-one.iam.gserviceaccount.com" \
    --role="roles/compute.admin" \
    --role="roles/compute.storageAdmin" \
    --role="roles/container.admin"
Updated IAM policy for project [citizix-one].
...

To allow users to impersonate the service account, run the gcloud iam service-accounts add-iam-policy-binding command to grant a user the Service Account User role (roles/iam.serviceAccountUser) on the service account:

gcloud iam service-accounts add-iam-policy-binding \
    SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com \
    --member="user:USER_EMAIL" \
    --role="roles/iam.serviceAccountUser"
# Generate a key for your new service account
gcloud iam service-accounts keys create iam-key.json \
  --iam-account="terraform-user@$citizix-one.iam.gserviceaccount.com";

# Print (and then remove) the JSON credentials
cat iam-key.json && rm iam-key.json;

You can list your service accounts to help you audit service accounts and keys, or as part of a custom tool for managing service accounts.

gcloud iam service-accounts list

To update a service account:

gcloud iam service-accounts update \
    SA_NAME@PROJECT_ID.iam.gserviceaccount.com \
    --description="UPDATED_SA_DESCRIPTION" \
    --display-name="UPDATED_DISPLAY_NAME"

To disable and enable a service account:

# Disable
gcloud iam service-accounts disable SA_NAME@PROJECT_ID.iam.gserviceaccount.com

# Enable
gcloud iam service-accounts enable SA_NAME@PROJECT_ID.iam.gserviceaccount.com

To Delete a service account:

gcloud iam service-accounts delete \
    SA_NAME@PROJECT_ID.iam.gserviceaccount.com

Configuring the Terraform Provider

Terraform providers create, manage, and update infrastructure resources, through API calls. They need to authenticate with the api thus we need to configure with the credentials we just created.

In your terraform directory, in the providers.tf, add the following content:

locals {
  gcp_project      = "citizix"
  credentials_path = "../terraform-user-xxxx.json"
  region           = "europe-west1"
}

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 4.20"
    }
  }
}

provider "google" {
  credentials = file(local.credentials_path)

  project = local.gcp_project
  region  = local.region
}

provider "google-beta" {
  credentials = file(local.credentials_path)

  project = local.gcp_project
  region  = local.region
}

In the above code, we are defining locals for the provider variables then passing them when creating the provider.

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy