首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >地形嵌套块中的for_each

地形嵌套块中的for_each
EN

Stack Overflow用户
提问于 2022-09-26 16:09:06
回答 2查看 122关注 0票数 0

我已经找了很多遍了,我觉得我还没有找到我真正需要的答案。如果所有属性都位于同一个根对象上,我将尝试遍历嵌套块,如果所有属性都位于同一个根对象上,则可以成功地执行此操作。如果我想遍历整个属性集,这是很好的。然而,这种情况有点不同。我需要循环一整组属性和一个子集。

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

代码语言:javascript
复制
  /// 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无法在对象中找到这些属性,而我已经确认的对象是根对象,而不是嵌套的。这是通过简单地将这些属性移出对象输入块的根来验证的。

代码语言:javascript
复制
│ 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的变量

代码语言:javascript
复制
variable "escalation_policies" {
  description = "A list of escalation policies and rules for a given PagerDuty service."
  type        = any
}

和资源

代码语言:javascript
复制
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
      }
    }
  }
} 
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-26 16:56:08

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

代码语言:javascript
复制
{ for k, v in var.escalation_policies : k => v }

这种表达方式在两方面都很奇怪:

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

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

代码语言:javascript
复制
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属性:

代码语言:javascript
复制
  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属性。

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

票数 2
EN

Stack Overflow用户

发布于 2022-09-26 16:54:23

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

代码语言:javascript
复制
id = rule.value.target.id

还请注意,迭代映射中的键值对并输出完全相同结构的for表达式是无关的,可以删除它以提高效率和可读性:

代码语言:javascript
复制
dynamic "rule" {
  for_each = var.escalation_policies
  ...
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73856931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档