带迭代的 Terraform 模板 jsonencoding
Terraform template jsonencoding with iterate
我正在寻找此模板的解决方案以获取正确的 JSON 文件。
正如您在这些部分中看到的那样,aws:RequestTag/***
末尾缺少逗号。如果我在模板中使用逗号,那么我将在最后一个字符串的末尾有一个不必要的逗号。
我不知道 ${jsonencode()}
应该有帮助,但我仍然没有意识到它如何与 %{ for key in key_tag ~}
一起使用。
如有任何帮助,我将不胜感激。
地形:
resource "local_file" "enforcetags" {
content = templatefile("${path.module}/enforcetags.tpl",
{
key_tag = ["development_prod", "production_prod", "rnd_prod"]
}
)
filename = "./enforce_tags.json"
}
模板:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": ${jsonencode([for key in key_tag : "${key}"])}
},
"StringEqualsIfExists": {
%{ for key in key_tag ~}
"aws:RequestTag/${key}": ${jsonencode([for key in key_tag : "${key}"])}
%{ endfor ~}
}
}
}
]
}
输出:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": ["development_prod","production_prod","rnd_prod"]
},
"StringEqualsIfExists": {
"aws:RequestTag/development_prod": ["development_prod","production_prod","rnd_prod"]
"aws:RequestTag/production_prod": ["development_prod","production_prod","rnd_prod"]
"aws:RequestTag/rnd_prod": ["development_prod","production_prod","rnd_prod"]
}
}
}
]
}
要在末尾加一个逗号,除了最后一个字符串应该是:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": ${jsonencode([for key in key_tag : "${key}"])}
},
"StringEqualsIfExists": ${jsonencode(
{for key in key_tag: "aws:RequestTag/${key}" => key_tag})}
}
}
]
}
在这里,您似乎 运行 遇到了尝试使用字符串连接生成有效 JSON 的典型挑战,这就是模板插值的有效方式。这个问题很常见,在 templatefile
文档页面中有专门的部分:Generating JSON or YAML from a template.
您可以通过遵循该部分中的建议并生成 整个 JSON 数据结构 和 jsonencode
来避免这种摩擦,而不仅仅是它的一些子部分就像您在共享的示例中所做的那样。您可以根据需要使用 Terraform 的普通表达式运算符生成动态部分。例如:
${jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "VisualEditor0"
Effect = "Allow"
Action = "ec2:*"
Resource = "*"
Condition = {
"ForAllValues:StringEquals" = {
"aws:TagKeys" = key_tag
},
"StringEqualsIfExists": {
for key in key_tag : "aws:RequestTag/${key}" => key_tag
}
}
}
],
})}
通过这种方法,您可以使用 Terraform 语法而不是 JSON 语法来定义数据结构,并让 jsonencode
负责将其编码为等效的有效 JSON。 jsonencode
保证始终生成有效的 JSON,包括所有预期位置的逗号,并且 Terraform 的对象语法无论如何不需要属性定义之间的逗号,因此您无需担心编写它们你自己。
(我还在上面稍微简化了你的 for
表达式,尽管这与你的问题没有直接关系。特别是,如果 key_tag
已经是一个序列类型那么 [for key in key_tag : "${key}"]
与直接写 key_tag
一样,因为那里没有发生实际的转换。)
我正在寻找此模板的解决方案以获取正确的 JSON 文件。
正如您在这些部分中看到的那样,aws:RequestTag/***
末尾缺少逗号。如果我在模板中使用逗号,那么我将在最后一个字符串的末尾有一个不必要的逗号。
我不知道 ${jsonencode()}
应该有帮助,但我仍然没有意识到它如何与 %{ for key in key_tag ~}
一起使用。
如有任何帮助,我将不胜感激。
地形:
resource "local_file" "enforcetags" {
content = templatefile("${path.module}/enforcetags.tpl",
{
key_tag = ["development_prod", "production_prod", "rnd_prod"]
}
)
filename = "./enforce_tags.json"
}
模板:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": ${jsonencode([for key in key_tag : "${key}"])}
},
"StringEqualsIfExists": {
%{ for key in key_tag ~}
"aws:RequestTag/${key}": ${jsonencode([for key in key_tag : "${key}"])}
%{ endfor ~}
}
}
}
]
}
输出:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": ["development_prod","production_prod","rnd_prod"]
},
"StringEqualsIfExists": {
"aws:RequestTag/development_prod": ["development_prod","production_prod","rnd_prod"]
"aws:RequestTag/production_prod": ["development_prod","production_prod","rnd_prod"]
"aws:RequestTag/rnd_prod": ["development_prod","production_prod","rnd_prod"]
}
}
}
]
}
要在末尾加一个逗号,除了最后一个字符串应该是:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": ${jsonencode([for key in key_tag : "${key}"])}
},
"StringEqualsIfExists": ${jsonencode(
{for key in key_tag: "aws:RequestTag/${key}" => key_tag})}
}
}
]
}
在这里,您似乎 运行 遇到了尝试使用字符串连接生成有效 JSON 的典型挑战,这就是模板插值的有效方式。这个问题很常见,在 templatefile
文档页面中有专门的部分:Generating JSON or YAML from a template.
您可以通过遵循该部分中的建议并生成 整个 JSON 数据结构 和 jsonencode
来避免这种摩擦,而不仅仅是它的一些子部分就像您在共享的示例中所做的那样。您可以根据需要使用 Terraform 的普通表达式运算符生成动态部分。例如:
${jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "VisualEditor0"
Effect = "Allow"
Action = "ec2:*"
Resource = "*"
Condition = {
"ForAllValues:StringEquals" = {
"aws:TagKeys" = key_tag
},
"StringEqualsIfExists": {
for key in key_tag : "aws:RequestTag/${key}" => key_tag
}
}
}
],
})}
通过这种方法,您可以使用 Terraform 语法而不是 JSON 语法来定义数据结构,并让 jsonencode
负责将其编码为等效的有效 JSON。 jsonencode
保证始终生成有效的 JSON,包括所有预期位置的逗号,并且 Terraform 的对象语法无论如何不需要属性定义之间的逗号,因此您无需担心编写它们你自己。
(我还在上面稍微简化了你的 for
表达式,尽管这与你的问题没有直接关系。特别是,如果 key_tag
已经是一个序列类型那么 [for key in key_tag : "${key}"]
与直接写 key_tag
一样,因为那里没有发生实际的转换。)