Terraform 更改文件后未运行资源aws_s3_bucket_对象(带etag)?

Terraform 更改文件后未运行资源aws_s3_bucket_对象(带etag)?,terraform,terraform-provider-aws,Terraform,Terraform Provider Aws,运行terraformapply后,我对其中一个文件进行了更改。我正在重新运行terraform apply,并希望它运行资源资源“aws\u s3\u bucket\u对象。前端\u bucket\u内容,但它没有: # https://stackoverflow.com/questions/57456167/uploading-multiple-files-in-aws-s3-from-terraform # https://registry.terraform.io/modules/has

运行
terraformapply
后,我对其中一个文件进行了更改。我正在重新运行
terraform apply
,并希望它运行资源
资源“aws\u s3\u bucket\u对象。前端\u bucket\u内容
,但它没有:

# https://stackoverflow.com/questions/57456167/uploading-multiple-files-in-aws-s3-from-terraform
# https://registry.terraform.io/modules/hashicorp/dir/template/latest
module "template_files" {
    source   = "hashicorp/dir/template"
    base_dir = local.frontend_deliverables
}

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

    bucket                 = aws_s3_bucket.frontend_bucket.bucket
    key                    = each.key
    content_type           = each.value.content_type
    source                 = each.value.source_path
    etag                   = each.value.digests.md5
    server_side_encryption = "AES256"

    depends_on = [
        null_resource.build_frontend
    ]
}
我遗漏了什么?以下是完整的代码:

locals {
  frontend_directory    = "./frontend"
  frontend_deliverables = "${local.frontend_directory}/build"
  frontend_bucket_name  = "my-bucket"
}

resource "null_resource" "build_frontend" {
  provisioner "local-exec" {
    command     = "npm run build"
    interpreter = ["PowerShell", "-Command"]
    working_dir = "${path.module}/frontend"
  }

  triggers = {
    always_run = timestamp()
  }
}

resource "aws_s3_bucket" "frontend_bucket" {
  bucket = local.frontend_bucket_name

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

# https://stackoverflow.com/questions/57456167/uploading-multiple-files-in-aws-s3-from-terraform
# https://registry.terraform.io/modules/hashicorp/dir/template/latest
module "template_files" {
  source   = "hashicorp/dir/template"
  base_dir = local.frontend_deliverables
}

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

  bucket                 = aws_s3_bucket.frontend_bucket.bucket
  key                    = each.key
  content_type           = each.value.content_type
  source                 = each.value.source_path
  etag                   = each.value.digests.md5
  server_side_encryption = "AES256"

  depends_on = [
    null_resource.build_frontend
  ]
}

resource "aws_cloudfront_distribution" "s3_distribution" {
  origin {
    domain_name = aws_s3_bucket.frontend_bucket.bucket_regional_domain_name
    origin_id   = "S3-${aws_s3_bucket.frontend_bucket.id}"

    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.origin_access_identity.cloudfront_access_identity_path
    }
  }
  default_root_object = "index.html"

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  default_cache_behavior {
    viewer_protocol_policy = "redirect-to-https"
    allowed_methods        = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
    cached_methods         = ["GET", "HEAD"]
    target_origin_id       = "S3-${aws_s3_bucket.frontend_bucket.id}" # must equate "origin_id" above..

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }

  enabled = true
}

resource "aws_cloudfront_origin_access_identity" "origin_access_identity" {
  comment = "my-tf-test-identity"
}

data "aws_iam_policy_document" "s3_policy" {
  statement {
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.frontend_bucket.arn}/*"]

    principals {
      type        = "AWS"
      identifiers = [aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn]
    }
  }
}

resource "aws_s3_bucket_policy" "frontend_s3_bucket_policy" {
  bucket = aws_s3_bucket.frontend_bucket.id
  policy = data.aws_iam_policy_document.s3_policy.json
}

根据我仍然建议使用
fileset
filemd5
的注释,您可以使用如下查找字典自动设置
内容类型

resource "aws_s3_bucket_object" "frontend_bucket_content" {
  for_each = fileset(local.frontend_deliverables, "**/*")

  bucket       = aws_s3_bucket.frontend_bucket.bucket
  key          = each.value
  source       = "${local.frontend_deliverables}/${each.value}"
  etag         = filemd5("${local.frontend_deliverables}/${each.value}")
  content_type = lookup(local.mime_types, split(".", each.value)[length(split(".", each.value)) - 1], "text/plain")
}
如果在
local.mime\u类型中找不到扩展名,则返回到
“text/plain”

我的
local.mime\u类型
如下所示(基于):


这可能是
“hashicorp/dir/template”
中的一个bug吗?…听起来确实很像。为什么不尝试不使用它,而是使用函数
fileset
filemd5
@HelderSepulveda,因为该方法无法正确设置
内容类型
locals {
  mime_types = {
    "aac"    = "audio/aac",
    "abw"    = "application/x-abiword",
    "arc"    = "application/x-freearc",
    "avi"    = "video/x-msvideo",
    "azw"    = "application/vnd.amazon.ebook",
    "bin"    = "application/octet-stream",
    "bmp"    = "image/bmp",
    "bz"     = "application/x-bzip",
    "bz2"    = "application/x-bzip2",
    "csh"    = "application/x-csh",
    "css"    = "text/css",
    "csv"    = "text/csv",
    "doc"    = "application/msword",
    "docx"   = "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    "eot"    = "application/vnd.ms-fontobject",
    "epub"   = "application/epub+zip",
    "gz"     = "application/gzip",
    "gif"    = "image/gif",
    "htm"    = "text/html",
    "html"   = "text/html",
    "ico"    = "image/vnd.microsoft.icon",
    "ics"    = "text/calendar",
    "jar"    = "application/java-archive",
    "jpeg"   = "image/jpeg",
    "jpg"    = "image/jpeg",
    "js"     = "text/javascript",
    "json"   = "application/json",
    "jsonld" = "application/ld+json",
    "mid"    = "audio/x-midi",
    "midi"   = "audio/x-midi",
    "mjs"    = "text/javascript",
    "mp3"    = "audio/mpeg",
    "mpeg"   = "video/mpeg",
    "mpkg"   = "application/vnd.apple.installer+xml",
    "odp"    = "application/vnd.oasis.opendocument.presentation",
    "ods"    = "application/vnd.oasis.opendocument.spreadsheet",
    "odt"    = "application/vnd.oasis.opendocument.text",
    "oga"    = "audio/ogg",
    "ogv"    = "video/ogg",
    "ogx"    = "application/ogg",
    "opus"   = "audio/opus",
    "otf"    = "font/otf",
    "png"    = "image/png",
    "pdf"    = "application/pdf",
    "php"    = "application/x-httpd-php",
    "ppt"    = "application/vnd.ms-powerpoint",
    "pptx"   = "application/vnd.openxmlformats-officedocument.presentationml.presentation",
    "rar"    = "application/vnd.rar",
    "rtf"    = "application/rtf",
    "sh"     = "application/x-sh",
    "svg"    = "image/svg+xml",
    "swf"    = "application/x-shockwave-flash",
    "tar"    = "application/x-tar",
    "tif"    = "image/tiff",
    "tiff"   = "image/tiff",
    "ts"     = "video/mp2t",
    "ttf"    = "font/ttf",
    "txt"    = "text/plain",
    "vsd"    = "application/vnd.visio",
    "wav"    = "audio/wav",
    "weba"   = "audio/webm",
    "webm"   = "video/webm",
    "webp"   = "image/webp",
    "woff"   = "font/woff",
    "woff2"  = "font/woff2",
    "xhtml"  = "application/xhtml+xml",
    "xls"    = "application/vnd.ms-excel",
    "xlsx"   = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "xml"    = "text/xml",
    "xul"    = "application/vnd.mozilla.xul+xml",
    "zip"    = "application/zip",
    "7z"     = "application/x-7z-compressed",
    "yaml"   = "application/x-yaml",
    "scss"   = "text/plain",
    "md"     = "text/markdown",
  }
}