You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 00:42:42