我正在编写一个模块,用所有相关资源创建多个S3 Bucket。目前,我有点拘泥于服务器端加密,因为我需要参数化尚未创建的密钥的KMS密钥id。
传递给模块的变量为:
- S3存储桶列表
- 创建了带有KMS的地图
S3存储桶的结构为
type = list(object({
bucket = string
acl = string
versioning = string
kms_description = string
logging = bool
loggingBucket = optional(string)
logPath = optional(string)
}))
}
KMS地图的结构类似于
kms_resources = {
0 = {
kms_arn = (known after apply)
kms_description = "my-kms"
kms_id = (known after apply)
}
}
此变量是创建所有KMS的前一个模块的输出。输出以这种方式创建
output "kms_resources" {
value = {
for kms, details in aws_kms_key.my-kms :
kms => ({
"kms_description" = details.description
"kms_id" = details.key_id
"kms_arn" = details.arn
})
}
}
正如您所看到的,这个想法是,在S3变量上,用户可以选择自己的KMS密钥,但我很难检索到值。此时,资源看起来像这个
resource "aws_s3_bucket_server_side_encryption_configuration" "my-s3-buckets" {
count = length(var.s3_buckets)
bucket = var.s3_buckets[count.index].bucket
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = [
for k in var.kms_keys : k.kms_id
if k.kms_description == var.s3_buckets[count.index].kms_description
]
sse_algorithm = "aws:kms"
}
}
}
我以为它会起作用,但有一次地形给了我Inappropriate value for attribute "kms_master_key_id": string required.
。我还希望,如果该值不存在,则kms_master_key_id默认设置为aws/s3
问题似乎是您试图将列表作为kms_master_key_id
而不仅仅是字符串。事实上,您还想使用"aws/s3"
,这实际上使修复变得非常容易:
kms_master_key_id = concat([
for k in var.kms_keys : k.kms_id
if k.kms_description == var.s3_buckets[count.index].kms_description
], ["aws/s3"])[0]
通过这种方式,您首先获得一个包含与描述匹配的keys/That键的列表,然后附加默认的s3键。然后,您只需选择列表的第一个元素,或者第一个实际键,或者如果没有匹配,则选择默认键。