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

Terraform中能否使用同名key不同值的多个local块?

Terraform 同名本地变量(local)的优先级问题

问题背景

现有以下Terraform本地变量块,其中domain值为cs,用于生成S3制品桶名称:

locals {
  organization = "xxxx"
  domain       = "cs"
  env = {
    prod = "prod"
    stg  = "stg"
    dev  = "dev"
  }
}

locals {
  s3_artifact_bucket_name = {
    prod = join("-", [
      local.s3_artifact_bucket_name_prefix,
      local.env["prod"]
    ])
    stg = join("-", [
      local.s3_artifact_bucket_name_prefix,
      local.env["stg"]
    ])
    dev = join("-", [
      local.s3_artifact_bucket_name_prefix,
      local.env["dev"]
    ])
  }
  s3_artifact_bucket_name_prefix = join("-", [
    local.organization,
    local.domain,
    local.s3_bucket_awsresource,
    local.s3_artifact_bucket_purpose
  ])
  s3_bucket_awsresource = join("-", [
    "bucket",
    var.cd_account_id
  ])
  s3_artifact_bucket_purpose = "artifacts-iac"
}

现在需要新增一个本地变量块,其中domain值为common,用于生成访问日志S3桶名称:

locals {
  # placeholder for access logs bucket name
  domain = "common"
  s3_bucket_awsresource = join("-", [
    "bucket",
    var.cd_account_id
  ])
  s3_bucket_purpose         = "s3-access-logs"
  access_logs_bucket_region = "us-east-1"
}

后续引用local.domain时希望指向common而非cs,有两个疑问:

  • 最终local.domain会指向哪个值?
  • 是否允许在不同locals块中使用同名的domain键并赋予不同值?

核心结论

  1. 同名local变量的覆盖规则
    Terraform会按locals块的定义顺序处理,后定义的locals块中的同名变量会直接覆盖之前的。也就是说,你新增的domain = "common"块在原有domain = "cs"块之后,最终local.domain的值会是common,所有后续引用local.domain的地方都会使用这个值。

但要注意:原有locals块中依赖local.domain的变量(比如s3_artifact_bucket_name_prefix),会使用定义它们时生效的domain值——也就是最初的cs,因为这些变量是在第一个domain所在块之后、第二个domain块之前定义的,Terraform在计算这些变量时,当时的local.domain还是cs。

  1. 是否允许同名键?
    允许在多个locals块中使用同名变量键,但会触发Terraform的变量覆盖行为,容易引发逻辑混淆,不推荐这么做。

更清晰的解决方案

为了避免变量覆盖带来的混乱,建议给不同用途的domain变量起明确的名字,比如:

locals {
  organization = "xxxx"
  domain_cs    = "cs"
  domain_common = "common"
  env = {
    prod = "prod"
    stg  = "stg"
    dev  = "dev"
  }
}

# 生成制品桶的相关变量
locals {
  s3_artifact_bucket_name = {
    prod = join("-", [
      local.s3_artifact_bucket_name_prefix,
      local.env["prod"]
    ])
    stg = join("-", [
      local.s3_artifact_bucket_name_prefix,
      local.env["stg"]
    ])
    dev = join("-", [
      local.s3_artifact_bucket_name_prefix,
      local.env["dev"]
    ])
  }
  s3_artifact_bucket_name_prefix = join("-", [
    local.organization,
    local.domain_cs,
    local.s3_bucket_awsresource,
    local.s3_artifact_bucket_purpose
  ])
  s3_bucket_awsresource = join("-", [
    "bucket",
    var.cd_account_id
  ])
  s3_artifact_bucket_purpose = "artifacts-iac"
}

# 生成访问日志桶的相关变量
locals {
  s3_bucket_awsresource_access_logs = join("-", [
    "bucket",
    var.cd_account_id
  ])
  s3_bucket_purpose_access_logs         = "s3-access-logs"
  access_logs_bucket_region = "us-east-1"
}

locals {
  s3_artifact_access_logs_bucket_name = join("-", [
    local.organization,
    local.domain_common,
    local.s3_bucket_awsresource_access_logs,
    local.s3_bucket_purpose_access_logs,
    local.access_logs_bucket_region
  ])
}

这样每个变量的用途明确,不会出现覆盖导致的意外行为,代码可读性也更高。


内容的提问来源于stack exchange,提问作者Jatin Mehrotra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:25:22