terraform 获取 yaml 值
terrraform get yaml values
我需要从 yaml 片段中获取值到 1. Route53 区域我需要 apex_nme 作为区域名称和 2. 记录作为 Route53 记录添加到特定区域.我不知道该怎么做。非常感谢任何帮助。
resource "aws_route53_zone" "this" {
for_each = {
for apex in var.source_domains : apex => {
name = apex.name
}
}
}
resource "aws_route53_record" "this" {
for_each = {
for records in var.source_domains : records => {
zone_id = aws_route53_zone.this[each.key].zone_id
name = subdomains.records
type = "A"
records = ["192.168.0.1"]
}
}
}
source_domains:
- apax_name: elastic2ls.com
records:
- elastic2ls.com
- www.elastic2ls.com
- apax_name: elastic2ls.ch
records:
- elastic2ls.ch
- www.elastic2ls.ch
- image.elastic2ls.ch
- m.elastic2ls.ch
- static.elastic2ls.ch
你的问题好像是关于 YAML 解析的,但我怀疑你真的在问如何为 aws_route53_record.this
编写 for_each
表达式来创建所有记录域。
为了完整起见,我会注意到您可以通过使调用模块使用如下表达式定义该变量来从 YAML 中填充 var.source_domains
:
module "example" {
source = "../modules/example"
source_domains = yamldecode(file("${path.module}/example.yaml")).source_domains
# ...
}
然后在模块内部,我首先声明该模块具有合适的类型约束,以明确我们期望的数据结构,如下所示:
variable "source_domains" {
type = set(object({
apax_name = string
records = set(string)
}))
}
这里我将顶层结构和嵌套记录都定义为 set 类型,因为我们将要使用它们的方式意味着顺序并不重要我们希望它们都是独一无二的。
所有这些都准备就绪后,我们就可以开始编写资源定义了。让我们从区域开始,这是更简单的情况,因为 var.source_domains
已经满足了我们要声明的每个资源实例有一个元素的主要要求:
resource "aws_route53_zone" "example" {
for_each = {
for d in var.source_domains : d.apax_name => d
}
name = each.value.apax_name
}
使用您共享的示例 YAML 输入,此块将声明此资源的两个实例:
aws_route53_zone.example["elastic2ls.com"]
aws_route53_zone.example["elastic2ls.ch"]
aws_route53_record
声明有点棘手,因为我们需要将输入数据结构投影到一个新结构中,其中我们要声明的每条记录都有一个元素,而不是每个 一个元素区域。 Flattening nested data structures for for_each
is a common use for the flatten
function,我们可以调整文档中的网络和子网示例,以改为使用区域和记录:
locals {
zone_records = flatten([
for d in var.source_domains : [
for r in d.records : {
zone_name = d.apax_name
zone_id = aws_route53_zone.example[d.apax_name].id
record = r
}
]
])
}
此 local value 正在构建一个对象列表,其中每个对象代表一对有效的区域和记录。这意味着元素的数量与我们需要声明的 aws_route53_record
个实例的数量相匹配,因此我们可以在 for_each
:
中使用这个数据结构
resource "aws_route53_record" "example" {
for_each = {
for zr in local.zone_records : zr.record => zr
}
zone_id = each.value.zone_id
name = each.value.record
# ...
}
这个例子与典型的 flatten
/for_each
模式有点不同,因为你所有的记录名称都已经嵌入了区域名称,所以我们不需要通常的表达式生成具有多个部分的复合唯一键,如文档示例中的 "${subnet.network_key}.${subnet.subnet_key}"
。在这种情况下,仅记录名称就足以成为所有对中的唯一键。
然后,再次基于您的 YAML 示例,将声明以下实例:
aws_route53_record.example["elastic2ls.com"]
aws_route53_record.example["www.elastic2ls.com"]
aws_route53_record.example["elastic2ls.ch"]
aws_route53_record.example["www.elastic2ls.ch"]
aws_route53_record.example["image.elastic2ls.ch"]
aws_route53_record.example["m.elastic2ls.ch"]
aws_route53_record.example["static.elastic2ls.ch"]
我需要从 yaml 片段中获取值到 1. Route53 区域我需要 apex_nme 作为区域名称和 2. 记录作为 Route53 记录添加到特定区域.我不知道该怎么做。非常感谢任何帮助。
resource "aws_route53_zone" "this" {
for_each = {
for apex in var.source_domains : apex => {
name = apex.name
}
}
}
resource "aws_route53_record" "this" {
for_each = {
for records in var.source_domains : records => {
zone_id = aws_route53_zone.this[each.key].zone_id
name = subdomains.records
type = "A"
records = ["192.168.0.1"]
}
}
}
source_domains:
- apax_name: elastic2ls.com
records:
- elastic2ls.com
- www.elastic2ls.com
- apax_name: elastic2ls.ch
records:
- elastic2ls.ch
- www.elastic2ls.ch
- image.elastic2ls.ch
- m.elastic2ls.ch
- static.elastic2ls.ch
你的问题好像是关于 YAML 解析的,但我怀疑你真的在问如何为 aws_route53_record.this
编写 for_each
表达式来创建所有记录域。
为了完整起见,我会注意到您可以通过使调用模块使用如下表达式定义该变量来从 YAML 中填充 var.source_domains
:
module "example" {
source = "../modules/example"
source_domains = yamldecode(file("${path.module}/example.yaml")).source_domains
# ...
}
然后在模块内部,我首先声明该模块具有合适的类型约束,以明确我们期望的数据结构,如下所示:
variable "source_domains" {
type = set(object({
apax_name = string
records = set(string)
}))
}
这里我将顶层结构和嵌套记录都定义为 set 类型,因为我们将要使用它们的方式意味着顺序并不重要我们希望它们都是独一无二的。
所有这些都准备就绪后,我们就可以开始编写资源定义了。让我们从区域开始,这是更简单的情况,因为 var.source_domains
已经满足了我们要声明的每个资源实例有一个元素的主要要求:
resource "aws_route53_zone" "example" {
for_each = {
for d in var.source_domains : d.apax_name => d
}
name = each.value.apax_name
}
使用您共享的示例 YAML 输入,此块将声明此资源的两个实例:
aws_route53_zone.example["elastic2ls.com"]
aws_route53_zone.example["elastic2ls.ch"]
aws_route53_record
声明有点棘手,因为我们需要将输入数据结构投影到一个新结构中,其中我们要声明的每条记录都有一个元素,而不是每个 一个元素区域。 Flattening nested data structures for for_each
is a common use for the flatten
function,我们可以调整文档中的网络和子网示例,以改为使用区域和记录:
locals {
zone_records = flatten([
for d in var.source_domains : [
for r in d.records : {
zone_name = d.apax_name
zone_id = aws_route53_zone.example[d.apax_name].id
record = r
}
]
])
}
此 local value 正在构建一个对象列表,其中每个对象代表一对有效的区域和记录。这意味着元素的数量与我们需要声明的 aws_route53_record
个实例的数量相匹配,因此我们可以在 for_each
:
resource "aws_route53_record" "example" {
for_each = {
for zr in local.zone_records : zr.record => zr
}
zone_id = each.value.zone_id
name = each.value.record
# ...
}
这个例子与典型的 flatten
/for_each
模式有点不同,因为你所有的记录名称都已经嵌入了区域名称,所以我们不需要通常的表达式生成具有多个部分的复合唯一键,如文档示例中的 "${subnet.network_key}.${subnet.subnet_key}"
。在这种情况下,仅记录名称就足以成为所有对中的唯一键。
然后,再次基于您的 YAML 示例,将声明以下实例:
aws_route53_record.example["elastic2ls.com"]
aws_route53_record.example["www.elastic2ls.com"]
aws_route53_record.example["elastic2ls.ch"]
aws_route53_record.example["www.elastic2ls.ch"]
aws_route53_record.example["image.elastic2ls.ch"]
aws_route53_record.example["m.elastic2ls.ch"]
aws_route53_record.example["static.elastic2ls.ch"]