Terraform循环变量批量上传密钥至多个Key Vault问题求助
问题分析与解决方案
你的问题核心在于**azurerm_key_vault_secret资源的for_each遍历对象错误**:当前代码用var.key_vaults作为循环对象,每个Key Vault只会生成一个Secret资源实例,后续配置的Secret会覆盖之前的,最终每个Vault只保留最后一个Secret。
要实现批量上传多个Secret到多个Vault,需要遍历每个Vault下的所有Secret,而非Vault本身。我们可以通过Terraform的flatten和for表达式,构建包含「Vault-Secret」唯一组合的扁平映射,让每个Secret成为独立的资源实例。
修改步骤
1. 构建扁平的Secret实例映射
在代码中添加locals块,将每个Vault下的Secret展开为独立条目,确保每个Secret都有唯一标识:
locals { # 展开所有Vault下的Secret,生成包含Vault和Secret信息的列表 key_vault_secrets = flatten([ for vault_key, vault_details in var.key_vaults : [ for secret_key, secret_details in vault_details.secrets : { vault_key = vault_key secret_key = secret_key vault_id = azurerm_key_vault.test_vault[vault_key].id secret_name = secret_details.name secret_value = secret_details.value content_type = secret_details.content_type } ] ]) # 将列表转换为映射,用「Vault键-Secret键」作为唯一键,避免资源冲突 secret_instances = { for secret in local.key_vault_secrets : "${secret.vault_key}-${secret.secret_key}" => secret } }
2. 修改Secret资源的for_each
将azurerm_key_vault_secret的for_each指向上面生成的local.secret_instances,确保每个Secret都被独立创建:
# Create an Azure Key Vault secrets resource "azurerm_key_vault_secret" "secret" { for_each = local.secret_instances key_vault_id = each.value.vault_id name = each.value.secret_name value = each.value.secret_value content_type = each.value.content_type }
变量配置示例
确保var.key_vaults按预期包含多个Secret,示例如下:
variable "key_vaults" { type = map(object({ vault_name = string location = string sku_name = string tags = map(string) secrets = map(object({ name = string value = string content_type = string })) })) default = { rg-test-east = { vault_name = "kv-test-eastus" location = "eastus" sku_name = "standard" tags = { env = "test" } secrets = { db-admin-pass = { name = "DBAdminPassword" value = "StrongPass123!" content_type = "text/plain" } api-auth-key = { name = "APIAuthKey" value = "789xyzABC" content_type = "text/plain" } # 可添加更多Secret... } } rg-test-west = { vault_name = "kv-test-westus" location = "westus" sku_name = "standard" tags = { env = "test" } secrets = { storage-account-key = { name = "StorageAccountKey" value = "StorageKey123" content_type = "text/plain" } # 可添加更多Secret... } } } }
验证
执行terraform plan,你会看到Terraform为每个「Vault-Secret」组合生成独立的创建计划;执行terraform apply后,每个Vault下的所有Secret都会被正确创建,不会出现覆盖问题。
内容的提问来源于stack exchange,提问作者Rodrigo
相关产品推荐
相关产品推荐

