Terraform AWS Network Firewall资源subnet_id属性值类型错误排查
解决Terraform创建AWS Network Firewall时的subnet_id类型错误
问题场景
在使用Terraform创建aws_networkfirewall_firewall资源时,通过dynamic块遍历firewall_subnet_ids,触发如下错误:
Inappropriate value for attribute "subnet_id": string required
查看firewall_subnet_ids的输出为嵌套列表结构:
firewall_subnet_ids = [ tolist([ "subnet-0579947678d######", "subnet-091417fd3a5######", "subnet-0165710e220######", "subnet-00afaa21ad6######", "subnet-0712cac718c######", "subnet-0d361a8d737######", ]), ]
出错的Terraform代码如下:
resource "aws_networkfirewall_firewall" "anfw" { name = "anfw-${var.cluster_name}" firewall_policy_arn = aws_networkfirewall_firewall_policy.anfw_policy.arn firewall_policy_change_protection = false subnet_change_protection = false vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id dynamic "subnet_mapping" { for_each = data.terraform_remote_state.vpc.outputs.firewall_subnet_ids content { subnet_id = subnet_mapping.value } } tags = local.tags }
完整错误信息:
╷ │ Error: Incorrect attribute value type │ │ on main.tf line 29, in resource "aws_networkfirewall_firewall" "anfw": │ 29: subnet_id = subnet_mapping.value │ │ Inappropriate value for attribute "subnet_id": string required.
原因分析
firewall_subnet_ids是嵌套列表结构,外层是一个仅包含单个子网ID列表的列表。当前dynamic块遍历的是外层列表,导致subnet_mapping.value返回的是内层的整个子网ID列表,而非单个字符串,与subnet_id要求的字符串类型不匹配。
解决方案
方案1:直接取内层列表
如果确定外层列表仅包含一个内层子网ID列表,可直接通过索引[0]获取内层列表进行遍历:
resource "aws_networkfirewall_firewall" "anfw" { name = "anfw-${var.cluster_name}" firewall_policy_arn = aws_networkfirewall_firewall_policy.anfw_policy.arn firewall_policy_change_protection = false subnet_change_protection = false vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id dynamic "subnet_mapping" { # 取嵌套列表中的内层子网ID列表 for_each = data.terraform_remote_state.vpc.outputs.firewall_subnet_ids[0] content { subnet_id = subnet_mapping.value } } tags = local.tags }
方案2:扁平化嵌套列表(通用方案)
如果外层列表可能包含多个内层列表,使用Terraform的flatten函数将嵌套列表转为一维列表,确保遍历的是单个子网ID字符串:
resource "aws_networkfirewall_firewall" "anfw" { name = "anfw-${var.cluster_name}" firewall_policy_arn = aws_networkfirewall_firewall_policy.anfw_policy.arn firewall_policy_change_protection = false subnet_change_protection = false vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id dynamic "subnet_mapping" { # 扁平化嵌套列表,得到所有子网ID的一维列表 for_each = flatten(data.terraform_remote_state.vpc.outputs.firewall_subnet_ids) content { subnet_id = subnet_mapping.value } } tags = local.tags }
内容的提问来源于stack exchange,提问作者user20208419
相关产品推荐
相关产品推荐

