You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Terraform部署S3 Bucket时无法加载本地源文件

问题:Terraform创建S3静态托管桶但本地文件未上传成功

我尝试用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:53:17