根据另一个资源的属性长度设置 "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 脚本中。
我有一个相当简单的 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 脚本中。