引用使用for_each循环创建的每个资源

时间:2019-10-16 04:12:08

标签: amazon-web-services terraform

我正在使用for_each创建许多s3存储桶,并且在创建资源时没有任何问题。稍后我在引用这些资源时会遇到麻烦。我希望能够引用所有资源。像这样:

resource "aws_s3_bucket" "dm_client" {
    for_each = toset(var.dm_client_bucket)

    bucket = format("dm-%s-%s",var.env,each.value)
    acl = "private"

    versioning {
        enabled = true
    }
...
data "aws_iam_policy_document" "dm_permission_client" {
    statement {
        sid = "ClientAccess"
        actions = [
            "s3:List*",
            "s3:Get*"
        ]
        resources = [
            aws_s3_bucket.dm_internal["*"].arn,
            "${aws_s3_bucket.dm_internal["*"].arn}/*",
            aws_s3_bucket.dm_client["*"].arn,
            "${aws_s3_bucket.dm_client["*"].arn}/*"
        ]
    }
}```
I've tried using *, "*", etc.. To no avail..

1 个答案:

答案 0 :(得分:1)

使用for_each时,资源值将成为从键到代表资源实例的对象的映射。 [*]运算符用于列表,因此在这种情况下不起作用。

相反,您可以编写一个for expression

[for b in aws_s3_bucket.dm_internal : b.arn]

在您描述的情况下,您需要一个列表,但是类似的语法也可以从键到ARN字符串派生一个映射:

{ for k, b in aws_s3_bucket.dm_internal : k => b.arn }

[*]运算符("Splat Expressions")是应用于列表或集合的for表达式的缩写。


resources中的aws_iam_policy_document参数需要一个字符串列表,但是如果您仅直接使用for表达式,则会得到一个字符串列表列表。要获取参数期望的字符串的平面列表,请使用concat

  resources = concat(
    [for b in aws_s3_bucket.dm_internal : b.arn],
    [for b in aws_s3_bucket.dm_internal : "${b.arn}/*"],
    [for b in aws_s3_bucket.dm_client : b.arn],
    [for b in aws_s3_bucket.dm_client : "${b.arn}/*"],
  )