【发布时间】:2023-01-26 22:38:11
【问题描述】:
使用 terraform 的 for_each 时,您必须指定一个唯一的 id 以用作将生成的资源与其源定义链接起来的方式。
我想为此使用自然索引,而不是任意的唯一值。在这种情况下,我使用的是 DNS,因此自然索引将是 DNS 记录名称 (FQDN)... 只有那不是总是独特;即,您可以拥有多个 example.com 的 A 记录以允许负载平衡,或者您可以拥有多个 TXT 记录以向多个供应商提供验证。
有没有办法将自然指数与计算值结合起来以提供唯一值;例如所以我们有自然索引后跟一个1如果这是第一次看到这个值,一个2代表第一次重复,等等?
具体要求/背景
我正在努力迁移我们的 DNS 记录,以便使用 Terraform/Terragrunt 通过 IaC 进行管理(这适用于手动管理条目的场景,而不是相关服务也在 IaC 下的场景)。 我希望将记录数据保存在 CSV(或类似文件)中,以避免那些日常管理记录的人需要熟悉 TF/TG;而不是让他们只更新数据,让管道处理剩下的事情。
CSV 格式是这样的:
| myId | RecordName | Type | Value |
|---|---|---|---|
| 1 | A | 1.2.3.4 | |
| 2 | A | 2.3.4.5 | |
| 3 | test | A | 3.4.5.6 |
| 4 | test | A | 4.5.6.7 |
| 5 | www | cname | example.com |
注意:我正在考虑每个 DNS 区域都有一个包含其名称的文件夹,以及一个格式如上的 CSV,它提供该区域的记录;所以上面的内容将在/example.com/文件夹中,因此我们有2条A记录example.com,2条test.example.com和www.example.com的一条CName指向example.com。
locals {
instances = csvdecode(file("myDnsRecords.csv"))
}
resource aws_route53_zone zone {
name = var.domainname
provider = aws
}
resource aws_route53_record route53_entry {
for_each = {for inst in local.instances : inst.myId => inst}
name = "${each.value.RecordName}${each.value.RecordName == "" ? "" : "."}${var.domainname}"
type = each.value.Type
zone_id = aws_route53_zone.zone.zone_id
ttl = 3600
records = [each.value.Value]
}
不过,我不想要 myId 列;因为那不会增加价值/与记录没有真正的关系;因此,如果我们要在 CSV 的早期删除/插入一条记录并对以下记录重新编号,这将导致需要对实际上没有更改的记录进行大量更改,只是因为它们的相关“索引”已更改。
我也不希望那些使用这些 CSV 的人必须手动管理这些字段;即我可以提供另一列并要求他们按以下方式填充它......但这是要求人为错误并增加复杂性:
| myId | RecordName | Type | Value |
|---|---|---|---|
| 1 | A | 1.2.3.4 | |
| 2 | A | 2.3.4.5 | |
| test1 | test | A | 3.4.5.6 |
| test2 | test | A | 4.5.6.7 |
| www1 | www | cname | example.com |
问题
有没有一种方法可以使用 for_each 循环和 CSV 数据,如下所示,同时解决唯一约束?
| RecordName | Type | Value |
|---|---|---|
| A | 1.2.3.4 | |
| A | 2.3.4.5 | |
| test | A | 3.4.5.6 |
| test | A | 4.5.6.7 |
| www | cname | example.com |
【问题讨论】:
标签: terraform terraform-provider-aws terragrunt