使用terraform yamldecode访问多级元素
我有一个yaml文件(也在azure devops管道中使用,因此需要采用这种格式),其中包含一些我想直接从terraform模块访问的设置 该文件看起来像:使用terraform yamldecode访问多级元素,yaml,terraform,Yaml,Terraform,我有一个yaml文件(也在azure devops管道中使用,因此需要采用这种格式),其中包含一些我想直接从terraform模块访问的设置 该文件看起来像: variables: - name: tenantsList value: tenanta,tenantb - name: unitName value: canary 我希望有一个这样的模块来访问设置,但我看不到如何进入底层: locals { settings = yamldecode(file("../
variables:
- name: tenantsList
value: tenanta,tenantb
- name: unitName
value: canary
我希望有一个这样的模块来访问设置,但我看不到如何进入底层:
locals {
settings = yamldecode(file("../settings.yml"))
}
module "infra" {
source = "../../../infra/terraform/"
unitname = local.settings.variables.unitName
}
但是地形平面图
错误如下:
Error: Unsupported attribute
on canary.tf line 16, in module "infra":
16: unitname = local.settings.variables.unitName
|----------------
| local.settings.variables is tuple with 2 elements
This value does not have any attributes.
看起来这很困难的主要原因是因为这个YAML文件在逻辑上表示一个映射,但在物理上表示为一个映射的YAML列表 当从这样一个单独的文件中读取数据时,我喜欢编写一个显式表达式来规范化它,并有选择地转换它,以便在Terraform模块的其余部分中更方便地使用。在这种情况下,将
变量
作为地图似乎是地形值最有用的表示形式,因此我们可以编写如下转换表达式:
locals {
raw_settings = yamldecode(file("${path.module}/../settings.yml"))
settings = {
variables = tomap({
for v in local.raw_settings.variables : v.name => v.value
})
}
}
上面使用a将贴图列表投影到单个贴图中,使用名称
值作为键
将地图列表转换为单个地图后,您可以按照最初尝试的方式访问它:
module "infra" {
source = "../../../infra/terraform/"
unitname = local.settings.variables.unitName
}
如果要将变换后的local.settings
值输出为YAML,它看起来会像这样,这就是现在可以直接访问地图元素的原因:
variables:
tenantsList: tenanta,tenantb
unitName: canary
只有当输入中的所有name
字符串都是唯一的时,这才有效,因为否则每个元素都不会有唯一的映射键
(像这样编写一个规范化表达式也可以作为YAML文件形状的隐式验证:如果
变量不是一个列表,或者如果值不是所有的类型,那么Terraform将在计算该表达式时引发一个类型错误。即使不需要任何转换,我也喜欢写出这种类型的表达式。)表达式,因为它可以作为YAML文件的预期形状的文档,而不必在其余配置中研究对它的所有引用。)您的YAML变量variables
是一个列表,而不是一个映射,因此您需要更改数据结构或以列表的形式访问它。您的意思是unitname=element(local.settings.variables,1)
吗?因为我尝试过,得到了:给定的值不适合子模块变量“unitname”在..\\..\infra\terraform\variables.tf:7,1-27:需要字符串。
因此,它似乎没有成功获取值,但很难看到它获取了什么,这将为您提供一个{name=unitName,value=canary}的映射如果你想要值<代码>加那利< /代码>,那么你会想使用<代码>本地设置。变量1。值。但是这似乎是一种脆弱的访问数据的方式。我会考虑将YAML输入更改为<代码>变量=“TunANSISLIST”=“TANTANA,TANANTB”,“UnITNED”=“金丝雀”}。
这样您就可以通过local.settings.variables.unitName
访问它,这更清晰。