【问题标题】:Create multiple folders within multiple S3 buckets with Terraform使用 Terraform 在多个 S3 存储桶中创建多个文件夹
【发布时间】:2021-07-02 15:32:33
【问题描述】:

我希望创建一个 S3 terraform 模块,该模块可以获取要在所有这些存储桶中创建的存储桶名称和文件夹名称的列表。 例如在我的 S3 模块 main.tf 中。我有

resource "aws_s3_bucket_object" "folders" {
    count = var.create_folders ? length(var.s3_folder_names) : 0
    bucket  = element(aws_s3_bucket.s3bucket.*.id, count.index)
    acl    = "private"
    key    = format("%s/",var.s3_folder_names[count.index])
    source = "/dev/null"
}

我正在调用这个模块,如下所示:

variable "s3_bucket_name" {
  type = list
  description = "List of S3 bucket names"
default = ["bucket1","bucket-2"]
}
variable "s3_folder_names" {
  type        = list
  description = "The list of S3 folders to be created inside S3 bucket"
  default=["folder1/dev","folder2/qa"]

}
module "s3" {
  source = "../../../gce-nextgen-cloud-terraform-modules/modules/s3"
  create_folders = true
  s3_folder_names = var.s3_folder_names
  environment = var.environment
  s3_bucket_name = var.s3_bucket_name
  force_destroy = true
  bucket_replication_enabled = true
  tags = local.common_tags
  providers = {
    aws.main_region = aws.main_region
    aws.secondary_region = aws.secondary_region
  }
}

我遇到了问题,因为计数变量只能在资源块中设置一次。这是导致问题的场景:

  1. 如果 var.s3_folder_names < aws_s3_bucket.s3bucket.*.id。 然后我将无法访问 S3 存储桶列表的所有元素,如下所示
resource "aws_s3_bucket_object" "folders" {
    count = var.create_folders ? length(var.s3_folder_names) : 0
    **bucket  = element(aws_s3_bucket.s3bucket.*.id, count.index)**
    acl    = "private"
    key    = format("%s/",var.s3_folder_names[count.index])
    source = "/dev/null"
}

因此,我将无法在所有存储桶中创建这些文件夹。唯一的目标是在所有这些存储桶中创建相同的文件夹结构集。 任何帮助将不胜感激。提前致谢!

【问题讨论】:

  • 为什么还要创建文件夹?你不需要。
  • 不明白。我知道它们不是 S3 内的文件夹,而是对象。但从肉眼来看,我们与它们一起工作并将它们作为文件夹进行管理。因此,我需要使用 terraform 在每个 S3 存储桶内创建具有层次结构的子目录。 @jarmod

标签: amazon-web-services terraform terraform-provider-aws


【解决方案1】:

您可以创建一个组合数据结构,例如:

locals {

  buckets_and_folders = merge([
    for bucket in var.s3_bucket_name:
      {
        for folder in var.s3_folder_names:
        "${bucket}-${folder}" => {
          bucket = bucket
          folder = folder
        }
      }
  ]...)

}

然后您将使用for_each 迭代此结构:

resource "aws_s3_bucket_object" "folders" {

    for_each = var.create_folders ? local.buckets_and_folders : {}

    bucket  = each.value.bucket
    acl    = "private"
    key    = format("%s/", each.value.folder)
    source = "/dev/null"
}

【讨论】:

  • 感谢您的帮助。我确实尝试了你的方法,但我得到了如下所示的错误: var.s3_bucket_name 是带有 1 个元素的字符串列表 var.s3_folder_names 是带有 1 个元素的字符串列表 调用函数“合并”失败:参数必须是地图或对象,得到“元组”。
  • @HemantKumar 你在合并结束时忘记...了吗?
  • 这是我的错误,因为我经常混淆 terraform,但现在我明白了,因为这些 '...' 是为了解包参数对吗?
  • @HemantKumar 是的,它会将列表解压缩为合并的参数。如果答案是有帮助的,一旦它起作用,我们将不胜感激。
  • 感谢您的帮助。它就像魅力一样。
猜你喜欢
  • 2021-08-14
  • 2019-05-14
  • 2020-10-28
  • 2021-12-16
  • 2021-12-06
  • 2021-09-27
  • 2016-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多