![](/img/trans.png)
[英]Terraform JSON Error when using for_each inside of resource inside of json file
[英]In Terraform, how can I use a for_each and manipulate each resource that is created?
我想看看是否可以在不通过资源引用创建更多资源的情况下操作 for_each 中的每个资源。
例如,我正在创建 3 个 AWS S3 存储桶,在我的 S3 模块中,我有以下资源:
resource "aws_s3_bucket" "s3-bucket" {
for_each = var.bucket_details
bucket = each.value.bucket
acl = each.value.acl
policy = each.value.policy
}
这是 my.tfvars:
bucket_details = {
bucket_1 = {
bucket = "stg-kikeman-bkt-1"
acl = "private"
policy = <<EOF
{ ... <= THIS IS A JSON S3 POLICY
}
EOF
},
bucket_2 = { ... }
bucket_3 = { ... }
应用后,假设创建 3 个桶,其中桶名、acl 及其策略的值。
但我遇到了错误:
on modules/s3/s3.tf line 15, in resource "aws_s3_bucket" "s3-bucket":
│ 15: policy = each.value.policy
│ ├────────────────
│ │ each.value is map of string with 3 elements
│
│ This map does not have an element with the key "policy"
看起来像 json 策略的关键策略的值没有被识别为“值”,我尝试使用 jsonencode({the_json_policy}) 但我得到了错误
Functions may not be called here
我正在研究如何使用 json 政策作为 map 的“价值”,当然如果可能的话。
可能吗?
这是。 根据您要在策略中更改的内容,您必须有条件地设置 attributes 。 基于需要不同设置的存储桶名称。
for_each
适用于您希望根据 map 中的数据系统地声明多个对象的情况。 如果您需要在实例之间存在差异,那么您将需要以某种方式在您提供的 map 中表示这些差异,以便设计仍然是系统的。
一种方法是将源集合改为从名称到包含策略文档和 ACL 字符串的对象的映射:
locals {
buckets = {
stg-bkt-1 = {
acl = "private"
policy = {
Version = "2012-10-17"
Id = Test
Statement = [
{
Sid = "1"
Effect = "Deny"
Principal = "*"
Action = "*"
Resource = "arn:aws:s3:::stg-bkt-1/*"
Condition = {
Bool = {
"aws:SecureTransport": "false"
}
}
},
]
}
}
stg-bkt-2 = {
acl = "public-read"
policy = {
Version = "2012-10-17"
Id = Test
Statement = [
{
Sid = "1"
Effect = "Deny"
Principal = "*"
Action = "*"
Resource = "arn:aws:s3:::stg-bkt-2/*"
Condition = {
Bool = {
"aws:SecureTransport": "false"
}
}
},
{
Sid = "2"
Effect = "Allow"
Principal = "*"
Action = ["s3:GetObject"]
Resource = "arn:aws:s3:::stg-bkt-2/*"
},
]
}
}
}
}
resource "aws_s3_bucket" "s3-bucket" {
for_each = var.buckets
bucket = each.key
acl = each.value.acl
policy = jsonencode(each.value.policy)
}
在资源配置最终完全引用each.key
和each.value
的情况下,我通常会说这根本不是系统性的,因此只写出多个resource "aws_s3_bucket"
会更简单、更容易resource "aws_s3_bucket"
块。 但是,如果您可以对此进行调整,以使所有存储桶仍然具有一些共同特征——例如,如果映射中的定义仅包含附加的 IAM 策略语句,这些语句将与所有存储桶通用的策略语句连接起来——那么使用for_each
系统地声明它们似乎是合理的,这样当您将来更改细节时,这些通用部分将被迫保持通用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.