How to Create and Manage Secrets in GCP Secret Manager Using Terraform

Create and manage secrets in Google Cloud Secret Manager with Terraform. Enable the API, IAM, automatic and user-managed replication, secret versions, and read secret data in Terraform.

Use Terraform to create and manage secrets in Google Cloud Secret Manager—so API keys, passwords, and certificates live in a central, auditable store instead of config files or code.

GCP Secret Manager is a secure storage service for sensitive data. It gives you a single place to manage, access, and audit secrets across Google Cloud. Terraform lets you define that setup as code (HCL or JSON) and apply it consistently across projects and environments.

Important: Terraform stores secret values in the state file in plain text. Use remote state with encryption, restrict access to state, and consider external secret injection for production.

Related reading:

Prerequisites

You need:

Log in to Google Cloud with the Cloud SDK:

1
2
gcloud auth login
gcloud auth application-default login

1. Enable the Secret Manager API

Enable the Secret Manager API for your project (required). In the GCP Console, search for Secret Manager and click Enable if it isn’t already. You only need to do this once per project.

With the gcloud CLI:

1
gcloud services enable secretmanager.googleapis.com

Or with Terraform:

1
2
3
resource "google_project_service" "secretmanager" {
  service = "secretmanager.googleapis.com"
}

2. Grant the Service Account Secret Manager Permissions

Your Terraform service account needs permission to manage secrets. In the GCP Console: IAM & AdminIAM, find the service account, click the pencil icon (Edit), and add the Secret Manager Admin role.

With gcloud:

1
2
3
4
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/secretmanager.admin" \
  --condition="None"

3. Add Terraform Provider and Create a Secret

Configure the Google provider and a Secret Manager secret with automatic replication and a first version.

Provider and locals:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
locals {
  gcp_project      = "citizix-one"
  credentials_path = "../terraform-user-xxxx.json"
  region           = "europe-west6"
}

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

provider "google" {
  credentials = file(local.credentials_path)
  project     = local.gcp_project
  region      = local.region
}

Create a secret named live-app-password with automatic replication and a secret version:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
resource "google_secret_manager_secret" "secret" {
  secret_id = "live-app-password"

  replication {
    automatic = true
  }

  depends_on = [google_project_service.secretmanager]
}

resource "google_secret_manager_secret_version" "secret-version-basic" {
  secret      = google_secret_manager_secret.secret.id
  secret_data = "Secr37P4s5word"
}

Grant access to a user or service account:

1
2
3
4
5
resource "google_secret_manager_secret_iam_member" "live-app" {
  secret_id = google_secret_manager_secret.secret.id
  role      = "roles/secretmanager.secretAccessor"
  member    = "user:[email protected]" # or serviceAccount:my-app@...
}

Optional: Secret with User-Managed Replication

To control exactly where secrets are replicated, use user-managed replication and list the locations. Example: replicate only in europe-west1 and europe-west2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
resource "google_secret_manager_secret" "secret_regional" {
  secret_id = "live-app-password-regional"

  labels = {
    label = "citizix"
  }

  replication {
    user_managed {
      replicas {
        location = "europe-west1"
      }
      replicas {
        location = "europe-west2"
      }
    }
  }
}

resource "google_secret_manager_secret_version" "secret-version-regional" {
  secret      = google_secret_manager_secret.secret_regional.id
  secret_data = "Secr37P4s5word"
}

4. Read Secret Data in Terraform

Use a data source to read a secret version. Specify a version to get that version; omit it to use the latest.

Specific version (e.g. version 1):

1
2
3
4
data "google_secret_manager_secret_version" "secret" {
  secret  = "live-app-password"
  version = "1"
}

Latest version:

1
2
3
data "google_secret_manager_secret_version" "secret" {
  secret = "live-app-password"
}

5. Use the Secret in Outputs (or Other Resources)

Reference the data source to expose the secret value (e.g. in an output). Avoid outputting secrets in production; use them only in resources that need them.

1
2
3
4
output "live-app-password" {
  value     = data.google_secret_manager_secret_version.secret.secret_data
  sensitive = true
}

Setting sensitive = true prevents the value from appearing in plan/apply logs.

Summary and Next Steps

You now use Terraform to create GCP Secret Manager secrets, set replication (automatic or user-managed), create versions, grant IAM access, and read secret data via data sources.

Next steps:

  • Use remote state (e.g. GCS backend) with encryption and access controls so the state file isn’t stored locally.
  • Prefer least-privilege roles (e.g. roles/secretmanager.secretAccessor for apps) instead of Secret Manager Admin where possible.
  • To sync Secret Manager into Kubernetes, use External Secrets with GCP Secret Manager.
comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy