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

How to insert a variable inside an AWS policy in terraform

我在 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

我希望它的 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

感谢任何帮助。谢谢

$SOMEVAR 更改为 ${SOMEVAR}

请查看Terraform string interpolation syntax

此外,我强烈建议使用数据源 aws_iam_policy_document 来定义 IAM 策略,而不是此处的文档。

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

创建文件,例如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"
      ]
    }
  ]
}

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

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

device-status-policy = templatefile("file.tpl", { SOMEVAR = var.your_terraform_variable})

希望对您有所帮助

使用 ${ ... } 语法的字符串插值是文字 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" ]
      }
    ]
  })

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

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

对于较大的数据结构,将它们分解到单独的文件中可以提高可读性,the templatefile function documentation includes some examples of calling jsonencode from inside an external template 也有类似的结果。