A 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 do not 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 reading
- How to create and manage Secrets in GCP Secret Manager using Terraform
- How to use Terraform to create a VPC network and a Cloud SQL in GCP
- How to use Terraform to create a VPC network and a GKE in GCP
- How to use Terraform to create a VPC network and a Compute instance in GCP
- How to use Terraform to create a Redis instance in GCP
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 (SA_NAME 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 SA_NAME@PROJECT_ID.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 Accountbutton.
Enter a name and description for the Service Account and click the CREATE button.
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
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:
| |
To create the service account in terminal, run the gcloud iam service-accounts create command:
| |
Replace the following values:
PROJECT_ID: the project IDSERVICE_ACCOUNT_ID: the ID for the service accountDESCRIPTION: an optional description of the service accountDISPLAY_NAME: a service account name to display in the Google Cloud console
This is the output on my system
| |
To grant your service account an IAM role on your project, run the gcloud projects add-iam-policy-binding command:
| |
Replace the following values:
PROJECT_ID: the project IDSERVICE_ACCOUNT_ID: the service account IDROLE_NAME: a role name, such asroles/compute.osLogin
This is the output on my machine
| |
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:
| |
| |
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.
| |
To update a service account:
| |
To disable and enable a service account:
| |
To Delete a service account:
| |
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 providers.tf, add the following content:
| |
In the above code, we are defining locals for the provider variables and then passing them when creating the providers.
Security notes for JSON keys
If you generate a JSON key for Terraform, treat it like a secret:
- Do not commit
iam-key.jsonto git. - Store it outside your repo (or in an encrypted secret store).
- Restrict permissions (for example
chmod 600 iam-key.json). - Rotate/delete the key if you suspect it was exposed.
Recommended: avoid long-lived JSON keys in CI/CD
Long-lived keys are convenient but increase blast radius. Prefer short-lived credentials by using one of these approaches:
- Workload Identity Federation (OIDC) for CI/CD workloads
- Service account impersonation so Terraform receives tokens at runtime
In both cases, your Terraform runs still authenticate, but you do not need to store a long-lived JSON key file.
Verification checklist
After configuring the Terraform provider, verify access with:
| |
If you still get authorization errors, confirm:
- The service account email matches what you created/granted IAM roles to
- The target resources (projects/buckets/etc.) grant the right IAM roles
- The required APIs are enabled in the GCP project
Troubleshooting common errors
403 / permissionDenied
You are missing one or more IAM roles on the target resources. Review:
gcloud projects get-iam-policy PROJECT_ID- IAM bindings on the specific resources Terraform manages
service account not found
Double-check SERVICE_ACCOUNT_ID and PROJECT_ID and confirm the service account exists:
| |
Terraform still uses the wrong credentials
Check whether Terraform is picking up a different auth method from your environment (for example ADC):
- If using
GOOGLE_APPLICATION_CREDENTIALS, ensure it points to the correct JSON key file. - If using
credentials = file(local.credentials_path), ensure the path is correct and readable.
Summary
You now have everything needed for Terraform on GCP: a service account, the IAM roles it needs, optional impersonation for short-lived access, a safe JSON key option for local runs, and working provider "google" / provider "google-beta" configuration.