【问题标题】:terraform templatefile for aws policies list用于 aws 策略列表的 terraform 模板文件
【发布时间】:2021-09-23 17:10:40
【问题描述】:

我的 main.tf 下面有一个示例。 出于某种原因,它强制模板变量上的双引号在我的模板文件中环绕,而来自其他来源的示例使用下面没有引号环绕:

%{ for i in split(",",mylist) ~}
Here's a value: ${i}
%{ endfor }

我的语法在文件上没有显示错误,但在运行时会出错 "%{ for addr in split(",",source_vpcs) ~} ${addr} %{ endfor ~}"

我收到此错误: 无效的功能 争论; “str”参数的值无效:需要字符串..

如何正确使用列表? source_vpcs = ["vpc1212","vpc21"]

#i am trying to pass this from the main.tf to pass into aws_vpc_endpoint resource and into its policy attribute.

    policy = templatefile("../templates/access_polices.tmpl", 
                   {
                     s3env = "dev"
                     account_num = "8888888"
                     source_vpcs = local.source_vpcs
                   }
               )

这是一个 tmpl 文件 ####新内容###

${jsonencode(
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "xx",
            "Effect": "Deny",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
              "*"
              ],
            "Condition": {
            "StringNotEquals": {
              "aws:SourceVpc": "${source_vpcs}",
              "s3:ResourceAccount": "${account_number}"
              }
        }
        },
        
    ]
}
)}

这是我想要实现的示例输出

"Condition": {
  "StringNotEquals": {
    "aws:SourceVpc": 
    [
      "vpc-888888888f",
      "vpc-999999999f"

    ]
    ,
    "s3:ResourceAccount":
    [
        888888888
     ]
  }

【问题讨论】:

  • Terraform 每两秒发布一次新版本 :D,如果您可以提供您使用的 terraform 版本,可以帮助其他人回答您的问题。
  • 我还在 tmpl 文件上尝试了 jsonencode 函数 ${jsonencode(policy)} 并且我能够做一个 terraform 计划,好像它看起来不错但是当我应用它时它并没有看到它有效的政策。我已经检查了政策是否正确。
  • 嗨 Vidura,我正在使用 Terraform v0.13.4

标签: amazon-web-services terraform-provider-aws terraform-template-file


【解决方案1】:

您将 source_vpcs 作为列表传入,然后尝试在 "," 上拆分列表。

由于您已经传入了一个列表,因此您不需要进行拆分;它已经存在于不同的元素中。因此,只需摆脱 split 并尝试以下操作:

"%{ for addr in source_vpcs ~} ${addr} %{ endfor ~}"

编辑: 这个最小的例子对我来说很好,没有错误。

template.txt

%{ for v in mylist ~}
Here's a value: ${v}
%{ endfor }

ma​​in.tf

resource "local_file" "template_test" {
  content     = templatefile("./template.txt", {
    mylist = [
      "value 1",
      "value 2"
    ]
  })
  filename = "./output.txt"
}

output.txt

Here's a value: value 1
Here's a value: value 2

编辑 2: 我不知道你想用这个 JSON 做什么,你真的应该考虑将aws_iam_policy_document data source 用于这样的 IAM 策略,但这里是创建 JSON 字符串的方法:

locals {
  source_vpcs = [
      "vpc-888888888f",
      "vpc-999999999f"
  ]
  account_number = 888888888

  jsonstring = jsonencode({
    Version = "2012-10-17",
    Statement = [
        {
            Sid = "xx",
            Effect = "Deny",
            Action = [
                "s3:GetObject"
            ],
            Resource = [
                "*"
            ],
            Condition = {
                StringNotEquals = {
                  "aws:SourceVpc" = local.source_vpcs,
                  "s3:ResourceAccount" = local.account_number
                }
            }
        }
    ]
  })
}

output "jsonstring" {
  value = local.jsonstring
}

现在您可以在任何您想使用该字符串的地方使用local.jsonstring(例如在 IAM 策略中)。如果你真的想把它输出到一个文件中,你可以添加:

resource "local_file" "jsonfile" {
  content     = local.jsonstring
  filename = "./policy.json"
}

现在policy.json 将拥有您的 JSON 内容。

编辑 3: 试试这个:

templatedir/policytemplate.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "xx",
            "Effect": "Deny",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
              "*"
              ],
            "Condition": {
            "StringNotEquals": {
              "aws:SourceVpc": ${jsonencode(vpc_ids)},
              "s3:ResourceAccount": "${account_number}"
              }
        }
        },
        
    ]
}

main.tf

locals {
  jsonpolicy = templatefile("./templatedir/policytemplate.json", {
    vpc_ids = [
      "vpc_1",
      "vpc_2"
    ]
    account_number = 888888
  })
}

output "jsonpolicy" {
  value = local.jsonpolicy
}

【讨论】:

  • 我先做完再拆分。它没有用。
  • 检查我编辑的答案以获得最小的工作示例。照原样确保它正常工作,然后添加模板的其他组件以查看问题出现的位置。
  • 感谢您的帮助,但在输出文本文件时我能够复制您的步骤,但我的问题在于使用 json 文件。让我编辑我的主要问题(我说“新内容”以提供我想要实现的示例模板文件。我使用这个模板文件函数,所以我可以将它放在 aws_vpc_endpoint 资源的策略属性上
  • 你在用这个输出的 JSON 文件做什么?如果您将其读回 Terraform 以使用它创建 IAM 策略,则有更简单的方法可以完成此操作,而根本无需使用外部文件。
  • 我明白了。我从来没有尝试过。我不使用 aws_iam_policy_document 数据源的原因,也不是您刚刚更新的那种方式,因为我有大约 16 个端点,每个端点都有不同的策略,有些可能有额外的语句。所以我已经做的是将每个 json 策略放入一个文件夹中的一个文件中,并尝试从每个不同的文件中创建一个模板文件。
猜你喜欢
  • 2020-08-12
  • 2019-02-06
  • 1970-01-01
  • 1970-01-01
  • 2022-07-20
  • 2021-06-10
  • 2021-09-14
  • 2020-05-14
  • 2020-09-17
相关资源
最近更新 更多