如何使用 Terraform 在 AWS S3 存储桶中创建文件夹?

问题描述 投票:0回答:7

我能够使用此链接在 AWS S3 中创建存储桶。

我使用以下代码创建了一个存储桶:

resource "aws_s3_bucket" "b" {
    bucket = "my_tf_test_bucket"
    acl    = "private"
}

现在我想在存储桶内创建文件夹,例如

Folder1

我找到了用于创建 S3 对象的链接。但这有一个强制参数

source
。我不确定这个值是什么,因为我的目的是在 S3 存储桶内创建一个文件夹。

amazon-web-services amazon-s3 directory bucket terraform
7个回答
97
投票

要在 Mac 或 Linux 上运行 terraform,以下命令将执行您想要的操作

resource "aws_s3_bucket_object" "folder1" {
    bucket = "${aws_s3_bucket.b.id}"
    acl    = "private"
    key    = "Folder1/"
    source = "/dev/null"
}

如果您使用的是 Windows,则可以使用空文件。

虽然人们会对 s3 没有文件夹感到迂腐,但在许多操作中,使用键前缀的对象占位符(也称为文件夹)可以让生活变得更轻松。例如 s3 同步。


34
投票

实际上,有一种规范的方法来创建它,而不依赖于操作系统,通过检查 UI 上的网络让您看到内容标题,如下所述: https://stackoverflow.com/users/1554386/alastair-麦科马克

S3 如今确实支持文件夹,从 UI 中可以看到。

这就是实现它的方法:

resource "aws_s3_bucket_object" "base_folder" {
    bucket  = "${aws_s3_bucket.default.id}"
    acl     = "private"
    key     =  "${var.named_folder}/"
    content_type = "application/x-directory"
    kms_key_id = "key_arn_if_used"
}

注意尾部斜杠,否则会创建一个空文件

以上已与 Windows 操作系统一起使用,使用 terraform s3_bucket_object 成功创建文件夹。


23
投票

这里的答案已经过时了,现在绝对可以通过 Terraform 在 S3 中创建一个空文件夹。使用 aws_s3_object 资源,如下所示:

resource "aws_s3_bucket" "this_bucket" {
  bucket = "demo_bucket"
}

resource "aws_s3_object" "object" {
  bucket = aws_s3_bucket.this_bucket.id
  key    = "demo/directory/"
}

如果您不提供对象的源,那么 terraform 将创建一个空目录。

重要 - 请注意尾部斜杠,这将确保您获得一个目录而不是空文件


16
投票

S3 不支持文件夹。对象可以具有带有斜线的前缀名称,看起来像文件夹,但这只是对象名称的一部分。所以没有办法在 terraform 或其他任何东西中创建文件夹,因为 S3 中没有文件夹这样的东西。

http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html http://docs.aws.amazon.com/AWSImportExport/latest/DG/ManipulatedS3KeyNames.html

如果您想假装,您可以在名为“Folder1/”的存储桶中创建一个零字节对象,但这不是必需的。您只需创建具有“Folder1/File1”等键名称的对象即可。


3
投票

旧答案,但如果您使用文件夹指定密钥(尚不存在),terraform 将自动为您创建文件夹

terraform {
  backend "s3" {
    bucket  = "mysql-staging"
    key     = "rds-mysql-state/terraform.tfstate"
    region  = "us-west-2"
    encrypt = true
  }
}

3
投票

我想在此讨论中添加一点,您可以通过向资源提供一组字符串来创建一组空文件夹:

resource "aws_s3_object" "default_s3_content" {
    for_each = var.default_s3_content
    bucket = aws_s3_bucket.bucket.id
    key = "${each.value}/"
}

其中

var.default_s3_content
是一组字符串:

variable "default_s3_content" {
   description = "The default content of the s3 bucket upon creation of the bucket"
   type = set(string)
   default = ["folder1", "folder2", "folder3", "folder4", "folder5"]
}

1
投票

v0.12.8 引入了新的

fileset()
函数,可以与
for_each
结合使用以原生支持此功能:

新功能:

lang/funcs:新的文件集函数,用于查找静态本地文件 匹配全局模式。 (#22523)

此函数的示例用法如下(来自这里):

# Given the file structure from the initial issue:
# my-dir
#    |- file_1
#    |- dir_a
#    |     |- file_a_1
#    |     |- file_a_2
#    |- dir_b
#    |     |- file_b_1
#    |- dir_c
# And given the expected behavior of the base_s3_key prefix in the initial issue

resource "aws_s3_bucket_object" "example" {
  for_each = fileset(path.module, "my-dir/**/file_*")

  bucket = aws_s3_bucket.example.id
  key    = replace(each.value, "my-dir", "base_s3_key")
  source = each.value
}

在撰写本文时,v0.12.8 已发布一天(于 2019 年 9 月 4 日发布),因此文档位于 https://www.terraform.io/docs/providers/aws/r/s3_bucket_object.html 尚未引用它。我不确定这是否是故意的。


顺便说一句,如果您使用上述内容,请记住在您的项目中更新/创建

version.tf
,如下所示:

terraform {
  required_version = ">= 0.12.8"
}
© www.soinside.com 2019 - 2024. All rights reserved.