AWS CloudFront 实战指南:使用 Terraform 构建全球分发网络

引言:为什么我们需要关注内容分发?

作为现代 Web 应用的开发者,我们经常面临这样一个挑战:如何确保世界各地的用户都能以最快的速度访问我们的网站或应用?假设我们目前的架构是将所有前端资源(HTML、图片、视频)都部署在一台 EC2 实例上。这在项目初期或许可行,但随着用户群体的扩大,单一区域的服务器往往会成为瓶颈。这种架构不仅延迟较高,而且无法利用全球边缘位置的优势。

为了解决这个问题,我们可以采取一种更为优化的替代方案:将所有静态网站数据迁移到 Amazon S3 存储桶中,并结合 AWS CloudFront 这一强大的内容分发网络(CDN)服务。通过这种组合,我们可以利用遍布全球的边缘位置来缓存内容,从而显著降低延迟,提升用户体验。

那么,作为基础设施即代码的坚定践行者,我们该如何高效地配置和管理这些资源呢?在本文中,我们将深入探讨如何使用 Terraform 来自动化配置 AWS CloudFront 分发,构建一个高性能、安全且易于维护的静态网站托管架构。

核心概念解析

在动手编写代码之前,让我们先花一点时间明确几个关键概念。这不仅有助于我们理解后续的配置,还能帮助我们在设计架构时做出更明智的决策。

#### AWS CloudFront 关键术语

  • 分发: 这是 CloudFront 的核心配置。你可以把它看作是一个“分发中心”,它告诉 CloudFront 从哪里获取内容(源),以及如何分发这些内容。每个分发都有一个唯一的 CloudFront 域名,例如 d123.cloudfront.net,你的用户将通过这个域名访问缓存后的内容。
  • 源: 这是内容的“真实家”,即 CloudFront 在其边缘节点未找到缓存内容时,回源获取数据的地方。最常见的就是 S3 存储桶,但它也可以是你的 EC2 实例、Load Balancer,甚至是外部的 HTTP 服务器。
  • 边缘位置: 这是 AWS 部署在全球各地的物理数据中心点。当用户请求内容时,DNS 会将请求路由到最近的边缘位置。如果该位置有缓存的内容,用户将立即获得响应;如果没有,CloudFront 会从源获取并缓存到该边缘位置,供后续用户使用。
  • 查看器证书: 安全至关重要。这定义了 CloudFront 与最终用户浏览器之间连接的加密方式。通常我们会选择使用 ACM(AWS Certificate Manager)管理的证书来启用 HTTPS。

#### Terraform 关键术语

  • 提供者: 这是 Terraform 与云服务商交互的插件。例如,provider "aws" 告诉 Terraform 我们要操作的是 AWS 的资源。
  • 资源: Terraform 配置的基本构建块。每一个基础设施组件(如 S3 存储桶、CloudFront 分发)都对应一个 resource 块。
  • 变量: 让我们的代码具有灵活性。通过定义变量,我们可以复用同一份脚本创建开发、测试和生产环境,而无需修改核心代码。
  • 状态: Terraform 会将当前基础设施的状态保存在一个文件中。它是 Terraform 知道“云端现在有什么”以及“需要改动什么”的根本依据,管理好状态文件是团队协作的基础。

2026 前沿视角:AI 辅助与云原生开发的融合

在我们开始编写代码之前,让我们思考一下 2026 年的开发环境与我们过去有何不同。在最近的项目中,我们发现Vibe Coding(氛围编程)已经成为一种常态。我们不再是孤立的编写者,而是与 AI 结对编程。使用像 CursorWindsurf 这样的 IDE,我们可以通过自然语言直接生成 Terraform 模块。

我们的工作流变革:

想象这样一个场景:你不需要死记硬背 Terraform 的文档语法。相反,你可以对你的 AI 助手说:“帮我们创建一个 CloudFront 分发,启用 OAC,并配置 WAF 防护。”几秒钟内,不仅代码生成完毕,连最佳实践的安全策略都已经为你考虑周全。但这并不意味着我们可以放弃理解原理。相反,作为现代工程师,我们需要更深入地理解这些生成的代码背后的逻辑,以便进行有效的 代码审查安全左移

此外,Agentic AI(自主 AI 代理) 正在接管运维中的重复性任务。例如,当我们部署完这个 CloudFront 架构后,AI 代理可以自动监控 CloudWatch 的指标。如果错误率突增,它不仅能发出警报,甚至在某些授权范围内,能够自动回滚到上一个稳定的状态。这种从“监控-响应”到“预测-预防”的转变,正是我们这一代工程师需要掌握的核心竞争力。

编写生产级 Terraform 代码

现在,让我们进入最核心的部分:编写基础设施即代码。我们将不仅仅构建一个能跑通的 Demo,而是要构建一个符合 2026 年企业级标准的架构。请在你的工作目录中创建一个名为 main.tf 的文件。

#### 1. 配置提供者与后端

首先,告诉 Terraform 我们要使用 AWS。在现代团队协作中,我们绝不会把 terraform.tfstate 这种敏感文件放在本地。我们通常会配置 S3 作为状态后端,并开启 DynamoDB 锁定。

# main.tf

terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  
  # 现代团队必备:远程状态管理
  backend "s3" {
    bucket         = "my-terraform-state-bucket"
    key            = "prod/cloudfront/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-state-lock"
  }
}

provider "aws" {
  region = "us-east-1"
}

#### 2. 创建 S3 存储桶与安全加固

我们需要一个地方来存放静态文件。在 2026 年,安全是第一要务。我们会明确禁用 S3 存储桶的公共访问,并利用 Bucket Policy 仅允许 CloudFront 访问。

# 创建私有 S3 存储桶作为源
resource "aws_s3_bucket" "website_bucket" {
  bucket = "my-unique-website-bucket-name-2026-prod" # 全局唯一
}

# 阻止公共访问是现代安全的标准实践
resource "aws_s3_bucket_public_access_block" "block_public_access" {
  bucket = aws_s3_bucket.website_bucket.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# 启用 S3 服务端加密
resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" {
  bucket = aws_s3_bucket.website_bucket.id

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

#### 3. 配置 Origin Access Control (OAC)

这是安全架构的关键。我们不再使用旧的 Access Identity,而是推荐使用更现代的 OAC,它支持 AWS Signature V4,并且对 S3 的访问控制更精细。

resource "aws_cloudfront_origin_access_control" "default" {
  name                              = "S3-OAC-Config"
  description                       = "Access Control for S3 Bucket"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

#### 4. 配置 CloudFront 分发 (核心逻辑)

现在让我们来配置 CloudFront 分发。注意这里的配置细节,特别是如何将 OAC 关联到 S3 源,以及如何设置缓存行为。

resource "aws_cloudfront_distribution" "website_cdn" {
  enabled             = true
  is_ipv6_enabled     = true # 双栈支持是必须的
  comment             = "Managed by Terraform - 2026 Edition"
  default_root_object = "index.html"

  # 价格级别:使用 200 可以在欧美获得更好的性能,同时节省成本
  # 如果全球用户分布均匀,使用 PriceClass_All
  price_class = "PriceClass_All"

  # 源配置
  origin {
    domain_name = aws_s3_bucket.website_bucket.bucket_regional_domain_name
    origin_id   = "S3-${aws_s3_bucket.website_bucket.id}"

    # 关键点:关联 OAC
    origin_access_control_id = aws_cloudfront_origin_access_control.default.id
  }

  # 默认缓存行为
  default_cache_behavior {
    allowed_methods  = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "S3-${aws_s3_bucket.website_bucket.id}"

    # 转发查询字符串配置
    forwarded_values {
      query_string = false
      cookies {
        forward = "none"
      }
    }

    # 现代浏览器优化策略
    compress               = true # 启用 Gzip 压缩
    viewer_protocol_policy = "redirect-to-https" # 强制 HTTPS
    min_ttl                = 0
    default_ttl            = 86400  # 24小时
    max_ttl                = 31536000 # 1年

    # 2026年趋势:函数计算
    # 我们可以在这里关联 Lambda@Edge 或 CloudFront Functions
    # function_association {
    #   event_type   = "viewer-request"
    #   function_arn = aws_lambda_function.headers.qualified_arn
    # }
  }

  # 自定义错误响应(提升用户体验)
  custom_error_response {
    error_code         = 403
    response_code      = 200
    response_page_path = "/index.html"
  }

  custom_error_response {
    error_code         = 404
    response_code      = 200
    response_page_path = "/index.html"
  }

  # 限制访问(可选)
  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  # 查看器证书
  # 注意:生产环境通常使用 ACM 验证证书 (acm_certificate_arn)
  # 这里为了演示使用默认证书
  viewer_certificate {
    cloudfront_default_certificate = true
  }
}

#### 5. 自动化部署 S3 对象

为了验证,我们使用 INLINECODEd2c17cbb 配合 INLINECODEf6384698 来模拟 CI/CD 流水线中的上传步骤。

resource "local_file" "index_html" {
  content  = <<-EOF
    
    
    
        2026 CloudFront Demo
        
    
    
        

Deployed via Terraform

This is a production-grade architecture example.

Generated at: ${timestamp()}

EOF filename = "${path.module}/index.html" } resource "aws_s3_object" "website_content" { bucket = aws_s3_bucket.website_bucket.id key = "index.html" source = local_file.index_html.filename content_type = "text/html" # 注意:这里不需要 ACL,因为通过 OAC 访问时,S3 bucket owner 拥有完全控制权 etag = filemd5(local_file.index_html.filename) }

#### 6. S3 存储桶策略 (最难点的自动化)

这是初学者最容易出错的地方。我们必须动态地生成 S3 策略,允许上面创建的 CloudFront 分发(通过 OAC)访问 S3,同时拒绝所有其他直接访问。

data "aws_iam_policy_document" "s3_bucket_policy" {
  statement {
    sid     = "AllowCloudFrontServicePrincipal"
    actions = ["s3:GetObject"]
    resources = [
      "${aws_s3_bucket.website_bucket.arn}/*",
      "${aws_s3_bucket.website_bucket.arn}"
    ]

    principals {
      type        = "Service"
      identifiers = ["cloudfront.amazonaws.com"]
    }

    condition {
      test     = "StringEquals"
      variable = "AWS:SourceArn"
      values   = [aws_cloudfront_distribution.website_cdn.arn]
    }
  }
}

resource "aws_s3_bucket_policy" "website_bucket_policy" {
  bucket = aws_s3_bucket.website_bucket.id
  policy = data.aws_iam_policy_document.s3_bucket_policy.json
}

部署与验证

让我们运行一下经典的 Terraform 工作流。在这个过程中,你可以观察 Terraform 是如何处理依赖关系的(例如,它会自动等待 CloudFront 分发部署完成后再输出域名)。

# 1. 初始化
terraform init

# 2. 查看计划
terraform plan -out=tfplan

# 3. 应用配置
terraform apply "tfplan"

验证安全性的关键步骤:

部署完成后,你会得到一个 CloudFront 域名。尝试访问它,你应该能看到你的 HTML 页面。现在,关键测试来了:尝试直接访问 S3 对象的 URL(格式通常为 https://s3.region.amazonaws.com/bucket-name/index.html)。你应该会收到 403 ForbiddenAccess Denied 错误。这证明我们的安全策略生效了——S3 资源被完全锁定,只能通过 CloudFront 访问。

进阶优化与常见陷阱 (2026版视角)

#### 常见陷阱:缓存中毒

在现代开发中,我们必须高度警惕缓存中毒攻击。如果你在缓存行为中错误地转发了所有的 Headers(比如 Authorization 头),攻击者可能利用这一点将恶意内容缓存到边缘节点,从而污染其他用户的访问体验。

我们的解决方案:forwarded_values 中,除非绝对必要,不要转发 Header。如果你确实需要根据 Header 进行路由(例如 A/B 测试),请使用 Cache Key Policy 来精确控制哪些变量会影响缓存键。

#### 常见陷阱:Terraform 状态漂移

在使用 CloudFront 时,AWS 控制台有时会自动在后台添加一些字段(比如 INLINECODEb36cedc9),这会导致 Terraform 状态文件与实际资源不一致,从而在下次 INLINECODEa95aab5d 时触发意外更新。

我们的解决方案: 使用 lifecycle 块来忽略这些变化。这在我们的生产环境配置中是必须的。

resource "aws_cloudfront_distribution" "website_cdn" {
  # ... other config ...
  
  lifecycle {
    ignore_changes = [
      # AWS 控制台可能会添加这些证书相关的字段,导致不必要的变更
      viewer_certificate[0].acm_certificate_arn,
      viewer_certificate[0].ssl_support_method
    ]
    
    # 防止误删除生产资源
    prevent_destroy = true 
  }
}

#### 未来趋势:多模态边缘计算

到了 2026 年,CloudFront 不仅仅是分发文件。我们可以考虑将 CloudFront Functions 引入到架构中。例如,我们可以编写一段 JavaScript 代码直接在边缘节点运行,用来重写 URL、修改响应 Header 或者进行简单的 A/B 测试。这比 Lambda@Edge 成本更低,启动速度更快。

总结与展望

通过这篇文章,我们一起完成了从零开始使用 Terraform 构建 AWS CloudFront 分发的全过程,并深入到了生产级的安全配置。

关键要点回顾:

  • 安全第一: 始终使用 OAC 限制 S3 访问,并强制 HTTPS。
  • 基础设施即代码: 使用 Terraform 管理状态,并利用 lifecycle 块防止意外变更。
  • 拥抱 AI 工具: 让 AI 帮助我们编写模板代码,但我们必须深入理解背后的原理。

希望这篇指南能帮助你在实际项目中自信地使用 Terraform 管理 AWS 基础设施。随着云原生技术的不断发展,持续学习是我们的唯一出路。祝你在云原生的探索之旅中收获满满!

参考代码下载

你可以直接将上述所有 HCL 代码块合并到一个 INLINECODEdb5e3690 文件中进行测试。不要忘记在测试完成后运行 INLINECODE765ce4f9 以清理资源,保持账户的整洁。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/35576.html
点赞
0.00 平均评分 (0% 分数) - 0