【发布时间】:2021-04-02 01:31:39
【问题描述】:
我正在使用 Terraform 创建和上传 S3 静态 Vue.JS 站点。如果我使用Terraform 将实际文件上传到存储桶,那么使用/index.html 打开站点会失败并给我一个下载对话框。如果我在控制台中手动上传文件,我可以通过访问/ 来按预期查看网站。
我的 terraform 文件在下面,我缺少什么?
provider "aws" {
access_key = var.aws_access_key
secret_key = var.aws_secret_key
version = "~> 3.0"
region = var.region
}
# create a bucket
resource "aws_s3_bucket" "aws_s3_bucket_portal" {
bucket = "my-silly-test"
acl = "public-read"
website {
index_document = "index.html"
error_document = "index.html"
}
}
# create bucket policy
resource "aws_s3_bucket_policy" "portal_policy" {
bucket = aws_s3_bucket.aws_s3_bucket_portal.id
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "${aws_s3_bucket.aws_s3_bucket_portal.arn}/*"
}
]
}
POLICY
}
variable "mime_types" {
default = {
htm = "text/html"
html = "text/html"
css = "text/css"
js = "application/javascript"
map = "application/javascript"
json = "application/json"
png = "image/png"
jpg = "image/jpg"
jpeg = "image/jpg"
gif = "image/gif"
svg = "image/svg+xml"
}
}
# upload root files to the bucket
resource "aws_s3_bucket_object" "website_files" {
for_each = fileset(var.upload_directory, "**/*.*")
bucket = aws_s3_bucket.aws_s3_bucket_portal.bucket
key = replace(each.value, var.upload_directory, "")
source = "${var.upload_directory}/${each.value}"
etag = filemd5("${var.upload_directory}/${each.value}")
# acl = "public-read"
content_type = lookup(var.mime_types, split(".", each.value)[length(split(".", each.value))-1], "text/html")
}
【问题讨论】:
-
在解决您的问题之前,您应该更改一个更紧迫的细节:您的存储桶策略允许每个人在您的存储桶中执行所有操作,包括写入、覆盖和删除对象,以及更改对象 ACL。请永远不要让每个人都使用“s3:*”!想象一下,有人用包含恶意代码的 JavaScript 文件替换了您的一个 JavaScript 文件。
-
您确定您的
aws_s3_bucket_object有效吗?我运行你的代码,我不得不在aws_s3_bucket_object修复很多员工。但这可能是因为我的测试静态网站与您的不同。 -
@marcin - 是的,相信它肯定会上传我的文件。但是,不确定它以与控制台相同的方式上传它们。您需要解决什么问题?
-
github.com/aviboy2006/angular-upload-s3cf/blob/master/… 在上传应用文件时看到在 python 中完成。检查 terraform 如何通过传递文件路径获取文件类型。
-
文件路径
"${var.upload_directory}${each.value}"在我的测试中不正确。它们应该是"${var.upload_directory}/${each.value}",acl = "public-read"不需要,因为您有公共存储桶策略,lookup缺少默认值。
标签: amazon-web-services vue.js amazon-s3 terraform