我正在创建一个存储桶,然后创建一个存储桶策略,以允许所有列出的帐户访问。似乎传递了terraform plan / apply,但是看着控制台,只列出了一个帐户,似乎是践踏了之前的政策补充。
我有一个变量列表和代码来生成存储桶/策略:
variable "accounts" {
type = "list"
default = [
"111111111111",
"222222222222",
"333333333333",
"444444444444",
"555555555555",
"666666666666",
"777777777777"
]
}
resource "aws_s3_bucket" "my_bucket" {
bucket = "${var.bucket_name}"
}
resource "aws_s3_bucket_policy" "my_bucket_policy" {
bucket = "${aws_s3_bucket.my_bucket.id}"
count = "${length(var.accounts)}"
policy =<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${element(var.accounts, count.index)}:root"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::${var.bucket_name}/CloudTrail/AWSLogs/${element(var.accounts, count.index)}/*"
}
]
}
EOF
}
有没有办法只在Resource或Principal部分迭代变量列表?目标是生成一个包含变量所有arns的存储桶策略。
答案 0 :(得分:0)
每个存储桶仅支持一个存储桶策略,因此您无法创建多个存储桶策略。
相反,您可以在单个策略中创建多个语句,每个帐户一个。 Terraform不支持迭代,但使用formatlist()
和join(
)函数可以获得更多相同的效果。
resource "aws_s3_bucket_policy" "my_bucket_policy" {
bucket = "${aws_s3_bucket.my_bucket.id}"
policy =<<EOF
{
"Version": "2012-10-17",
"Statement": [
${join(",\n",formatlist("
{
\"Effect\": \"Allow\",
\"Principal\": {
\"AWS\": \"arn:aws:iam::%s:root\"
},
\"Action\": \"s3:PutObject\",
\"Resource\": \"arn:aws:s3:::%s/CloudTrail/AWSLogs/%s/*\"
}
", var.accounts, var.bucket_name, var.accounts))}
]
}
EOF
}
在这种情况下,我将整个语句内容作为formatlist()
函数的第一个参数。有必要避开双引号,但Terraform不需要转义换行符。它包含您要放置替换的%s
。其他formatlist()
参数是替换。
formatlist()
的输出是一个列表,因此我必须使用join()
函数将列表加入到单个输出字符串中。 join()
函数还允许我在每个语句之间添加逗号分隔符。