使用 terraform 在 for_each 嵌套资源中循环
Posted
技术标签:
【中文标题】使用 terraform 在 for_each 嵌套资源中循环【英文标题】:Looping in for_each nested resources with terraform 【发布时间】:2021-10-06 13:19:16 【问题描述】:我正在尝试使用多个订阅预配多个 Azure 服务总线主题。我可以创建主题,但无法循环订阅变量来创建订阅。
################
locals
servicebus =
"topic_1" = [
subscription = ["subscription1", "subscription2", "subscription3"]
],
"topic_2" = [
subscription = ["subscription4", "subscription5", "subscription6"]
],
"topic_3" = [
subscription = ["subscription7", "subscription8", "subscription9"]
]
service_bus = flatten([
for topicname, topic in local.servicebus : [
for subname in topic :
name = topicname
subscription_name = subname.subscription
]
])
在 servicebus_subscription 资源块中,无法循环订阅名称,但是当我提供 index(each.value.subscription_name[0]) 时,它只创建一个订阅
############ Creating Servicebus Topic ###############################
module "servicebus_topic"
source = "./servicebus/topic"
for_each =
for sname in local.service_bus : sname.name => sname
name = each.key
resource_group_name = azurerm_resource_group.rg.name
namespace_name = module.servicebus_namespace.name
max_size_in_megabytes = "1024"
depends_on = [module.servicebus_namespace.name]
########## Creating Servicebus Subscription ###############################
resource "azurerm_servicebus_subscription" "sbs"
for_each =
for sname in local.service_bus : sname.name => sname
name = each.value.subscription_name
topic_name = module.servicebus_topic[each.value.name].name
namespace_name = module.servicebus_namespace.name
resource_group_name = azurerm_resource_group.rg.name
max_delivery_count = "10"
错误:
Error: Incorrect attribute value type
│
│ on servicebus.tf line 77, in resource "azurerm_servicebus_subscription" "sbs":
│ 77: name = each.value.subscription_name
│ ├────────────────
│ │ each.value.subscription_name is tuple with 3 elements
│
│ Inappropriate value for attribute "name": string required.
╵
╷
│ Error: Incorrect attribute value type
│
│ on servicebus.tf line 77, in resource "azurerm_servicebus_subscription" "sbs":
│ 77: name = each.value.subscription_name
│ ├────────────────
│ │ each.value.subscription_name is tuple with 3 elements
│
│ Inappropriate value for attribute "name": string required.
使用 Terraform 控制台的局部变量调试输出:
> local.service_bus
[
"name" = "topic_1"
"subscription_name" = [
"subscription1",
"subscription2",
"subscription3",
]
,
"name" = "topic_2"
"subscription_name" = [
"subscription4",
"subscription5",
"subscription16",
]
,
]
【问题讨论】:
【参考方案1】:你们很亲密。应该是:
service_bus = merge([
for topicname, topic in local.servicebus :
for subname in topic[0].subscription :
"$topicname-$subname" =>
name = topicname
subscription_name = subname
]...)
然后
resource "azurerm_servicebus_subscription" "sbs"
for_each = local.service_bus
name = each.value.subscription_name
topic_name = module.servicebus_topic[each.value.name].name
namespace_name = module.servicebus_namespace.name
resource_group_name = azurerm_resource_group.rg.name
max_delivery_count = "10"
【讨论】:
导致错误,详细信息如下:Error: Invalid index │ │ on servicebus.tf line 85, in resource "azurerm_servicebus_subscription" "sbs": │ 85: topic_name = module.servicebus_topic[each.value.name].name │ │ │ each.value.name is "topic_1" │ │ module.servicebus_topic is object with 6 attributes │ │ The given key does not identify an element in this collection value.
导致错误
@sreeram 你确定你听懂了我的回答还是你的问题完全代表了你的真实代码?【参考方案2】:
我已经根据 Marcin 的代码创建了一个完整的工作示例:
locals
servicebus =
"topic1" = [
subscription = ["sub1", "sub2"]
],
"topic2" = [
subscription = ["sub1"]
]
service_bus = merge([
for topicname, topic in local.servicebus :
for subname in topic[0].subscription :
"$topicname-$subname" =>
name = topicname
subscription_name = subname
]...)
resource "azurerm_servicebus_topic" "topic"
depends_on = [
module.servicebus
]
for_each = local.service_bus
name = each.value.name
resource_group_name = azurerm_resource_group.shared.name
namespace_name = module.servicebus.namespace_name
enable_partitioning = false
max_size_in_megabytes = 1024
resource "azurerm_servicebus_subscription" "subscription"
for_each = local.service_bus
name = each.value.subscription_name
topic_name = each.value.name
namespace_name = module.servicebus.namespace_name
resource_group_name = azurerm_resource_group.shared.name
max_delivery_count = "10"
唯一的小问题是如果没有订阅,它不会创建主题。我有一些主题就是这种情况。
【讨论】:
以上是关于使用 terraform 在 for_each 嵌套资源中循环的主要内容,如果未能解决你的问题,请参考以下文章
如何在 terraform 中正确使用 for_each 中的 each.value?
具有下游依赖项的 Terraform 条件“for_each”
Terraform 因 for_each 参数无效/给定的“for_each”参数值不合适而失败
Terraform For_Each:如何引用创建的资源 ID