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

时间:2019-08-12 05:48:11

标签: amazon-s3 file-upload terraform-provider-aws

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

这是我的Terraform代码。

class User {
  score = 0;
  constructor(username, email) {
    this.username = username;
    this.email = email;
  }
  get userName() {
    return this.username;
  }
  login() {
    console.log(`you have logged in ${this.username}`);
    return this;
  }
  logout() {
    console.log(`you have logout ${this.username}`);
    return this;
  }
  incScore() {
    this.score += 1;
    console.log(`The ${this.username} have scored ${this.score}`)
    return this;
  }
}

const user = new User('foo', 'foo@bar.com');
console.log(user.userName)
user.incScore();

我不知道我哪里错了。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:5)

您正在尝试上载目录,而Terraform希望在源字段中使用一个文件。尚不支持将文件夹上传到S3存储桶。

但是,您可以按照建议here使用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}"
  }
}

答案 1 :(得分:3)

从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}")
}

请参阅GitHub上的terraform-providers/terraform-provider-aws : aws_s3_bucket_object: support for directory uploads #3020

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

答案 2 :(得分:3)

自 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