Terraform:在另一个资源中引用在for_each中创建的资源

时间:2020-08-28 21:40:29

标签: amazon-web-services foreach terraform amazon-route53

当我有一个托管区域时,很容易创建该区域,然后通过按名称引用托管区域来创建代理帐户中该区域的NS记录。

现在,我需要创建多个托管区域,并将名称服务器记录传递回父帐户,并且我不确定是否有可能(或如何)引用多个资源。读这篇文章可能没有多大意义,所以下面的代码是我所掌握的。

我现在有一个for_each循环,该循环将遍历字符串列表并为每个字符串创建一个托管区域,然后我想在另一个帐户中创建相应的NS记录,请注意,我正在使用单独的提供商provider = aws.management_account连接到管理帐户,这对于单个托管区域来说效果很好。

我不知道如何引用托管区域,是否有某些语法或我的方法错误?

resource "aws_route53_zone" "public_hosted_zone" {
  for_each = local.aws_zones
  name     = "${each.value}.${var.domain}"
}

resource "aws_route53_record" "ns_records" {
  for_each        = local.aws_zones
  provider        = aws.management_account
  allow_overwrite = true
  name            = "${each.value}.${var.domain}"
  ttl             = 30
  type            = "NS"
  zone_id         = data.aws_ssm_parameter.public_hosted_zone_id.value

  records = [
    aws_route53_zone.public_hosted_zone.name_servers[0], # Here is my old code which works for a single hosted zone but I cannot work out how to reference multiples created above
    aws_route53_zone.public_hosted_zone.name_servers[1],
    aws_route53_zone.public_hosted_zone.name_servers[2],
    aws_route53_zone.public_hosted_zone.name_servers[3]
  ]
}

2 个答案:

答案 0 :(得分:2)

由于您的local.aws_zones设置为[“ dev”,“ test”,“ qa”],因此,您的aws_route53_zone.public_hosted_zone将是键为“ dev”,“ test”,“ qa”的地图。

因此,要在aws_route53_record中使用它,可以尝试:

resource "aws_route53_record" "ns_records" {
  for_each        = local.aws_zones

  # other attributes

  records = aws_route53_zone.public_hosted_zone[each.key].name_servers
}

答案 1 :(得分:1)

在这种情况下,您的意图似乎是说“ local.aws_zones中的每个条目有一个区域,然后每个区域有一个NS记录集”。

在这种情况下,一种简单的记录方式是使用一种资源作为另一种资源的for_each,如下所示:

resource "aws_route53_zone" "public_hosted_zone" {
  for_each = local.aws_zones

  name = "${each.value}.${var.domain}"
}

resource "aws_route53_record" "ns_records" {
  provider = aws.management_account
  for_each = aws_route53_zone.public_hosted_zone

  allow_overwrite = true
  name            = each.value.name
  ttl             = 30
  type            = "NS"
  zone_id         = data.aws_ssm_parameter.public_hosted_zone_id.value
  records         = each.value.name_servers
}

通过在for_each内使用resource "aws_route53_zone" "public_hosted_zone",您可以使aws_route53_zone.public_hosted_zone成为从区域键到区域对象的映射,它本身符合for_each的期望,因此您可以将该地图向下传递到另一个资源。

此方法的一个重要优点是each.value块中的resource "aws_route53_record" "ns_records"是直接对应的区域对象,因此我们可以编写each.value.name来获得派生的name区域中的参数,而不必再次重复该表达式,我们可以编写each.value.name_servers来获取每个区域的导出的名称服务器集。这样就可以避免编写更复杂的表达式以通过each.key查找区域,因为Terraform已经完成了必要的查找以填充each.value