地形嵌套块中的for_each



我已经搜索了很多,但我认为我没有找到我真正需要的答案。我正在尝试循环一个嵌套块,如果所有属性都在同一个根对象上,我就成功地做到了。如果我想在整个属性集上循环,这非常好。然而,这种情况有点不同。我需要循环整个属性集和一个子集。

在这个Terragrunt示例中,您可以看到所需的输入,因为我们希望完全循环升级策略以及循环规则及其目标,这样我们就可以创建许多包含许多规则/目标的升级策略。

/// PagerDuty Escalation Policies
create_escalation_policy = true
escalation_policies = [
{
name        = "TEST Engineering Escalation 1"
description = "My TEST engineering escalation policy 1"
teams       = ["111N1CV"]
num_loops   = 2
rule = [
{
escalation_delay_in_minutes = 15
target = {
type = "user_reference"
id   = "ABCB8F3"
}
},
{
escalation_delay_in_minutes = 15
target = {
type = "user_reference"
id   = "NBCB1A1"
}
}
}
]

然而,经过一番尝试和错误之后,我能够循环整个升级策略,但如果我们在rule = {中有值,则不能循环。CCD_1返回一个一般错误,Terraform在我确认为根对象而不是嵌套对象的对象中找不到这些属性。这是通过简单地将这些属性移到对象输入块的根来验证的。

│ Error: Unsupported attribute
│ 
│   on main.tf line 121, in resource "pagerduty_escalation_policy" "this":
│  121:         id   = rule.value.id
│     ├────────────────
│     │ rule.value is object with 5 attributes
│ 
│ This object does not have an attribute named "id".

作为参考,这里是var.escalation_policies 的变量

variable "escalation_policies" {
description = "A list of escalation policies and rules for a given PagerDuty service."
type        = any
}

以及资源

resource "pagerduty_escalation_policy" "this" {
for_each = { 
for key in var.escalation_policies : key.name => {
name                        = key.name
description                 = key.description
num_loops                   = key.num_loops
teams                       = key.teams
}
if var.create_escalation_policy == true 
}
name        = each.value.name
description = each.value.description
num_loops   = each.value.num_loops
teams       = each.value.teams
dynamic "rule" {
for_each = {
for k, v in var.escalation_policies : k => v }
content {
escalation_delay_in_minutes = rule.value.escalation_delay_in_minutes
target {
type = rule.value.type
id   = rule.value.id
}
}
}
} 

在您当前的示例中,dynamic "rule"块有一个for表达式,它实际上没有做任何有用的事情:

{ for k, v in var.escalation_policies : k => v }

这个表达在两个方面很奇怪:

  • 单独使用表达式,将k, v直接投影到k => v是不寻常的,因为这不会真正改变键或值的任何内容。由于源var.escalation_policies是一个列表而不是映射,因此更改结果的数据类型,并使Terraform将整数索引转换为字符串,但除此之外,元素与var.escalation_policies相同
  • 考虑到上下文,这也是不寻常的,因为它重复了基于与包含资源相同集合的嵌套块:每个var.escalation_policy元素将有一个pagerduty_escalation_policy.this实例,然后每个实例将为每个升级策略有一个嵌套的rule

为了获得有用的结果,dynamic块中的for_each应该使用不同的集合作为其重复的基础。我认为在您的情况下,您打算在每个策略的rule属性中使用嵌套列表,但最外层的for_each表达式不包括规则,因此您首先需要更新:

resource "pagerduty_escalation_policy" "this" {
for_each = { 
for policy in var.escalation_policies : policy.name => {
name                        = policy.name
description                 = policy.description
num_loops                   = policy.num_loops
teams                       = policy.teams
rules                       = policy.rule
}
if var.create_escalation_policy == true 
}
# ...
}

这意味着CCD_ 15现在将包括附加属性CCD_。

然后,您可以在dynamic块中引用rules属性:

dynamic "rule" {
for_each = each.value.rules
content {
escalation_delay_in_minutes = rule.value.escalation_delay_in_minutes
target {
type = rule.value.target.type
id   = rule.value.target.id
}
}
}

这个命令告诉Terraform为each.value.rules的每个元素生成一个动态rule块,这是当前策略的rules属性。

content块中,rule.value是当前的rule对象,因此可以引用该对象中的escalation_delay_in_minutestarget等属性。

idtarget对象中的键,而不是rule:中的键

id = rule.value.target.id

还要注意的是,for表达式在映射中遍历键值对并输出完全相同的结构,这是无关的,为了提高效率和可读性,可以删除:

dynamic "rule" {
for_each = var.escalation_policies
...
}

相关内容

  • 没有找到相关文章

最新更新