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
-
Key Management:
- Regular rotation
- Proper permissions
- Monitor usage
- Backup strategy
-
Security:
- Use HSM when needed
- Implement IAM
- Regular audits
- Monitor access
-
Performance:
- Monitor usage
- Track metrics
- Regular review
- Optimize access
-
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
-
Key Organization:
- Proper naming
- Document usage
- Regular review
- Track versions
-
Security:
- Regular rotation
- Monitor access
- Audit logs
- Backup keys
-
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