带下游依赖的Terraform条件' for_each '



给定一些条件/过滤的for_each语句,我如何使用剩余的对象下游依赖关系?

注:Terraform 0.13.7

例如,如果一个用户没有s3 bucket, terraform应该创建一个,并设置它的通知策略。如果他们有一个桶,那么terraform应该查找桶并设置它的通知。

到目前为止,我已经尝试格式化我的有效载荷如下:

"snowpipes": {
. . .
"create_staging_bucket": true,
"staging_bucket": {
"name": "existing-bucket-deployment",
"url": "old-dirty-bucket",
"arn": "arn:aws:s3:::old-dirty-bucket"
},
. . .
}

然后像这样构建我的地形:

resource "aws_s3_bucket" "staging_bucket" {
for_each = {for k, v in var.snowpipes : k => v if v.create_staging_bucket == true}
bucket = lower(each.value.staging_bucket.url)
}
resource "aws_s3_bucket_notification" "bucket_notification" {
for_each = var.snowpipes
bucket = aws_s3_bucket.staging_bucket[each.key].id
. . .
}

,然后我得到这样的错误,表明给定的键被过滤掉了:

Error: Invalid index
on main.tf line 504, in resource "aws_s3_bucket_notification" "bucket_notification":
504:   bucket = aws_s3_bucket.staging_bucket[each.key].id
|----------------
| aws_s3_bucket.staging_bucket is object with no attributes
| each.key is "existing-bucket-deployment"
The given key does not identify an element in this collection value.

不确定是否有一种方法可以在resourcedata对象之间来回交换?

我通常建议保持共享模块简单的通过一个艰难的决定是否创建桶是否其范围的一部分,然后在调用模块总是声明自己的S3 bucket如果你决定S3 bucket没有范围的一部分,但我也能看到,有时是方便灵活,并有可能以牺牲一些额外的复杂性在配置。

让我们从下面的变量声明开始:

variable "snowpipes" {
type = map(object({
create_staging_bucket = bool
staging_bucket = object({
name = string
url  = string
arn  = string
})
# (and whatever else you need, immaterial to this question)
}))
}

接下来,让我们为这些具有create_staging_bucket集的元素的子集声明aws_s3_bucket资源,这与您已经写的相同:

resource "aws_s3_bucket" "staging_bucket" {
for_each = {
for k, v in var.snowpipes : k => v
if v.create_staging_bucket == true
}
bucket = lower(each.value.staging_bucket.url)
}
到目前为止,我希望我只是重复了你们已经学过的东西。我的下一步是将这个资源的结果合并到原始变量的设置中,以便创建所有staging bucket的平面映射,而不管它们是否在这里创建:
locals {
staging_buckets = merge(
{ for k, sp in var.snowpipes : k => sp.staging_bucket }
{
for k, b in aws_s3_bucket.staging_bucket : k => {
name = b.bucket
url  = b.bucket # (not sure about this, but following your example above)
arn  = b.arn
}
}
}
}

现在我们回到了一个映射,它与我们在var.snowpipes中开始的所有键相同,其中一些元素只是与输入中的元素一字不差,而其他元素是根据我们声明的资源合成的。由于merge的优先级行为,它将更倾向于使用来自第二个映射的键,而不是来自第一个映射的键。

我们可以将其用于桶通知资源:

resource "aws_s3_bucket_notification" "bucket_notification" {
for_each = local.staging_buckets
bucket = each.value.name
# ...
}

最新更新