使用 Terraform 构建云原生博客平台
目录
代码示例和文档
Next.js + AWS(CloudFront、S3、Route53、ACM)+ Terraform + GitHub Actions CI/CD
Github 代码
完整的 Terraform 配置、GitHub Actions 工作流程和详细的设置说明可在存储库中找到。您可以随意将其用作您自己的项目的参考或提出改进建议。
记住:有时最长的道路会教给你最宝贵的经验。
为什么要构建另一个博客平台?
他们说:“只要使用 WordPress 就可以了。几分钟就可以搞定。”
作为一名 AWS 解决方案架构师,我知道我可以在一小时内在控制台中启动一个简单的博客。但问题是 - 我已经构建了保持 99.9% 正常运行时间的生产系统。我已经无数次点击控制台。这个项目不是关于博客的最快路径;而是关于突破我的极限。
我需要一个能够:
真正的价值是什么?知道如何在控制台中执行某项操作和在 Terraform 中实现它之间的差距。这就是学习发生的地方。这就是工程师成长的地方。
架构决策
核心基础设施组件
我在设计架构时考虑了几个关键要求:
每个部分的组合方式如下:
内容交付和安全
基础设施管理
这种设置不仅遵循了 AWS 精心构建的框架的六大支柱,还让我了解了网络和 IaC 的复杂性。
真正的挑战:连续的旅程
纸面上看似简单的架构变成了复杂的故障排除之旅。以下是每个挑战如何导致下一个挑战:
1. 托管区域之谜
最初,Terraform 无法通过名称访问托管区域。虽然 AWS CLI 可以找到它,但 Terraform 一直失败。这是我第一次意识到更深层次的问题,尽管我还没有意识到。
# Initial attempt that failed` resource "zone_name" "primary" { name = var.domain_name } # Solution: Use zone ID directly` data "zone_id" "primary" { zone_id = var.zone_id }
2. 多账户迷宫
托管区域问题揭示了一个复杂的问题:我在不知情的情况下尝试跨多个 AWS 账户访问资源,但没有适当的跨账户权限。具体表现如下:
在尝试修复权限多次后,我疲惫不堪,打开了无数个 Chrome 标签,于是我离开了电脑。有时,最好的调试工具就是全新的视角。当我回来时,我系统地检查了每个环境变量,发现它们配置不正确。
最初,我为默认帐户设置了环境变量:
# Checking current identity aws sts get-caller-identity # Setting up environment variables export AWS_ACCESS_KEY_ID="new_access_key" export AWS_SECRET_ACCESS_KEY="new_secret_key" export AWS_DEFAULT_REGION="us-east-1" # Profile export AWS_PROFILE=default
但这在尝试切换账户时会产生冲突。真正的问题是什么?Terraform 角色缺乏跨账户访问权限。
3.跨账户资源管理
情况变得清晰起来:
头脑清醒后,我看清了事情的真相。我采取了系统的方法:
解决方案需要系统清理:
这些问题的解决标志着该项目的一个重要转折点。我不仅设法通过确保资源与各自的账户正确对齐来简化 AWS 架构,而且还强化了 AWS 管理和 Terraform 使用的最佳实践。这个过程强调了警惕的账户管理的重要性,并为在云环境中保持清晰度和组织性提供了宝贵的经验教训。
4. CI/CD 管道优化
最后的挑战出现在 CI/CD 管道中。虽然 YAML 在语法上是正确的,但 Terraform 操作却挂在 Terraform Plan 上。根本原因是什么?环境变量需要单独传递给每个 Terraform 命令:
- name: Terraform Init run: | cd ./terraform-config terraform init env: TF_VAR_domain_name: ${{ secrets.DOMAIN_NAME }} TF_VAR_aws_region: ${{ secrets.AWS_REGION}} TF_VAR_zone_id: ${{ secrets.ZONE_ID }} - name: Terraform id: plan run: | cd ./terraform-config terraform plan -out=tfplan - name: Terraform Apply id: apply run: | cd ./terraform-config terraform apply -auto-approve tfplan
工作解决方案
- name: Terraform Init run: | cd ./terraform-config terraform init env: TF_VAR_domain_name: ${{ secrets.DOMAIN_NAME }} TF_VAR_aws_region: ${{ secrets.AWS_REGION}} TF_VAR_zone_id: ${{ secrets.ZONE_ID }} - name: Terraform id: plan run: | cd ./terraform-config terraform plan -out=tfplan env: TF_VAR_domain_name: ${{ secrets.DOMAIN_NAME }} TF_VAR_aws_region: ${{ secrets.AWS_REGION}} TF_VAR_zone_id: ${{ secrets.ZONE_ID }} - name: Terraform Apply id: apply run: | cd ./terraform-config terraform apply -auto-approve tfplan env: TF_VAR_domain_name: ${{ secrets.DOMAIN_NAME }} TF_VAR_aws_region: ${{ secrets.AWS_REGION}} TF_VAR_zone_id: ${{ secrets.ZONE_ID }}
我花了两个小时才解决了这个难题,这凸显了理解 CI/CD 管道中 Terraform 命令的细微差别的重要性,并强调了细致配置以确保顺利实现自动化的必要性。
主要学习内容
- Always verify which account you're operating in - Set up proper profile management early - Use `aws sts get-caller-identity` frequently
- What works in the console might need different approaches in Terraform - Resource relationships need explicit definition - State management is crucial
- OIDC federation setup requires careful configuration - Environment variables affect different tools differently - Multiple authentication methods need careful management
- Always verify account context before operations Implement clear naming conventions Maintain separation of concerns between accounts Document environment variable requirements
拥抱艰难之路
一年前,我做出了一个选择:不再满足于简单的道路。我已经建立了多个 AWS 项目。已经维护了 Linux 服务器。已经获得了 AWS 解决方案架构师认证。但 Terraform?那是我要攀登的下一座山。
控制台很舒服。它是可视化的。它是即时的。但是代码呢?代码要求精确。每个资源关系都必须明确。每个权限都必须定义。每个交互都必须计划好。
这个项目迫使我以不同的方式思考基础设施:
相反,我必须:
是不是更难了?当然。
是不是花了更长时间?毫无疑问。
这值得吗?每一分钟都令人沮丧。
期待
这个平台不仅仅是一个博客——它证明了现代云架构的复杂性和学习机会。每一个挑战都迫使我更深入地研究 AWS 服务、Terraform 行为和云实践。
最终架构遵循 AWS 完善架构框架原则: