如何在 terraform 的 AWS 策略中插入变量

Mam*_*mun 3 amazon-web-services terraform aws-policies

我在 terraform 中为 AWS 资源定义了一个策略,如下所示:


device-status-policy = <<EOF
{"Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:Connect", "Resource": "arn:aws:iot:us-west-2:foobaraccountid:client/device-status-qa*" }, { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Receive", "iot:Subscribe" ] }
   EOF

Run Code Online (Sandbox Code Playgroud)

我希望它的 Resource 部分是一个变量,就像这样(伪代码)

device-status-policy = <<EOF
{"Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:Connect", "Resource": "$SOMEVAR/device-status-qa*" }, { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Receive", "iot:Subscribe" ] }
   EOF
Run Code Online (Sandbox Code Playgroud)

任何帮助表示赞赏。谢谢。

mar*_*ber 5

所以我会选择的唯一合理的选择是:

使用以下内容创建一个文件,例如 policy.tpl:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "${SOMEVAR}/device-status-qa*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish",
        "iot:Receive",
        "iot:Subscribe"
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

该策略文件具有您需要的变量。

然后您只需引用它并按以下方式传递变量:

device-status-policy = templatefile("file.tpl", { SOMEVAR = var.your_terraform_variable})
Run Code Online (Sandbox Code Playgroud)

希望有帮助


Mar*_*ins 5

使用${ ... }语法的字符串插值是对文字 JSON 字符串的最小更改,但如果插入的字符串包含 JSON 解析器可能会误解的反斜杠和引号,则它冒着生成正确 JSON 语法的挑战的风险。

Terraform 的jsonencode功能可以是一个很好的折衷方案,因为 Terraform 具有与 JSON 非常相似的对象语法,因此能够快速了解​​它生成的 JSON 结构被保留,同时允许任意 Terraform 表达式,其结果将被自动编码使用正确的 JSON 语法:

  device-status-policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": "iot:Connect",
        "Resource": "${SOMEVAR}/device-status-qa*"
      },
      {
        "Effect": "Allow",
        "Action": [ "iot:Publish", "iot:Receive", "iot:Subscribe" ]
      }
    ]
  })
Run Code Online (Sandbox Code Playgroud)

请注意,上面使用的是 Terraform 语言对象语法的变体形式,它使用冒号而不是等号;两者都是有效的,并且在此处使用冒号有助于输入类似于 JSON,因此可以更轻松地调整您已经编写的 JSON(就像我在这里所做的那样)而无需大量重写。

但是,"${SOMEVAR}/device-status-qa*"Terraform将序列理解为带引号的模板表达式而不是文字字符串,SOMEVAR因此在使用 JSON 语法序列化整个结果字符串之前,它将评估结果并将其包含在Resource值中。尽管在这种特殊情况下似乎不太可能,但如果结果是包含 a 的字符串,那么 JSON 编码将自动对其进行转义,以确保结果是有效的语法。SOMEVAR"\"

对于其中它提高可读性因子出来到一个单独的文件大的数据结构,所述templatefile功能文件包括的一些实例中调用jsonencode从一个外部模板中也具有类似的结果。