用于 aws 策略列表的 terraform 模板文件

Posted

技术标签:

【中文标题】用于 aws 策略列表的 terraform 模板文件【英文标题】:terraform templatefile for aws policies list 【发布时间】: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 【参考方案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 策略放入一个文件夹中的一个文件中,并尝试从每个不同的文件中创建一个模板文件。

以上是关于用于 aws 策略列表的 terraform 模板文件的主要内容,如果未能解决你的问题,请参考以下文章

用于管理 AWS 无服务器基础设施的 Terraform 或 cloudformation [关闭]

Terraform:将 AWS 托管策略附加到角色的正确方法?

如何使用 Terraform 创建没有代入角色策略的 AWS IAM 角色?

防止 terraform 函数“模板文件”输出 heredoc

Terraform 依赖于 aws_iam_policy

Terraform Splat 表达式给出“无效的模板插值”