循环遍历列表映射以在一个资源块中为多个域创建 DNS 记录
Posted
技术标签:
【中文标题】循环遍历列表映射以在一个资源块中为多个域创建 DNS 记录【英文标题】:Loop through map of lists to create DNS records for multiple domains in one resource block 【发布时间】:2021-12-23 19:13:49 【问题描述】:我有几个域,我想创建尽可能多的 DRY 子域。这是原始结构:
variable "domain1"
type = list(string)
default = ["www", "www2"]
variable "domain2"
type = list(string)
default = ["www3", "www1"]
resource "aws_route53_record" "domain1"
for_each = toset(var.domain1)
type = "A"
name = "$each.key.domain1.com"
zone_id = ""
resource "aws_route53_record" "domain2"
for_each = toset(var.domain2)
type = "A"
name = "$each.key.domain2.com"
zone_id = ""
我想组合成一个变量和一个资源块:
variable "subdomains"
type = map(list(string))
default =
"domain1.com" = ["www", "www2"]
"domain2.com" = ["www3", "www1"]
resource "aws_route53_record" "domain1"
for_each = var.subdomains // make magic happen here...
type = "A"
name = "$each.subdomain_part.$each.domain_part" // ...and here
zone_id = ""
有没有办法做到这一点?
【问题讨论】:
如果您有两个不同的域domain1.com
和domain2.com
,我假设它们也有两个不同的zone_id
,对吧?因此,我认为要概括这一点,您需要某种方式来了解或动态生成区域 ID,以实现完整的工作解决方案。 ??????
不过,这很容易。只是使用相同变量循环通过 aws_route53_zone 数据资源
【参考方案1】:
您可以按如下方式展平您的var.subdomains
:
locals
subdomains_flat = flatten([for domain, subdomains in var.subdomains:
[ for subdomain in subdomains:
domain_part = domain
subdomain_part = subdomain
]
])
然后:
resource "aws_route53_record" "domain1"
for_each = for idx, val in local.subdomains_flat: idx => val
type = "A"
name = "$each.value.subdomain_part.$each.value.domain_part"
zone_id = ""
【讨论】:
这行得通,但会造成相当混乱的状态,因为索引用于资源名称。是否可以对其进行调整,以便在资源名称中使用子域? @aardbol 索引必须是唯一的,不能保证子域将是唯一的,而不是 subdomains_flat 数组,您可以构建适合您需要的自定义地图以获得更好看的索引【参考方案2】:跟进the comment关于混乱状态的信息,我不会说混乱......但肯定有一些缺点,该答案中的索引是数字,计划显示资源结束:
# aws_route53_record.domain1["0"] will be created
+ resource "aws_route53_record" "domain1"
# aws_route53_record.domain1["1"] will be created
+ resource "aws_route53_record" "domain1"
当我们在列表中添加或删除子域时,这可能会产生问题,顺序可能会发生变化,这将导致资源被破坏和重新创建,这对 route53 记录不理想...
这是另一种在资源名称中创建不同索引的方法。
我们仍然使用 flatten 来提取子域,但在这种情况下,我会立即连接,该局部变量已准备好供 aws_route53_record
资源使用。
provider "aws"
region = "us-east-2"
variable "subdomains"
type = map(list(string))
default =
"domain1.com" = ["www", "www2"]
"domain2.com" = ["www3", "www1"]
locals
records = flatten([for d, subs in var.subdomains: [for s in subs: "$s.$d"]])
resource "aws_route53_record" "domain1"
for_each = toset(local.records)
type = "A"
name = each.value
zone_id = "us-east-1"
一个 terraform 计划如下所示:
Terraform will perform the following actions:
# aws_route53_record.domain1["www.domain1.com"] will be created
+ resource "aws_route53_record" "domain1"
+ allow_overwrite = (known after apply)
+ fqdn = (known after apply)
+ id = (known after apply)
+ name = "www.domain1.com"
+ type = "A"
+ zone_id = "us-east-1"
# aws_route53_record.domain1["www1.domain2.com"] will be created
+ resource "aws_route53_record" "domain1"
+ allow_overwrite = (known after apply)
+ fqdn = (known after apply)
+ id = (known after apply)
+ name = "www1.domain2.com"
+ type = "A"
+ zone_id = "us-east-1"
...
【讨论】:
以上是关于循环遍历列表映射以在一个资源块中为多个域创建 DNS 记录的主要内容,如果未能解决你的问题,请参考以下文章
循环遍历 pandas 数据框列中的列表元素以在新列中返回列表