【发布时间】:2021-07-11 07:28:29
【问题描述】:
我有一个本地文件来描述不同的参数,用于不同的环境,例如
parameters.tf:
locals {
env = {
dev1 = {
...
natgw_route_table_id = "rtb-048....."
transit_gateway_route_table_id = "tgw-rtb-05cc..."
transit_gateway_id = "tgw-087..."
ec2_route_table_id = "rtb-059..."
ec2routes_ngw = {
f1 = {
destination_cidr = "10.12.13.14/24"\
nat_gateway_id = "nat-02a..."
transit_gateway_attachment_id = "tgw-attach-0f07..."
}
f2 = {
destination_cidr = "10.12.13.15/32"
nat_gateway_id = "nat-0a6c..."
transit_gateway_attachment_id = "tgw-attach-028"
}
}
}
...
prod = {
natgw_route_table_id = "rtb-0be..."
transit_gateway_route_table_id = "tgw-rtb-0ab7..."
transit_gateway_id = "tgw-00dfa..."
ec2_route_table_id = ["rtb-0de4...", "rtb-070a9...", "rtb-044a...", "rtb-0c8a..."]
ec2routes_ngw = {
f1 = {
destination_cidr = "10.10.11.12/24"
nat_gateway_id = ["nat-09af...", "nat-042b...", "nat-078e...", "nat-0cd2c..."]
transit_gateway_attachment_id = "tgw-attach-0ed5025f6fc1731f7"
}
}
}
}
}
如您所见,对于名为 dev1 的环境,我们有一个子网到一个 nat 网关。 这可以通过以下资源轻松解决:
resource "aws_route" "natgw" {
for_each = { for k, v in local.workspace["ec2routes_ngw"] : k => v if(local.workspace["releaseStage"] != "prod")}
route_table_id = local.workspace["ec2_route_table_id"]
destination_cidr_block = each.value.destination_cidr
nat_gateway_id = each.value.nat_gateway_id
}
但是,对于 prod 和可能的其他人,我们为每个 AZ 子网及其各自的 NAT 网关提供了一个路由表。
现在,我可以破解它来工作,但我更愿意这样做更优雅一些。
我发现了一些使用for_each 和扁平化本地文件的类似示例。我不介意为那些 prod 类型的环境提供单独的资源,但我不想对其进行硬编码。
感谢任何想法。
【问题讨论】:
-
你确定这是你的数据结构吗?所以一旦
ec2_route_table_id和nat_gateway_id是字符串,那么它们就是一个列表?换句话说,你的数据结构没有一致性? -
同意您的数据结构不一致。在 terraform 中展开如此复杂的数据结构需要进行大量重新映射,以便为您想要从中创建的每个资源正确访问该结构。最有可能涉及使用
setproduct()或 @ 等函数再次重构结构987654332@ 以便稍后使用for_each创建资源.. 我们在 vpc 模块中做了很多这样的事情:github.com/mineiros-io/terraform-aws-vpc -
嗯,它是一个伪数据结构。即使我将
nat_gateway_id格式化为一个包含一个元素的列表以保持一致性,我也不知道如何展开它以创建适当的资源。 -
Flattening nested structures for
for_each中有一个类似情况的工作示例。如果这是您已经看到的示例之一,那么如果您可以展示您尝试过的内容和发生了什么,或者在您的问题中包含您在参考该示例后遇到的任何具体问题,将会有所帮助。
标签: terraform terraform-provider-aws