如何在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
相关产品推荐
相关产品推荐

