JP9*_*P96 10 foreach for-loop amazon-web-services terraform
我有一个包含要创建的子网列表的对象。
variable "subnet-map" {
default = {
ec2 = [
{
cidr_block = "10.0.1.0/24"
availability_zone = "eu-west-1a"
}
],
lambda = [
{
cidr_block = "10.0.5.0/24"
availability_zone = "eu-west-1a"
},
{
cidr_block = "10.0.6.0/24"
availability_zone = "eu-west-1b"
},
{
cidr_block = "10.0.7.0/24"
availability_zone = "eu-west-1c"
}
],
secrets = [
{
cidr_block = "10.0.8.0/24"
availability_zone = "eu-west-1a"
},
{
cidr_block = "10.0.9.0/24"
availability_zone = "eu-west-1b"
},
{
cidr_block = "10.0.10.0/24"
availability_zone = "eu-west-1c"
}
],
rds = [
{
cidr_block = "10.0.11.0/24"
availability_zone = "eu-west-1a"
},
{
cidr_block = "10.0.12.0/24"
availability_zone = "eu-west-1b"
},
{
cidr_block = "10.0.13.0/24"
availability_zone = "eu-west-1c"
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
早些时候我使用了计数循环结构。所以我曾经把上面的结构扁平化成一个对象列表
locals {
subnets = flatten([
for resource in keys(var.subnet-map) : [
for subnet in var.subnet-map[resource] : {
resource = resource
cidr_block = subnet.cidr_block
availability_zone = subnet.availability_zone
}
]
])
}
Run Code Online (Sandbox Code Playgroud)
然后我会通过做来创建资源
resource "aws_subnet" "aws-subnets" {
count = length(local.subnets)
vpc_id = aws_vpc.aws-vpc.id
cidr_block = local.subnets[count.index].cidr_block
availability_zone = local.subnets[count.index].availability_zone
tags = {
Name = "subnet-${local.subnets[count.index].resource}-${local.subnets[count.index].availability_zone}"
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想使用 for_each 循环。但我不知道该怎么做。这是我到目前为止所做的。
resource "aws_subnet" "subnets-dev" {
for_each = var.subnet-map
vpc_id = aws_vpc.vpc-dev.id
cidr_block = each.value.cidr_block
availability_zone = each.value.availability_zone
tags = {
Name = "subnet-dev-${each.value.resource}-${each.value.availability_zone}"
environment = "dev"
}
}
Run Code Online (Sandbox Code Playgroud)
但它不断给出一个错误说
Error: Unsupported attribute
on vpc/main.tf line 93, in resource "aws_subnet" "subnets-dev":
93: Name = "subnet-dev-${each.value.resource}-${each.value.availability_zone}"
|----------------
| each.value is tuple with 3 elements
This value does not have any attributes.
Run Code Online (Sandbox Code Playgroud)
我怎么能解决这个问题?
Mar*_*ins 10
我不确定我是否完全遵循了您在此处尝试的所有内容,因为您最初的片段var.subnet-map显示它是对象列表的映射图,但是后来当您使用for_each = var.subnet-map它时,它似乎已将其视为列表映射。在尝试之前,您是否删除了额外的地图级别(“默认”键)for_each?
使用 的原始定义variable "subnet-map",您的第一步for_each将类似于您所做的count:您需要将结构展平,这次是将结构展平为对象映射而不是对象列表。到达那里的最简单方法是从现有的扁平化列表中获取地图:
locals {
subnets = flatten([
for resource in keys(var.subnet-map) : [
for subnet in var.subnet-map[resource] : {
resource = resource
cidr_block = subnet.cidr_block
availability_zone = subnet.availability_zone
}
]
])
subnets_map = {
for s in local.subnets: "${s.resource}:${s.availability_zone}" => s
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我假设您的“资源”字符串和可用区一起是一个合适的子网唯一标识符。如果没有,您可以将"${s.resource}:${s.availability_zone}"零件调整为您想要用于这些的任何唯一键。
现在您可以使用扁平化的地图作为for_each地图:
resource "aws_subnet" "subnets-dev" {
for_each = local.subnets_map
vpc_id = aws_vpc.vpc-dev.id
cidr_block = each.value.cidr_block
availability_zone = each.value.availability_zone
tags = {
Name = "subnet-dev-${each.value.resource}-${each.value.availability_zone}"
environment = "dev"
}
}
Run Code Online (Sandbox Code Playgroud)
这将为您提供具有类似地址的实例aws_subnet.subnets-dev["ec2:eu-west-1a"]。
请注意,如果您要从count要保留的现有子网进行迁移,则还需要执行一次性迁移步骤,以告诉 Terraform 现有状态中的哪些索引对应于新配置中的哪些键。
例如,如果(且仅当) index0以前是 for ec2in eu-west-1a,则该索引的迁移命令将是:
terraform state mv 'aws_subnet.subnets-dev[0]' 'aws_subnet.subnets-dev["ec2:eu-west-1a"]'
Run Code Online (Sandbox Code Playgroud)
如果您不确定它们之间的关系,您可以terraform plan在添加后运行for_each并查看 Terraform 计划销毁的实例。如果您依次处理其中的每一个,将 Terraform 当前知道的地址与Name标签中显示的资源和可用区域名称一起使用,您可以将它们中的每一个迁移到其新地址,以便 Terraform 不再认为您是要求它销毁编号的实例并用命名的实例替换它们。
| 归档时间: |
|
| 查看次数: |
22947 次 |
| 最近记录: |