Reputation: 9015
After running terraform apply
, I made a change to one of the files. I was re-running terraform apply
and was expecting it to run the resource resource "aws_s3_bucket_object.frontend_bucket_content
, but it didn't:
# 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
]
}
What am I missing? here's the full code:
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
}
Upvotes: 0
Views: 1053
Reputation: 4837
Following up on the comments I'd still recommend to use fileset
and filemd5
, you can set the Content-Type
automatically using a lookup dictionary like this:
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")
}
This falls back to "text/plain"
if the extension can't be found in local.mime_types
.
My local.mime_types
looks like this (based on Common MIME types):
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",
}
}
Upvotes: 1