我已经找了很多遍了,我觉得我还没有找到我真正需要的答案。如果所有属性都位于同一个根对象上,我将尝试遍历嵌套块,如果所有属性都位于同一个根对象上,则可以成功地执行此操作。如果我想遍历整个属性集,这是很好的。然而,这种情况有点不同。我需要循环一整组属性和一个子集。
在这个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 = {中有值,返回一个通用错误,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
}
}
}
} 发布于 2022-09-26 16:56:08
对于当前的示例,dynamic "rule"块有一个for表达式,它实际上没有做任何有用的事情:
{ for k, v in var.escalation_policies : k => v }这种表达方式在两方面都很奇怪:
k, v投影到k => v是不寻常的,因为这并没有真正改变有关键或值的任何内容。由于源var.escalation_policies.var.escalation_policies相同,这也是不寻常的,因为它基于与包含的资源相同的集合重复嵌套块:每个var.escalation_policy元素将有一个pagerduty_escalation_policy.this实例,然后每个var.escalation_policy元素都有一个嵌套rule块。为了获得有用的结果,您的for_each块中的dynamic应该使用不同的集合作为重复的基础。我认为在您的示例中,您打算在每个策略的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
}
# ...
}这意味着each.value现在将包含一个附加属性rules,它在var.escalation_policies的每个元素中具有与相应属性相同的值。
然后,您可以引用rules块中的dynamic属性:
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的每个元素生成一个动态的each.value.rules块,这是当前策略的rules属性。
在content块rule.value中是当前的rule对象,因此可以引用该对象中的escalation_delay_in_minutes和target等属性。
发布于 2022-09-26 16:54:23
id是target对象中的键,而不是rule中的键。
id = rule.value.target.id还请注意,迭代映射中的键值对并输出完全相同结构的for表达式是无关的,可以删除它以提高效率和可读性:
dynamic "rule" {
for_each = var.escalation_policies
...
}https://stackoverflow.com/questions/73856931
复制相似问题