我想使用 Terraform 部署一系列 AWS S3 存储桶。每个存储桶都有不同的内容和不同的名称,但它们的其他配置相同。
存储桶是使用
aws_s3_bucket
资源创建的,并通过 aws_s3_object
资源填充。每个存储桶的内容均源自与该存储桶同名的本地目录。我没有使用 AWS 计算资源,仅使用存储。
我可以像这样创建并填充一个桶:
resource "aws_s3_bucket" "bucket" {
bucket = "sample-bucket-name"
}
# put stuff into the bucket from a directory of the same name
resource "aws_s3_object" "textfiles" {
for_each = fileset(path.module, "sample-bucket-name/**/*.txt")
bucket = aws_s3_bucket.bucket.id
key = replace(each.value, "/^sample-bucket-name//", "")
source = each.value
content_type = lookup(local.content_types, regex("\\.[^.]+$", each.value), null)
etag = filemd5(each.value)
}
如何对多个桶执行此操作?最简单的方法是复制此 HCL 代码,更改存储桶名称,然后为每个存储桶重新运行它。但是,我希望我的代码比那更干燥。
据我了解(来自这篇博文),有两种主要方法可以干燥此类代码:模块和工作区。
工作空间看起来将所有 terraform 代码保存在一个目录中。通过这种方法,我会将一堆 terraform 代码保留在一个位置,这对我来说很有意义,因为我的所有存储桶都配置相同。我假设存储桶名称将从变量中插入。
另一方面,模块将使用多个目录,每个存储桶一个。我想每个都会包含一个
variables.tf
文件。这种方法在 Terraform subreddit 和其他地方很流行。但我不确定我是否理解其优点。
哪种方法适合我的用例?
我可以在网上找到很多关于此问题的建议,这些建议适用于部署不同环境的人员:开发、暂存、生产等,以及在每个环境中具有不同配置(例如不同数量的 EC2 实例)的人员。 这不是我的情况。我希望每个模块或工作区都具有相同的配置(S3 存储桶名称和内容除外)。
如何使其干燥?我将使用哪些变量?我应该使用什么目录结构?
module "s3_bucket" {
for_each = toset(["assets", "media"])
source = "terraform-aws-modules/s3-bucket/aws"
bucket = "${each.key}_bucket"
acl = "private"
control_object_ownership = true
object_ownership = "ObjectWriter"
versioning = {
enabled = true
}
}
您可以使用带有存储桶名称列表的变量,而不是上面使用的静态列表。