本节摘要:基础设施即代码(IaC)用 Terraform、Ansible 等声明式/配置管理工具定义服务器、网络与 K8s 集群——纳入 Git 版本控制,经 CI plan/apply 变更。本节合并云原生集成要点,说明 IaC 如何保证 dev/staging/prod 环境一致性。
阅读完本节,你应当能够:
terraform plan 与人工 approve 后 applyterraform { required_providers { aws = { source = "hashicorp/aws", version = "~> 5.0" } } backend "s3" { bucket = "corp-terraform-state" key = "ci-runners/prod/terraform.tfstate" region = "ap-east-1" } } resource "aws_instance" "jenkins_agent" { ami = "ami-0abcdef1234567890" instance_type = "t3.medium" tags = { Name = "jenkins-agent-prod", Environment = "prod" } }
remote state 在 S3——团队协作锁状态,避免本地 tfstate 丢失。
terraform: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: hashicorp/setup-terraform@v3 - run: terraform init - run: terraform plan -out=plan.tfplan - run: terraform show -no-color plan.tfplan > plan.txt - uses: actions/upload-artifact@v4 with: { name: tfplan, path: plan.tfplan } apply: needs: terraform if: github.ref == 'refs/heads/main' environment: infrastructure # 人工 approve steps: - run: terraform apply -auto-approve plan.tfplan
plan 在 PR,apply 在 main + approve——与 CD 审批同构。
| 工具 | 类型 | 擅长 | CI 阶段 |
|---|---|---|---|
| Terraform | 声明式 provisioning | 云资源 CRUD | plan/apply |
| Ansible | 配置管理 | 装软件、改配置 | playbook |
| Pulumi | 代码式 IaC | 复杂逻辑 | 同 Terraform |
| Crossplane | K8s 原生 | 云资源 K8s CRD | GitOps |
Ansible 示例(装 Docker):
- hosts: app_servers become: yes tasks: - name: Install Docker apt: { name: docker.io, state: present } - name: Start Docker service: { name: docker, state: started }
Terraform 创建 VM,Ansible 配置 VM——先 provision 后 configure。
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: { name: myapp, namespace: argocd } spec: source: repoURL: https://git.corp.com/ops/k8s-manifests path: apps/myapp/overlays/prod targetRevision: main destination: server: https://kubernetes.default.svc namespace: production syncPolicy: automated: { prune: true, selfHeal: true }
Git 中 manifest 变更 → Argo 自动 sync 到集群——部署即 Git merge,与 CI build 镜像分离。
| 模式 | 推送方 | 回滚 |
|---|---|---|
| Push CD | CI kubectl apply | 重跑旧 pipeline |
| GitOps | Argo 拉 Git | Git revert |
⚠️ 常见坑:terraform apply 无 plan 审查——误删
aws_instance生产库一夜消失。PR 必须 attach plan output。
💡 关键直觉:SOURCE 5.2 强调 版本控制一切——IaC 把「服务器长什么样」变成可 diff 的
.tf,与 Dockerfile 同级。
terraform workspace select staging terraform plan -detailed-exitcode # 非零 = drift,staging 与代码定义不一致
定期 cron plan 检测配置漂移——有人手工改 AWS 控制台会暴露。
Terraform 引用 Vault:
data "vault_generic_secret" "db" { path = "secret/prod/db" } resource "aws_db_instance" "main" { password = data.vault_generic_secret.db.data["password"] }
密码不进 .tf 明文——CI 用 OIDC 调 Vault。
CodePipeline Source stage 接 GitHub webhook → CodeBuild 跑 build → CodeDeploy 推 EC2/ECS/Lambda——全 AWS 栈团队的托管 CD。与自托管 Jenkins 比,少运维,vendor lock-in 高。
K8s CRD 管理 RDS、S3——GitOps 统一 app 与 cloud resource:
apiVersion: database.aws.crossplane.io/v1beta1 kind: RDSInstance metadata: { name: prod-db } spec: forProvider: { dbInstanceClass: db.t3.medium, engine: postgres }
Terraform 与 Crossplane 选型:已有 TF 模块库用 TF;K8s-native 团队试 Crossplane。
Packer 构建 VM 镜像,Ansible provision 装 Docker/Jenkins agent——runner 启动从镜像 clone,秒级就绪。与 container runner 比,适合需要 bare metal 性能的场景。
| 项 | Dev | Staging | Prod |
|---|---|---|---|
| K8s 版本 | 同 minor | 同 minor | 同 minor |
| DB 引擎版本 | 同 major | 同 major | 同 major |
| TLS 终止 | 可自签 | 同 prod CA | 生产 CA |
| 外部依赖 | mock/sandbox | sandbox | live |
Dev 用 SQLite、Prod 用 PostgreSQL 是经典 parity 破坏——集成 bug 只在 prod 出现。
下一节 5.3 安全扫描与 Pipeline as Code 收官。
IaC 的核心原则是「环境即版本控制」:服务器、网络、集群的声明全部进 Git,变更走 PR,状态有单一可信源。Terraform 负责 provisioning(创建云资源),Ansible 负责 configuration(在已有主机上装软件配服务),两者分工明确不要混用。plan/apply 分离是 IaC 进 CI 的标准形态:PR 阶段跑 plan 并贴出 diff,apply 在 main 合并后由人工 approve 执行。
落地时的关键决策:remote state 必须放在共享后端(S3+锁/GitLab TF state),防止多人改同一 state;密钥用 Vault/Secret Manager 注入,禁止写进 .tf 明文;定期跑 plan 检测配置漂移。对 K8s 场景,GitOps(Argo CD/Flux)把部署变成 Git 的 apply,天然具备审计与回滚能力。IaC 的最终目标是环境可重建:一个 prod 环境能从 Git 的 manifest 完全重建,而不依赖任何手工操作。