0

我正在努力为 Azure 中相同资源的多个专用端点设置动态专用 dns 区域记录(ACR - Azure 容器注册表)。

所以我目前已经设置了这个简单的例子。基本上,它模拟 ACR 的创建并构建需要在 DNS 中注册的记录映射,以便可以正确使用 ACR。这里的问题是,需要以某种方式从每个资源/对象的内部字段(这里是端点变量)中提取值,然后正确转换它以匹配预期的输出。这是必需的,因为在我的情况下,它是模块的组成部分,并且需要根据创建的实际资源的值动态构建。

以下示例应该可以帮助任何想要检查此问题并有所帮助的人。要验证您是否得到正确的结果,只需键入“terraform refresh”,然后应该打印输出。

terraform {
  backend local {}
}

# simulates creation of multiple Azure Container Registry private endpoints
variable endpoints {
  type = map
  default = {
    "registry" = {
      custom_dns_configs = [
        {
          fqdn = "something.westeurope.data.azurecr.io"
          ip_addresses = ["1.1.1.1",]
        },
        {
          fqdn         = "something.azurecr.io"
          ip_addresses = ["1.1.1.2",]
        }
      ]
    },
    "registry2" = {
      custom_dns_configs = [
        {
          fqdn = "something.westeurope.data.azurecr.io"
          ip_addresses = ["1.1.2.1",]
        },
        {
          fqdn = "something.azurecr.io"
          ip_addresses = ["1.1.2.2",]
        },
      ]
    },
    #...
    # "registryN" = {...}
  }
}

# Question: How to write for block here to get out of it exactly what's in expected
#           result having in mind that there can be multiple of "registry" blocks?
#           Below line produce only single result which doesn't match expected result.
output result {
  value = {for pe in var.endpoints:
    pe.custom_dns_configs[0].fqdn => pe.custom_dns_configs[0].ip_addresses
  }
}

# Expected result:
# result = {
#   "something.westeurope.data.azurecr.io" = [
#     "1.1.1.1",
#     "1.1.2.1",
#   ]
#   "something.azurecr.io" = [
#     "1.1.1.2",
#     "1.1.2.2",
#   ]
# }
4

1 回答 1

0

回答我自己的问题:

output result {
  value = {for k,v in { 
      for cdc in flatten(
        [for pe in var.endpoints: pe.custom_dns_configs]
      ): 
        cdc.fqdn => cdc.ip_addresses...
    }: 
      k => flatten(v)
  }
}

现在解释几句:

  • [] 和 {} - [] 生成一个元组,从传入映射中删除“注册表”键,而 {} 需要生成某种动态键
  • [for pe in var.endpoints: pe.custom_dns_configs] 只需为地图的每个元素从 var.environments 中提取内部字段。然后使用 flatten 只是为了使事情更简单,而无需深入研究不同级别的嵌套列表
  • 接下来是为 fqdn -> list(ip 地址) 构建新地图
  • cdc.ip_addresses 之后的“...”是必需的。这是允许按键对值进行分组的表示法。在这种情况下,我们至少有 2 倍相同的 fqdn,通常情况下,terraform 会抱怨当键不唯一时它无法创建这样的映射。在那里添加这 3 个点可以启用此分组。
  • 然后 top-most for block 仅用于展平整个值输出。

现在的问题是我们是否仍想保留“registry”、“registry2”、“registryN” 分组。为此,我还没有找到解决方案。

于 2021-07-26T12:32:52.193 回答