Terraform 高级
Source: Dev.to
为什么要使用 Terraform?
Terraform 用于 自动化云基础设施,让人们不必手动创建:
- VPC
- 子网
- 安全组
- ECS 集群
- 任务定义
- 负载均衡器
- IAM 角色
- RDS
- S3
- DynamoDB
- Secrets
- ECR 注册表
- Route53
- CloudWatch 警报
没有 Terraform 时
- 工程师在控制台上点点点
- 没有历史记录
- 没有审查/追踪
- 意外的错误配置
- 难以复现环境
- 失败后难以恢复
- 难以扩展
- 不可能维护数十个环境
使用 Terraform 时
一切都是 代码,整个基础设施都是 可重复 的:
- 从头重新创建整个系统
- 团队使用 Git 历史、PR 审查、CI/CD 流水线
- 一条命令即可正确更新所有云资源
你的项目包括:
- 7 个微服务(Python)
- ECS 集群
- ALB
- Couchbase
- Confluent Cloud
- PostgreSQL/RDS
- VPN / VPC
- Kafka Broker
- Lambda(可选)
- S3 状态后端
每位高级 DevOps 必须了解的 Terraform 核心概念
(A) Terraform 是
- 声明式 —— 你描述 想要什么,Terraform 决定 如何 构建。
(B) Terraform 文件
| 文件 | 用途 |
|---|---|
provider.tf | AWS 提供商配置 |
backend.tf | S3 + DynamoDB 状态存储 |
variables.tf | 模块使用的输入变量 |
ecs.tf | ECS 集群、服务、任务定义 |
alb.tf | 负载均衡器、监听器、目标组 |
rds.tf | PostgreSQL RDS 实例 |
network.tf | VPC + 子网(或复用已有 VPC) |
sg.tf | 安全组 |
outputs.tf | 导出有用的值(ALB DNS、SG ID 等) |
在面试中,你必须能够解释每个文件存在的原因。
Terraform 状态 —— 公司期望你了解的内容
Terraform 将它创建的所有内容记在:
terraform.tfstate
状态文件包含:
- 所有 AWS 资源 ID
- 资源之间的依赖关系
- 当前配置
- 每个资源的属性
🚨 此文件至关重要——丢失它将是灾难性的。
企业从不在本地存储 tfstate;它们使用远程后端:
- S3 → 存放
.tfstate文件 - DynamoDB → 管理状态锁
为什么使用 S3 后端?(你的项目示例)
你的项目涉及:
- GitHub Actions
- 在不同机器上的本地开发
- 多次执行
terraform apply
如果每台机器都存本地 tfstate,会出现:
- 并发 apply 时相互覆盖
- GitHub Actions 看不到本地更改
- Terraform 混乱导致重复或破坏性操作
S3 解决了这些问题:
- 为所有 Terraform 运行提供统一的中心状态
- GitHub Actions 与本地机器读取相同的状态
- 可以安全删除本地
terraform.tfstate文件 - 状态被版本化 → 可回滚
为什么使用 DynamoDB 锁?(你今天遇到的具体问题)
Terraform 必须防止 并发 apply。在一次运行期间:
terraform plan
terraform apply
Terraform 会在 DynamoDB 中写入锁:
LockID = kafka-enterprise-orders-tfstate/terraform.tfstate
- 如果 GitHub Actions 在本地运行仍在进行时启动,锁会阻止冲突。
- 如果之前的运行崩溃,锁可能会一直残留,需要手动删除。
Terraform Apply 流程(你的项目真实流程)
-
terraform init- 下载 AWS 提供商
- 读取后端配置
- 连接到 S3 和 DynamoDB
-
terraform plan- 将期望的基础设施(代码)与实际的 AWS 状态进行比较
- 显示计划的更改
-
terraform apply- 创建/更新 ECS 任务定义和服务
- 更新 ALB 目标组和监听器
- 修改安全组和子网关联
- 管理 IAM 角色
- 如有需要创建 RDS 实例
- 生成输出(ALB DNS、SG ID 等)
Terraform 漂移检测(高级岗位非常重要)
Terraform 总是检测状态文件与真实资源之间的漂移。
案例 1 – 子网被手动删除
Terraform 报告:
InvalidSubnetID.NotFound
随后尝试通过重新创建缺失的子网来纠正漂移(或使运行失败,提示手动修复)。
Terraform 变量与 Secrets(你的项目)
你从 GitHub Actions 向 Terraform 传递以下变量:
TF_VAR_container_image_producer
TF_VAR_container_image_payment
TF_VAR_container_image_fraud
TF_VAR_container_image_analytics
TF_VAR_web_backend_image
TF_VAR_web_frontend_image
TF_VAR_confluent_bootstrap_servers
TF_VAR_confluent_api_key
TF_VAR_confluent_api_secret
TF_VAR_rds_password
TF_VAR_existing_vpc_id
TF_VAR_existing_public_subnet_ids
TF_VAR_existing_private_subnet_ids
TF_VAR_existing_ecs_tasks_sg_id
TF_VAR_existing_alb_sg_id
TF_VAR_existing_rds_sg_id
这些变量使代码能够在每次部署时动态读取容器镜像和其他 Secrets。当代码推送后,CI/CD 会构建镜像、推送到 GHCR,并将镜像标签注入 Terraform,进而更新 ECS 任务定义。
高级 DevOps 面试中的 Terraform —— 面试官的期待
必备知识点
- Terraform 状态
- 后端(S3、Azure Blob、GCS)
- 锁定(DynamoDB)
- 模块
- 工作区
- 提供商
- 数据源
- 变量与输出
- 依赖图
- 生命周期规则
terraform importterraform taintterraform graph- CI/CD 流水线
- Secrets 管理
如何用真实案例解释
“我们的 Terraform 管理 ECS、ALB、VPC、RDS、SG 以及 Kafka 资源。
状态集中存放在 S3,使用 DynamoDB 锁防止并发问题。
GitHub Actions 通过TF_VAR_变量将 CI 中构建的镜像注入 ECS 任务定义。”
为什么在 你的项目 中必须使用 Terraform
你有 17+ 个相互依赖的 AWS 资源需要一起更新:
- 更换容器镜像 → 更新 ECS 任务
- 更改端口 → 更新 ALB 目标组
- 更换 AWS 区域 → VPC、子网、RDS 必须重新创建
- 更换 Kafka 集群 → 环境变量更新
- 更改安全组 → ECS 与 ALB 更新
Terraform 能保证所有资源的正确顺序和一致性。
Terraform 的内部工作原理(“图论”)
Terraform 构建依赖图:
aws_vpc -> subnets -> route tables -> security groups ->
alb -> ecs_cluster -> ecs_services -> tasks
随后执行操作:
- 并行 处理相互独立的资源
- 顺序 处理有依赖关系的资源
你今天的 ECS 错误 —— Terraform 检测到的基础设施问题
- 安全组无效 – 某个 Secret 含有非法值,Terraform 拒绝了它。
- 子网被手动删除 – Terraform 警告缺失的子网,你随后纠正了子网 ID。
Terraform CI/CD —— 你的流水线
- 构建 Docker 镜像
- 将镜像推送到 GitHub Container Registry
- 运行 Terraform(plan & apply)
- 使用新任务定义更新 ECS 服务
- 新容器即时部署
此工作流提供了企业级、可重复的部署过程。