您如何使用 Terraform 动态创建具有可变数量资源块的 AWS IAM 策略文档?
How do you dynamically create an AWS IAM policy document with a variable number of resource blocks using terraform?
在我当前的 Terraform 配置中,我使用静态 JSON 文件并使用文件功能导入到 Terraform 中以创建 AWS IAM 策略。
地形代码:
resource "aws_iam_policy" "example" {
policy = "${file("policy.json")}"
}
JSON 文件 (policy.json) 中的 AWS IAM 策略定义:
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-2",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::777788889999:root"
]
},
"Action": [
"kms:Decrypt"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::444455556666:root"
]
},
"Action": [
"kms:Decrypt"
],
"Resource": "*"
}
]
}
我的目标是使用存储在 terraform 变量中的帐号列表,并使用它在 terraform 中动态构建 aws_iam_policy 资源。我的第一个想法是尝试使用 terraform jsonencode 函数。但是,看起来可能有一种方法可以使用新的 terraform 动态表达式 foreach 循环来实现这一点。
症结似乎在于在 IAM 策略中附加了可变数量的资源块。
伪代码如下:
var account_number_list = ["123","456","789"]
policy = {"Statement":[]}
for each account_number in account_number_list:
policy["Statement"].append(policy block with account_number var reference)
感谢任何帮助。
最好的,
安德鲁
aws 的 aws_iam_policy_document
数据源为您提供了一种创建 json 策略的方法,无需从文件或多行字符串导入原始 json。
因为您全部在 terraform 中定义策略语句,所以它的好处是让您可以在主体数组上使用 looping/filtering。
在您的示例中,您可以执行以下操作:
data "aws_iam_policy_document" "example_doc" {
statement {
sid = "Enable IAM User Permissions"
effect = "Allow"
actions = [
"kms:*"
]
resources = [
"*"
]
principals {
type = "AWS"
identifiers = [
for account_id in account_number_list:
account_id
]
}
}
statement {
...other statements...
}
}
resource "aws_iam_policy" "example" {
// For terraform >=0.12
policy = data.aws_iam_policy_document.example_doc.json
// For terraform <0.12
policy = "${data.aws_iam_policy_document.example_doc.json}"
}
这很棒,是一个可以坚持下去的好模式。不幸的是,我 运行 遇到了一个问题,它违反了配额限制:
担任角色策略:LimitExceeded:不能超过 ACLSizePerRole 的配额:2048
您可以请求增加此配额大小,但据说最大值为 4098。我们拥有的每个 AWS 帐户都需要我尝试创建的代入角色策略,因此我们最终也会达到该限制。
不幸的是,您可以在代入角色策略的 arn 中使用通配符,但您可以使用“*”,我认为这样做风险更大。
第一个选项:
如果您不想在 aws_iam_policy_document
中重建策略,您可以使用 templatefile
请参阅 https://www.terraform.io/docs/language/functions/templatefile.html
resource "aws_iam_policy" "example" {
policy = templatefile("policy.json",{account_number_list = ["123","456","789"]})
}
...
%{ for account in account_number_list ~}
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${account}:root"
},
"Action": "kms:*",
"Resource": "*"
},
%{ endfor ~}
...
第二个选项:
AWS's IAM policy document syntax allows for replacement of policy
variables within a statement using ${...}-style notation, which
conflicts with Terraform's interpolation syntax. In order to use AWS
policy variables with this data source, use &{...} notation for
interpolations that should be processed by AWS rather than by
Terraform.
...
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::&{aws:userid}:root"
},
"Action": "kms:*",
"Resource": "*"
},
点赞:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document
在我当前的 Terraform 配置中,我使用静态 JSON 文件并使用文件功能导入到 Terraform 中以创建 AWS IAM 策略。
地形代码:
resource "aws_iam_policy" "example" {
policy = "${file("policy.json")}"
}
JSON 文件 (policy.json) 中的 AWS IAM 策略定义:
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-2",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::777788889999:root"
]
},
"Action": [
"kms:Decrypt"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::444455556666:root"
]
},
"Action": [
"kms:Decrypt"
],
"Resource": "*"
}
]
}
我的目标是使用存储在 terraform 变量中的帐号列表,并使用它在 terraform 中动态构建 aws_iam_policy 资源。我的第一个想法是尝试使用 terraform jsonencode 函数。但是,看起来可能有一种方法可以使用新的 terraform 动态表达式 foreach 循环来实现这一点。
症结似乎在于在 IAM 策略中附加了可变数量的资源块。
伪代码如下:
var account_number_list = ["123","456","789"]
policy = {"Statement":[]}
for each account_number in account_number_list:
policy["Statement"].append(policy block with account_number var reference)
感谢任何帮助。
最好的, 安德鲁
aws 的 aws_iam_policy_document
数据源为您提供了一种创建 json 策略的方法,无需从文件或多行字符串导入原始 json。
因为您全部在 terraform 中定义策略语句,所以它的好处是让您可以在主体数组上使用 looping/filtering。
在您的示例中,您可以执行以下操作:
data "aws_iam_policy_document" "example_doc" {
statement {
sid = "Enable IAM User Permissions"
effect = "Allow"
actions = [
"kms:*"
]
resources = [
"*"
]
principals {
type = "AWS"
identifiers = [
for account_id in account_number_list:
account_id
]
}
}
statement {
...other statements...
}
}
resource "aws_iam_policy" "example" {
// For terraform >=0.12
policy = data.aws_iam_policy_document.example_doc.json
// For terraform <0.12
policy = "${data.aws_iam_policy_document.example_doc.json}"
}
这很棒,是一个可以坚持下去的好模式。不幸的是,我 运行 遇到了一个问题,它违反了配额限制:
担任角色策略:LimitExceeded:不能超过 ACLSizePerRole 的配额:2048
您可以请求增加此配额大小,但据说最大值为 4098。我们拥有的每个 AWS 帐户都需要我尝试创建的代入角色策略,因此我们最终也会达到该限制。
不幸的是,您可以在代入角色策略的 arn 中使用通配符,但您可以使用“*”,我认为这样做风险更大。
第一个选项:
如果您不想在 aws_iam_policy_document
中重建策略,您可以使用 templatefile
请参阅 https://www.terraform.io/docs/language/functions/templatefile.html
resource "aws_iam_policy" "example" {
policy = templatefile("policy.json",{account_number_list = ["123","456","789"]})
}
...
%{ for account in account_number_list ~}
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${account}:root"
},
"Action": "kms:*",
"Resource": "*"
},
%{ endfor ~}
...
第二个选项:
AWS's IAM policy document syntax allows for replacement of policy variables within a statement using ${...}-style notation, which conflicts with Terraform's interpolation syntax. In order to use AWS policy variables with this data source, use &{...} notation for interpolations that should be processed by AWS rather than by Terraform.
...
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::&{aws:userid}:root"
},
"Action": "kms:*",
"Resource": "*"
},
点赞:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document