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

如何在Terraform的tfvars文件中实现值的多变量共享?

解决方案

由于Terraform的.tfvars文件仅用于给变量赋值,不支持引用变量或表达式,你可以通过以下几种方式避免硬编码重复值:

1. 用本地值(Local Values)复用配置

将共享的CIDR和依赖它的规则逻辑移到.tf配置文件中,通过本地值统一管理:

首先在variables.tf定义必要变量:

variable "my_cidr" {
  type        = string
  description = "VPC CIDR block"
}

然后在main.tf中定义本地值并引用变量:

locals {
  # 复用my_cidr定义EFS入站规则
  efs_ingress_rules = [
    {
      description       = "Allowed EFS ingress sources"
      from_port         = 2049
      to_port           = 2049
      protocol          = "tcp"
      cidr_blocks       = [var.my_cidr]
      ipv6_cidr_blocks  = null
      prefix_list_ids   = []
      security_groups   = []
      self              = false
    }
  ]
}

# 使用本地值创建安全组规则
resource "aws_security_group_rule" "efs_ingress" {
  count             = length(local.efs_ingress_rules)
  type              = "ingress"
  from_port         = local.efs_ingress_rules[count.index].from_port
  to_port           = local.efs_ingress_rules[count.index].to_port
  protocol          = local.efs_ingress_rules[count.index].protocol
  cidr_blocks       = local.efs_ingress_rules[count.index].cidr_blocks
  ipv6_cidr_blocks  = local.efs_ingress_rules[count.index].ipv6_cidr_blocks
  prefix_list_ids   = local.efs_ingress_rules[count.index].prefix_list_ids
  security_groups   = local.efs_ingress_rules[count.index].security_groups
  self              = local.efs_ingress_rules[count.index].self
  security_group_id = aws_security_group.efs.id
}

此时你的.tfvars只需保留CIDR赋值:

my_cidr = "10.10.10.0/24"

2. 给变量设置默认值(适合模块场景)

如果需要让EFS规则支持自定义,但默认复用VPC CIDR,可以给规则变量设置包含var.my_cidr的默认值:

在模块的variables.tf中:

variable "my_cidr" {
  type        = string
  description = "VPC CIDR block"
}

variable "efs_ingress_rules" {
  type = list(object({
    description       = string
    from_port         = number
    to_port           = number
    protocol          = string
    cidr_blocks       = list(string)
    ipv6_cidr_blocks  = list(string) | null
    prefix_list_ids   = list(string)
    security_groups   = list(string)
    self              = bool
  }))
  description = "EFS ingress rules"
  # 默认规则自动引用my_cidr
  default = [
    {
      description       = "Allowed EFS ingress sources"
      from_port         = 2049
      to_port           = 2049
      protocol          = "tcp"
      cidr_blocks       = [var.my_cidr]
      ipv6_cidr_blocks  = null
      prefix_list_ids   = []
      security_groups   = []
      self              = false
    }
  ]
}

这样使用者在.tfvars中可以只传my_cidr,直接使用默认规则;如果需要自定义规则,再覆盖efs_ingress_rules即可。

3. 用模板文件管理共享配置(适合复杂场景)

如果有大量共享配置需要维护,可以用YAML/JSON模板文件结合templatefile函数渲染:

创建config-template.yaml:

my_cidr: ${my_cidr}
efs_ingress:
  - description: "Allowed EFS ingress sources"
    from_port: 2049
    to_port: 2049
    protocol: "tcp"
    cidr_blocks: ["${my_cidr}"]
    ipv6_cidr_blocks: null
    prefix_list_ids: []
    security_groups: []
    self: false

在main.tf中读取并渲染模板:

locals {
  config = yamldecode(templatefile("${path.module}/config-template.yaml", {
    my_cidr = var.my_cidr
  }))
}

# 示例:使用渲染后的配置创建规则
resource "aws_security_group_rule" "efs_ingress" {
  count             = length(local.config.efs_ingress)
  type              = "ingress"
  from_port         = local.config.efs_ingress[count.index].from_port
  to_port           = local.config.efs_ingress[count.index].to_port
  protocol          = local.config.efs_ingress[count.index].protocol
  cidr_blocks       = local.config.efs_ingress[count.index].cidr_blocks
  # 其他参数...
  security_group_id = aws_security_group.efs.id
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:13:22