使用Terraform部署S3 Bucket时无法加载本地源文件
我尝试用Terraform创建S3 Bucket并配置静态托管,所有配置步骤都正常执行,但本地的源文件始终没有加载到桶中。
我的Terraform代码如下:
provider "aws" { region = "us-east-1" } # 创建名为sullyelh.com的Bucket resource "aws_s3_bucket" "sullyelhcom" { bucket = "sullyelh.com" tags = { Name = "Resume" } } # 配置静态托管的索引和错误页面 resource "aws_s3_bucket_website_configuration" "sullyelhcom" { bucket = aws_s3_bucket.sullyelhcom.id index_document { suffix = "index.html" } error_document { key = "error.html" } } # 从本地加载索引和错误文件 resource "aws_s3_object" "provision_source_files" { bucket = aws_s3_bucket.sullyelhcom.id for_each = fileset("aws-resume/", "**/*.*") key = each.value source = "aws-resume/${each.value}" content_type = file("aws-resume/${each.value}") } # 关闭S3的公共访问阻止设置 resource "aws_s3_bucket_public_access_block" "sullyelhcom" { bucket = aws_s3_bucket.sullyelhcom.id block_public_acls = false block_public_policy = false ignore_public_acls = false restrict_public_buckets = false } # 配置公共读取的Bucket策略 resource "aws_s3_bucket_policy" "sullyelhcom" { bucket = aws_s3_bucket.sullyelhcom.id policy = jsonencode({ Version = "2012-10-17", Statement = [ { Sid = "PublicReadGetObject", Effect = "Allow", Principal = "*", Action = "s3:GetObject", Resource = "${aws_s3_bucket.sullyelhcom.arn}/*" } ] }) }
本地文件结构:
aws-resume\ - static-files\ -- css\ -- js\ - index.html - resume.html - errro.html
1. 修复content_type字段的错误
代码中content_type使用了file()函数,该函数会读取文件的实际内容并赋值给content_type,但content_type需要的是文件的MIME类型(如text/html、text/css)而非文件内容,这会导致Terraform无法正确处理文件上传。
将content_type行替换为:
content_type = mime_type("aws-resume/${each.value}")
mime_type()函数会根据文件后缀自动识别正确的MIME类型,符合S3 Object的要求。
2. 修正错误页面文件名
网站配置中指定错误页面为error.html,但本地文件是errro.html(拼写错误),这会导致静态托管无法找到错误页面,同时影响文件的正常识别。将本地的errro.html重命名为error.html。
3. 确认文件路径正确性
确保aws-resume/文件夹和你的Terraform配置文件(如main.tf)处于同一目录下。如果路径不对,fileset()函数无法匹配到任何文件,自然不会创建S3对象。如果文件夹在其他路径,需调整fileset和source中的路径,比如上级目录写../aws-resume/。
4. 可选:添加文件哈希以支持更新检测
为让Terraform能检测到本地文件的变更并自动更新S3对象,可添加source_hash字段:
source_hash = filemd5("aws-resume/${each.value}")
这样当本地文件内容变化时,Terraform会自动重新上传该文件。
修改后的aws_s3_object资源代码:
resource "aws_s3_object" "provision_source_files" { bucket = aws_s3_bucket.sullyelhcom.id for_each = fileset("aws-resume/", "**/*.*") key = each.value source = "aws-resume/${each.value}" content_type = mime_type("aws-resume/${each.value}") source_hash = filemd5("aws-resume/${each.value}") }
执行terraform apply重新部署,本地文件就能正常上传到S3桶中了。
内容的提问来源于stack exchange,提问作者chiefqueef

