在我当前的地形配置中,我使用静态 JSON 文件并使用文件函数导入到地形中以创建 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
数据源为您提供了一种以 terraform 创建 json 策略的方法,而无需从文件或多行字符串导入原始 json。
由于您全部在 terraform 中定义策略语句,因此它的好处是允许您在委托人数组上使用循环/过滤。
在您的示例中,您可以执行以下操作:
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}"
}
第一个选项:
如果不想在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 ~}
...
第二个选项:
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#policy-vars-infotouse
AWS 的 IAM 策略文档语法允许替换策略 使用 ${...} 的语句中的变量-样式表示法,其中 与 Terraform 的插值语法冲突。为了使用AWS而 策略变量 对于此数据源,请使用 &{...} 表示法 应由 AWS 而不是由 地形。
...
{
"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
这很棒,是一个很好的模式,能够坚持下去。 不幸的是,我遇到了一个问题,它超过了配额限制:
代入角色策略: 已超出限制: 不能超过 ACLSizePerRole: 2048 的配额
您可以请求增加此配额大小,但据说最大值为 4098。 我们拥有的每个 AWS 账户都需要我尝试创建的代入角色策略,因此我们最终也会达到该限制。
不幸的是,您可以在代入角色策略的 arn 中使用通配符,但您可以使用"*",我认为这风险要大得多。