根据另一个资源的属性长度设置 "count"

Setting "count" based on the length of an attribute on another resource

我有一个相当简单的 Terraform 配置,它创建一个 Route53 区域,然后在 Cloudflare 中创建 NS 记录以将子域委托给该区域。目前,它假设每个 Route53 区域始终恰好有四个权威 DNS 服务器,并创建四个单独的 cloudflare_record 资源,但我想概括一下,部分原因是谁知道 AWS 是否会开始放置第五个权威服务器将来会在那里,但也会作为 "test case" 用于将来更复杂的东西(比如 AWS AZ,我 知道 不同地区的数量不同)。

到目前为止我想出的是:

resource "cloudflare_record" "public-zone-ns" {
  domain = "example.com"
  name   = "${terraform.env}"
  type   = "NS"
  ttl    = "120"
  count  = "${length(aws_route53_zone.public-zone.name_servers)}"
  value  = "${lookup(aws_route53_zone.public-zone.name_servers, count.index)}"
}

resource "aws_route53_zone" "public-zone" {
  name = "${terraform.env}.example.com"
}

当我 运行 terraform plan 解决这个问题时,我得到了这个错误:

Error running plan: 1 error(s) occurred:

* cloudflare_record.public-zone-ns: cloudflare_record.public-zone-ns: value of 'count' cannot be computed

认为 这意味着因为 aws_route53_zone 实际上还没有被创建,所以 terraform 不知道 length(aws_route53_zone.public-zone.name_servers) 是什么,并且因此 cloudflare_record.public-zone-ns.count 的插值失败,我被搞砸了。

然而,令我惊讶的是 Terraform 竟然如此死板;肯定能够像这样创建数量可变的资源将是肉和土豆的东西。对长度进行硬编码,或创建单独的资源,似乎是如此……限制。

那么,我错过了什么?当我事先不知道我需要多少资源时,如何创建大量资源?

我明白你的意思了,这也让我很惊讶。连资源cloudflare_record都加了depends_on,也是无奈。

要解决此问题,您可以将其拆分为两个堆栈,并确保在 cloudflare 记录之前创建 route 53 记录。

堆栈 #1

resource "aws_route53_zone" "public-zone" {
  name = "${terraform.env}.example.com"
}

output "name_servers" {
  value = "${aws_route53_zone.public-zone.name_servers}"
}

堆栈 #2

data "terraform_remote_state" "route53" {
  backend = "s3"
  config {
    bucket = "terraform-state-prod"
    key    = "network/terraform.tfstate"
    region = "us-east-1"
  }
}

resource "cloudflare_record" "public-zone-ns" {
  domain = "example.com"
  name   = "${terraform.env}"
  type   = "NS"
  ttl    = "120"
  count  = "${length(data.terraform_remote_state.route53.name_servers)}"
  value  = "${element(data.terraform_remote_state.route53.name_servers, count.index)}"
}

当前无法计算计数是 terraform 中的一个未解决问题 https://github.com/hashicorp/terraform/issues/12570

您可以将名称服务器移动到一个变量数组,然后获取它的长度,所有这些都在一个 terraform 脚本中。