Sitelet https://github.com/microsoftexpert/terraform-google-discovery-engine-cmek-config
Skip to content

Latest commit

Β 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

☁️ Google Cloud Discovery Engine CMEK Config Terraform Module

Provisions a customer-managed encryption key configuration for Discovery Engine (google_discovery_engine_cmek_config) β€” targeting hashicorp/google ~> 7.0 on Terraform >= 1.12.0.

Terraform Provider Module Version Module Type Resource Count Posture


🧩 Overview

  • πŸ” Manages one Discovery Engine CMEK config β€” the customer-managed encryption key applied to Discovery Engine resources in a project/location.
  • 🌍 location here accepts ONLY "us"/"eu" β€” no "global", a different enum from every other Discovery Engine resource in this batch.
  • 🧯 deletion_policy defaults to "PREVENT" β€” a house extension.

πŸ’‘ Why it matters: CMEK is often a hard compliance requirement for a financial institution's search/AI corpora. Getting set_default right determines whether new Discovery Engine resources in this project/location are automatically encrypted with the intended key.


❀️ Support this project

If these Terraform modules have been helpful to you or your organization, I'd appreciate your support in any of the following ways:

Whether it's a star, a professional connection, or a coffee, every gesture helps keep these modules actively maintained and continually improving. Thank you for being part of the community!


πŸ—ΊοΈ Where this fits

flowchart LR
 KMS["terraform-google-kms-keyring\n(google_kms_crypto_key)"]:::neutral
 CMEK["terraform-google-discovery-engine-cmek-config\n(google_discovery_engine_cmek_config)"]:::this

 KMS -.->|"key name to kms_key (inferred, required)"| CMEK

 classDef this fill:#4285F4,color:#ffffff,stroke:#333333
 classDef neutral fill:#E8EAED,color:#202124,stroke:#999999
Loading

Validated via the Mermaid Chart MCP before embedding.


🧬 What this builds

flowchart LR
 subgraph Inputs["Inputs"]
 I1["cmek_config_id, location,\nkms_key"]
 I2["set_default, single_region_keys,\ndeletion_policy, timeouts"]
 end

 THIS["google_discovery_engine_cmek_config.this"]:::this

 O1["id, name, is_default,\nkms_key_version, state"]

 I1 --> THIS
 I2 --> THIS
 THIS --> O1

 classDef this fill:#4285F4,color:#ffffff,stroke:#333333
Loading

Resource inventory: one keystone resource, google_discovery_engine_cmek_config.this. No for_each-managed children β€” this is a standalone module (see SCOPE.md).


βœ… Provider / Versions

Terraform >= 1.12.0
hashicorp/google ~> 7.0
Provider block None β€” the caller configures google (ADC, WIF, or a service account key per our authentication model)

Schema notes that bite:

  • location accepts ONLY "us"/"eu" β€” no "global".
  • kms_key/single_region_keys[].kms_key are INFERRED, not confirmed by a live example.
  • No labels, no self_link.
  • deletion_policy defaults to "PREVENT" β€” a house extension.

πŸ”‘ Required IAM Roles

  • roles/discoveryengine.admin (or a narrower CMEK-administration role) on the target project.

☁️ GCP Prerequisites

  • discoveryengine.googleapis.com enabled.
  • The KMS key ring/key must already exist, and the Discovery Engine service agent needs roles/cloudkms.cryptoKeyEncrypterDecrypter on it.

πŸ“ Module Structure

terraform-google-discovery-engine-cmek-config/
β”œβ”€β”€ providers.tf # required_providers + required_version β€” no provider {} block
β”œβ”€β”€ variables.tf # google_discovery_engine_cmek_config.this schema
β”œβ”€β”€ main.tf # google_discovery_engine_cmek_config.this β€” the sole keystone resource
β”œβ”€β”€ outputs.tf # id, name, is_default β€” no self_link (none exists)
β”œβ”€β”€ README.md # this file
β”œβ”€β”€ SCOPE.md # lightweight standalone scope
└── examples/
 └── basic/ # smallest real call

βš™οΈ Quick Start

module "cmek_config" {
  source = "git::https://github.com/microsoftexpert/terraform-google-discovery-engine-cmek-config.git?ref=v1.0.0"

  cmek_config_id = "member-data-cmek"
  location       = "us"
  kms_key        = module.kms.crypto_key_ids["discovery-engine-key"]
}

πŸ”Œ Cross-Module Contract

Consumes

Input Type Source module
kms_key string terraform-google-kms-keyring (required, INFERRED)
single_region_keys[].kms_key string, optional terraform-google-kms-keyring (INFERRED)

Emits

Output Description
id Terraform-internal id
name Computed full resource name
is_default Whether this is the default CmekConfig for the customer
kms_key_version KMS key version currently in use
state The state of the CmekConfig
notebooklm_state Whether the NotebookLM Corpus is ready

πŸ“š Example Library

1 Β· Minimal default CMEK config
module "cmek_config" {
  source = "git::https://github.com/microsoftexpert/terraform-google-discovery-engine-cmek-config.git?ref=v1.0.0"

  cmek_config_id = "member-data-cmek"
  location       = "us"
  kms_key        = module.kms.crypto_key_ids["discovery-engine-key"]
}
2 Β· Non-default CMEK config
module "secondary_cmek_config" {
  source = "git::https://github.com/microsoftexpert/terraform-google-discovery-engine-cmek-config.git?ref=v1.0.0"

  cmek_config_id = "secondary-cmek"
  location       = "us"
  kms_key        = module.kms.crypto_key_ids["secondary-key"]
  set_default    = false
}
3 Β· With single-region keys
module "multi_key_cmek_config" {
  source = "git::https://github.com/microsoftexpert/terraform-google-discovery-engine-cmek-config.git?ref=v1.0.0"

  cmek_config_id = "multi-region-cmek"
  location       = "us"
  kms_key        = module.kms.crypto_key_ids["discovery-engine-key"]

  single_region_keys = [
    { kms_key = module.kms.crypto_key_ids["us-east1-key"] },
  ]
}
4 Β· EU location
module "eu_cmek_config" {
  source = "git::https://github.com/microsoftexpert/terraform-google-discovery-engine-cmek-config.git?ref=v1.0.0"

  cmek_config_id = "eu-member-cmek"
  location       = "eu"
  kms_key        = module.kms_eu.crypto_key_ids["discovery-engine-key"]
}
5 Β· Custom timeouts
module "cmek_config_custom_timeouts" {
  source = "git::https://github.com/microsoftexpert/terraform-google-discovery-engine-cmek-config.git?ref=v1.0.0"

  cmek_config_id = "slow-provision-cmek"
  location       = "us"
  kms_key        = module.kms.crypto_key_ids["discovery-engine-key"]

  timeouts = {
    create = "10m"
  }
}
6 Β· Relaxed deletion_policy for a scratch/dev CMEK config
module "dev_cmek_config" {
  source = "git::https://github.com/microsoftexpert/terraform-google-discovery-engine-cmek-config.git?ref=v1.0.0"

  cmek_config_id  = "dev-cmek"
  location        = "us"
  kms_key         = module.kms.crypto_key_ids["dev-key"]
  deletion_policy = "DELETE"
}
7 Β· πŸ—οΈ End-to-end composition
module "kms" {
  source = "git::https://github.com/microsoftexpert/terraform-google-kms-keyring.git?ref=v1.0.0"

  key_ring_name = "discovery-engine-keyring"
  location      = "us"

  crypto_keys = {
    "discovery-engine-key" = {}
  }
}

module "cmek_config" {
  source = "git::https://github.com/microsoftexpert/terraform-google-discovery-engine-cmek-config.git?ref=v1.0.0"

  cmek_config_id = "member-data-cmek"
  location       = "us"
  kms_key        = module.kms.crypto_key_ids["discovery-engine-key"]
}

output "cmek_config_is_default" {
  value = module.cmek_config.is_default
}

πŸ“₯ Inputs

Required: cmek_config_id, location, kms_key.

Grouped summary: identity (cmek_config_id, location), encryption (kms_key, set_default, single_region_keys), operations (deletion_policy, timeouts β€” no labels).

Full object schemas
variable "cmek_config_id" {
  type = string
}

variable "location" {
  type = string # "us" | "eu" ONLY
}

variable "kms_key" {
  type = string
}

variable "set_default" {
  type    = bool
  default = true
}

variable "single_region_keys" {
  type = list(object({
    kms_key = string
  }))
  default = []
}

variable "deletion_policy" {
  type    = string
  default = "PREVENT" # "DELETE" | "ABANDON" | "PREVENT"
}

variable "timeouts" {
  type = object({
    create = optional(string)
    update = optional(string)
    delete = optional(string)
  })
  default = null
}

🧾 Outputs

Output Description Notes
id Terraform-internal id No self_link exists
name Computed full resource name Always populated
is_default Whether this is the default CmekConfig Always populated
kms_key_version KMS key version currently in use Always populated
state The state of the CmekConfig Always populated
notebooklm_state Whether the NotebookLM Corpus is ready Always populated

🧠 Architecture Notes

  • cmek_config_id/location/kms_key are force-new.
  • location accepts only "us"/"eu" β€” no "global", unlike every other Discovery Engine resource in this batch.

🧱 Design Principles

Concern Secure default Opt-out (explicit)
Deletion guard deletion_policy = "PREVENT" (house extension) Caller sets "DELETE" or "ABANDON" explicitly
CMEK kms_key required, never defaulted to a specific key N/A β€” caller always supplies a real key

πŸš€ Runbook

cd terraform-google-discovery-engine-cmek-config
terraform init -backend=false
terraform validate
terraform fmt -check

Pin ?ref=v1.0.0 β€” never a branch. This library is plan-only; a human applies from CI with valid ADC/WIF credentials.


πŸ§ͺ Testing

terraform validate/fmt -check confirm internal type/reference consistency and formatting only β€” they cannot catch GCP API-level rejections (an invalid KMS key reference). A real terraform plan/apply against a live project is the only way to confirm this module's behavior end-to-end.


πŸ’¬ Example Output

$ terraform output

id = "projects/casey-prod/locations/us/cmekConfigs/member-data-cmek"
name = "projects/casey-prod/locations/us/cmekConfigs/member-data-cmek"
is_default = true
state = "ACTIVE"

πŸ” Troubleshooting

Symptom Cause Fix
apply fails with a KMS permission error Discovery Engine service agent lacks roles/cloudkms.cryptoKeyEncrypterDecrypter on the key Grant the role and allow ~60 seconds for IAM propagation
destroy fails with a deletion-policy error deletion_policy = "PREVENT" (this module's default) Apply once with deletion_policy = "DELETE" or "ABANDON", then run the destroy
New Discovery Engine resources are not encrypted with the expected key set_default = false was set on the intended config, or another config is is_default = true Set set_default = true on the intended CMEK config

πŸ”— Related Docs

About

Terraform module: terraform-google-discovery-engine-cmek-config

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages