当你的团队决定引入基础设施即代码时,第一个问题往往不是“用什么工具”,而是“从哪里开始”。你可能已经用Terraform或CloudFormation写了一些配置文件,但发现它们和手点控制台没有本质区别:没有版本控制、没有评审、改坏了只能靠人肉回滚。这正是本文要解决的问题——在DevOps流程中把基础设施真正当作代码来管理,而不是把配置文件堆在某个共享文件夹里。
先解决版本控制:没有Git的IaC等于没做
基础设施即代码的核心是“代码”二字,而代码的第一步就是版本控制。如果你还没有把所有基础设施定义文件(比如Terraform的.tf文件、Ansible的playbook)纳入Git仓库,那么后续的自动化、协作、回滚都无从谈起。
操作上,你需要为基础设施单独建一个仓库(或至少一个目录),并制定分支策略。常见的做法是:main分支对应生产环境,develop分支对应预发,功能分支对应开发环境。每次修改基础设施配置,都走Pull Request流程,让至少一个人review变更。
常见误区:把密钥或敏感信息直接写在配置文件里提交到Git。这会让你的云账号暴露在风险中。正确做法是使用密钥管理工具(如Vault、AWS Secrets Manager)或环境变量注入。
把IaC集成到CI/CD流水线
有了版本控制,下一步是让流水线自动执行基础设施变更。以GitHub Actions为例,你可以创建一个workflow,在Push到main分支时运行terraform plan和terraform apply。但直接在生产环境自动apply是有风险的,你需要设置合理的审批门禁。
一个实用的模式是:在Pull Request时运行terraform plan并输出变更预览,人工确认后再合并。合并后,另一个workflow负责apply。这样既保证了自动化,又保留了人工判断的环节。
失败条件:如果plan阶段出现错误(比如语法错误、资源冲突),流水线应该失败并通知开发者,而不是跳过检查直接apply。你也可以使用类似terraform validate和terraform fmt的静态检查来提前发现问题。
让可观测性配置也变成代码
很多团队在实现IaC时只关注计算资源(如虚拟机、容器),却忽略了监控和告警配置。但可观测性本身也是基础设施的一部分。如果你用Prometheus监控系统,那么告警规则和抓取配置应该和你的应用代码一起版本化。
Prometheus的配置(如prometheus.yml)和告警规则文件都是文本格式,完全可以纳入Git仓库。这样,当告警规则变更时,你可以通过代码评审来避免误报或漏报。Prometheus是云原生计算基金会(CNCF)的项目,它收集和存储指标作为时间序列数据,并支持标签(labels)来区分不同维度的数据。
操作建议:将Prometheus的配置和告警规则放在独立的仓库或目录中,并编写自动化测试来验证规则的正确性(比如使用promtool)。同时,考虑使用OpenTelemetry来统一采集指标、日志和追踪,它的配置也是代码化的,而且支持多种后端,避免厂商锁定。
处理环境差异:开发、测试、生产
一个常见的陷阱是“环境漂移”:开发环境、测试环境、生产环境的配置不一致,导致在测试环境验证通过的变更,到了生产环境却失败。使用IaC时,你需要通过参数化或模块化来管理环境差异。
例如,在Terraform中,你可以使用变量文件(如terraform.tfvars)来区分不同环境,但要注意保持变量命名一致,避免硬编码。另一种做法是使用Workspace或目录结构来隔离环境。
取舍:完全相同的配置在三个环境几乎不可能,但你可以通过“配置漂移检测”工具(如driftctl)来定期对比实际资源与代码定义的差异,及时修复漂移。
安全与合规:把检查嵌入流水线
基础设施变更涉及安全风险,因此你需要将安全扫描集成到CI/CD中。例如,使用tfsec或checkov扫描Terraform代码中的安全漏洞,使用trivy扫描容器镜像。这些工具都可以在GitHub Actions中运行,并在发现问题时阻止合并。
另外,对于合规要求(如PCI-DSS),你需要确保基础设施变更留有审计日志。Git本身就是一个审计日志,但你可能还需要记录谁在什么时间执行了apply操作。这可以通过CI/CD系统的日志来实现。
常见误区与解决方案
误区一:把IaC工具当万能药。IaC能管理资源生命周期,但无法解决架构设计问题。比如,如果你的应用是无状态的,IaC可以轻松重建;但如果是有状态的数据库,你可能需要额外处理数据迁移。
误区二:忽略状态文件的管理。Terraform的状态文件(terraform.tfstate)记录了资源与代码的映射,如果多人同时操作而不锁定,会导致冲突。你需要将状态文件存储在远程后端(如S3、GCS),并启用锁机制。
误区三:不测试基础设施代码。和应用程序一样,基础设施代码也需要测试。你可以使用Terratest等工具编写集成测试,在临时环境中验证基础设施的正确性。
参考资料
延伸阅读
