Managing Cloud KMS with Terraform

Learn how to set up and manage Google Cloud Key Management Service using Terraform

In this guide, we’ll explore how to manage Google Cloud KMS using Terraform.

Video Tutorial

Learn more about managing Google Cloud KMS with Terraform in this comprehensive video tutorial:

Prerequisites

  • Google Cloud SDK installed and configured
  • Terraform installed (version 1.0.0 or later)
  • A GCP project with billing enabled

Project Structure

.
├── main.tf                   # Main Terraform configuration file
├── variables.tf              # Variable definitions
├── outputs.tf               # Output definitions
├── terraform.tfvars         # Variable values
└── modules/
    └── kms/
        ├── main.tf          # Cloud KMS specific configurations
        ├── variables.tf      # Module variables
        ├── keys.tf          # Key configurations
        └── outputs.tf       # Module outputs

Provider Configuration

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

provider "google" {
  project = var.project_id
  region  = var.region
}

Variables

variable "project_id" {
  description = "The ID of the GCP project"
  type        = string
}

variable "region" {
  description = "The region to deploy resources to"
  type        = string
  default     = "us-central1"
}

variable "keyring_name" {
  description = "Name of the KMS keyring"
  type        = string
}

Key Ring Configuration

resource "google_kms_key_ring" "keyring" {
  name     = var.keyring_name
  location = var.region
}

Encryption Key Configuration

resource "google_kms_crypto_key" "key" {
  name            = "encryption-key"
  key_ring        = google_kms_key_ring.keyring.id
  rotation_period = "7776000s"  # 90 days

  version_template {
    algorithm        = "GOOGLE_SYMMETRIC_ENCRYPTION"
    protection_level = "HSM"
  }

  lifecycle {
    prevent_destroy = true
  }
}

# Key for automatic rotation
resource "google_kms_crypto_key" "rotating_key" {
  name            = "rotating-key"
  key_ring        = google_kms_key_ring.keyring.id
  rotation_period = "2592000s"  # 30 days

  version_template {
    algorithm        = "GOOGLE_SYMMETRIC_ENCRYPTION"
    protection_level = "SOFTWARE"
  }
}

# Key for asymmetric signing
resource "google_kms_crypto_key" "signing_key" {
  name     = "signing-key"
  key_ring = google_kms_key_ring.keyring.id

  version_template {
    algorithm        = "EC_SIGN_P256_SHA256"
    protection_level = "HSM"
  }

  purpose = "ASYMMETRIC_SIGN"
}

IAM Configuration

resource "google_kms_key_ring_iam_binding" "key_ring_binding" {
  key_ring_id = google_kms_key_ring.keyring.id
  role        = "roles/cloudkms.admin"

  members = [
    "serviceAccount:${google_service_account.kms_admin.email}",
  ]
}

resource "google_kms_crypto_key_iam_binding" "crypto_key_binding" {
  crypto_key_id = google_kms_crypto_key.key.id
  role          = "roles/cloudkms.cryptoKeyEncrypterDecrypter"

  members = [
    "serviceAccount:${google_service_account.kms_user.email}",
  ]
}

resource "google_service_account" "kms_admin" {
  account_id   = "kms-admin"
  display_name = "KMS Admin Service Account"
}

resource "google_service_account" "kms_user" {
  account_id   = "kms-user"
  display_name = "KMS User Service Account"
}

Key Import Configuration

resource "google_kms_crypto_key" "imported_key" {
  name     = "imported-key"
  key_ring = google_kms_key_ring.keyring.id

  import_only = true

  version_template {
    algorithm        = "GOOGLE_SYMMETRIC_ENCRYPTION"
    protection_level = "SOFTWARE"
  }
}

Key Rotation Configuration

resource "google_kms_crypto_key" "scheduled_key" {
  name            = "scheduled-key"
  key_ring        = google_kms_key_ring.keyring.id
  rotation_period = "604800s"  # 7 days

  version_template {
    algorithm        = "GOOGLE_SYMMETRIC_ENCRYPTION"
    protection_level = "SOFTWARE"
  }

  lifecycle {
    prevent_destroy = true
  }
}

Monitoring Configuration

resource "google_monitoring_alert_policy" "kms_alert" {
  display_name = "KMS Key Usage Alert"
  combiner     = "OR"

  conditions {
    display_name = "High Key Usage"
    condition_threshold {
      filter          = "metric.type=\"cloudkms.googleapis.com/crypto/crypto_key_versions\" AND resource.type=\"cloudkms.googleapis.com/CryptoKey\""
      duration        = "300s"
      comparison     = "COMPARISON_GT"
      threshold_value = 1000

      trigger {
        count = 1
      }

      aggregations {
        alignment_period   = "60s"
        per_series_aligner = "ALIGN_RATE"
      }
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.name]
}

Outputs

output "keyring_id" {
  value       = google_kms_key_ring.keyring.id
  description = "The ID of the KMS keyring"
}

output "encryption_key_id" {
  value       = google_kms_crypto_key.key.id
  description = "The ID of the encryption key"
}

output "signing_key_id" {
  value       = google_kms_crypto_key.signing_key.id
  description = "The ID of the signing key"
}

Best Practices

  1. Key Management:

    • Regular rotation
    • Proper permissions
    • Monitor usage
    • Backup strategy
  2. Security:

    • Use HSM when needed
    • Implement IAM
    • Regular audits
    • Monitor access
  3. Performance:

    • Monitor usage
    • Track metrics
    • Regular review
    • Optimize access
  4. Cost Optimization:

    • Monitor operations
    • Clean up unused
    • Right-size HSM
    • Regular review

Common Operations

Creating Resources

terraform init
terraform plan
terraform apply

Key Operations

# Encrypt data
gcloud kms encrypt \
  --location=us-central1 \
  --keyring=my-keyring \
  --key=my-key \
  --plaintext-file=input.txt \
  --ciphertext-file=encrypted.txt

# Decrypt data
gcloud kms decrypt \
  --location=us-central1 \
  --keyring=my-keyring \
  --key=my-key \
  --ciphertext-file=encrypted.txt \
  --plaintext-file=decrypted.txt

Best Practices and Tips

  1. Key Organization:

    • Proper naming
    • Document usage
    • Regular review
    • Track versions
  2. Security:

    • Regular rotation
    • Monitor access
    • Audit logs
    • Backup keys
  3. Operations:

    • Monitor usage
    • Track metrics
    • Set up alerts
    • Regular maintenance

Conclusion

You’ve learned how to set up and manage Google Cloud KMS using Terraform. This setup provides:

  • Secure key management
  • Automated rotation
  • Access control
  • Best practices implementation