IaC Bazaar
Google CloudPlan-validated

Cloud KMS Keyring & Keys

Keyrings and rotation-enabled crypto keys with per-key IAM for CMEK across GCS, BigQuery, Cloud SQL and disks.

terraformGCP#gcp

Compare Secrets & Key Management across clouds →

gcp-kmsterraform v1.7

Verification

Plan-validated

Passed: module logic verified on a mocked plan — inputs, validation rules, conditional creation and outputs resolve (no real provider, no cloud).

Conformance

  • Static validation (fmt · validate · tflint)
  • Security scan: findings disclosed (Checkov)
  • Plan tests (mocked: validation rules · outputs)

Provenance

  • SHA-256 checksum
  • Signature (pending)

Functional

  • Live test pending (no cloud run yet)

Last verified 2026-06-28 · how we verify

Documentation

gcp-kms

A Cloud KMS key ring and its crypto keys, with automatic rotation on by default for symmetric keys and least-privilege per-key IAM for CMEK across GCS, BigQuery, Cloud SQL, Compute disks, and any other service that accepts a customer-managed encryption key. Works with Terraform and OpenTofu (>= 1.6), Google provider >= 7.0, < 8.0.

Status: static-validated, live-test pending. Ships under live-test quarantine — validated with tofu fmt, tofu validate, and tflint. Real apply → verify → destroy against a GCP project is pending a cloud sandbox. KMS live-testing is special: key rings and keys are not deletable, so a live lane must randomize names and treat "destroy" as versions scheduled for destruction — see the lifecycle note below.

Secure defaults

  • Rotation on by default — symmetric ENCRYPT_DECRYPT keys rotate every 90 days (7776000s) unless you override rotation_period. Rotation only applies to symmetric keys; the module auto-nulls rotation_period for asymmetric/MAC keys, so their minimal config applies without having to set rotation_period = null yourself.
  • Least-privilege per-key IAM — grants are additive google_kms_crypto_key_iam_member bindings scoped to a single key, so a CMEK consumer gets exactly cryptoKeyEncrypterDecrypter on the one key it needs, never broad ring-wide access.
  • prevent_destroy = true on every key — a code-review / plan guard so a key cannot be removed accidentally; operators must consciously lift it.
  • destroy_scheduled_duration (default 30 days) — destroyed key versions sit in a recoverable window before material is irreversibly gone.
  • Regional location encouraged — keep key material within a jurisdiction; HSM protection (protection_level = "HSM", FIPS 140-2 L3) available per key.

Lifecycle caveat (important)

Cloud KMS key rings and crypto keys cannot be deleted. terraform destroy removes them from state and schedules key versions for destruction; the ring/key resources persist in GCP permanently. Pick stable names, and in a live-test context randomize names per run since a name is never reclaimable.

Usage

module "kms" {
  source        = "./gcp-kms"
  project_id    = "my-project-123456"
  location      = "us-central1"
  key_ring_name = "app-keyring"

  keys = {
    "gcs-cmek" = {
      purpose         = "ENCRYPT_DECRYPT"
      rotation_period = "7776000s" # 90 days
      iam = {
        "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [
          "serviceAccount:[email protected]",
        ]
      }
    }
  }
}

# Use the key id as CMEK on another resource:
# kms_key_name = module.kms.crypto_key_ids["gcs-cmek"]

Inputs

NameTypeDefaultDescription
project_idstringHost project (required)
locationstringKMS location, e.g. us-central1, europe, global (required)
key_ring_namestringKey ring name — not reclaimable, pick a stable one (required)
keysmap(object)Keyed crypto keys: { purpose, rotation_period, algorithm, protection_level, destroy_scheduled_duration, labels, iam } (required)
labelsmap(string){}Default labels merged onto every key

Per-key fields: purpose (ENCRYPT_DECRYPT default), rotation_period (7776000s; set null for non-symmetric), algorithm (GOOGLE_SYMMETRIC_ENCRYPTION default), protection_level (SOFTWARE default, or HSM), destroy_scheduled_duration (2592000s), labels, and iam ({ role => [members] }).

Outputs

key_ring_id, key_ring_name, crypto_key_ids, crypto_key_names, crypto_keys.

Requirements

  • Terraform or OpenTofu >= 1.6
  • hashicorp/google >= 7.0, < 8.0

License

Commercial — LicenseRef-IaCBazaar-Commercial.