繁体   English   中英

从 terraform 上传 AWS S3 中的多个文件

[英]Uploading Multiple files in AWS S3 from terraform

我想将多个文件从本地设备中的特定文件夹上传到 AWS S3。 我遇到了以下错误。

在此处输入图像描述

这是我的 terraform 代码。

resource "aws_s3_bucket" "testbucket" {
    bucket = "test-terraform-pawan-1"
    acl = "private"

    tags = {
        Name  = "test-terraform"
        Environment = "test"
    }
}

resource "aws_s3_bucket_object" "uploadfile" {
  bucket = "test-terraform-pawan-1"
  key     = "index.html"
  source = "/home/pawan/Documents/Projects/"

}

我怎么解决这个问题?

从 Terraform 0.12.8 开始,您可以使用fileset函数获取给定路径和模式的文件列表。 结合for_each ,您应该能够将每个文件作为其自己的aws_s3_bucket_object上传:

resource "aws_s3_bucket_object" "dist" {
  for_each = fileset("/home/pawan/Documents/Projects/", "*")

  bucket = "test-terraform-pawan-1"
  key    = each.value
  source = "/home/pawan/Documents/Projects/${each.value}"
  # etag makes the file update when it changes; see https://stackoverflow.com/questions/56107258/terraform-upload-file-to-s3-on-every-apply
  etag   = filemd5("/home/pawan/Documents/Projects/${each.value}")
}

请参阅terraform-providers/terraform-provider-aws:aws_s3_bucket_object:在 GitHub 上支持目录上传 #3020

注意:这不会设置像content_type这样的元数据,据我所知,Terraform 没有内置方法来推断文件的内容类型。 此元数据对于诸如从浏览器正常工作的 HTTP 访问之类的事情很重要。 如果这对您很重要,您应该考虑手动指定每个文件,而不是尝试自动从文件夹中获取所有内容。

您正在尝试上传目录,而 Terraform 需要源字段中的单个文件。 尚不支持将文件夹上传到 S3 存储桶。

但是,您可以使用 null_resource 配置程序调用 awscli 命令,如此处建议那样。

resource "null_resource" "remove_and_upload_to_s3" {
  provisioner "local-exec" {
    command = "aws s3 sync ${path.module}/s3Contents s3://${aws_s3_bucket.site.id}"
  }
}

自 2020 年 6 月 9 日起,terraform 具有一种内置方法来推断您在上传到 S3 存储桶时可能需要的文件的内容类型(和一些其他属性)

HCL 格式:

module "template_files" {
  source = "hashicorp/dir/template"

  base_dir = "${path.module}/src"
  template_vars = {
    # Pass in any values that you wish to use in your templates.
    vpc_id = "vpc-abc123"
  }
}

resource "aws_s3_bucket_object" "static_files" {
  for_each = module.template_files.files

  bucket       = "example"
  key          = each.key
  content_type = each.value.content_type

  # The template_files module guarantees that only one of these two attributes
  # will be set for each file, depending on whether it is an in-memory template
  # rendering result or a static file on disk.
  source  = each.value.source_path
  content = each.value.content

  # Unless the bucket has encryption enabled, the ETag of each object is an
  # MD5 hash of that object.
  etag = each.value.digests.md5
}

JSON格式:

{
"resource": {
  "aws_s3_bucket_object": {
    "static_files": {
      "for_each": "${module.template_files.files}"
      #...
      }}}}
#...
}

来源: https ://registry.terraform.io/modules/hashicorp/dir/template/latest

我的目标是使其动态化,因此每当我在目录中创建文件夹时,terraform 会自动将该新文件夹及其内容上传到具有相同密钥结构的 S3 存储桶中。

我是这样做的。

首先,您必须获得一个局部变量,其中包含每个文件夹及其下的文件的列表。 然后我们可以遍历该列表以将源上传到 S3 存储桶。

示例:我有一个名为“Directories”的文件夹,其中包含 2 个名为“Folder1”和“Folder2”的子文件夹,每个子文件夹都有自己的文件。

- Directories
  - Folder1
    * test_file_1.txt
    * test_file_2.txt
  - Folder2
    * test_file_3.txt

第 1 步:获取本地变量。

locals{
  folder_files = flatten([for d in flatten(fileset("${path.module}/Directories/*", "*")) : trim( d, "../") ])
}

Output 看起来像这样:

folder_files = [
  "Folder1/test_file_1.txt",
  "Folder1/test_file_2.txt",
  "Folder2/test_file_3.txt",
]

第二步:动态上传s3对象

resource "aws_s3_object" "this" {
  for_each = { for idx, file in local.folder_files : idx => file }

  bucket       = aws_s3_bucket.this.bucket
  key          = "/Directories/${each.value}"
  source       = "${path.module}/Directories/${each.value}"
  etag = "${path.module}/Directories/${each.value}"
}

这会遍历本地变量,

因此,在您的 S3 存储桶中,您将以相同的结构上传本地目录及其子目录和文件:

Directory
  - Folder1
    - test_file_1.txt
    - test_file_2.txt
  - Folder2
    - test_file_3.txt

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM