基础设施即代码
前言
你有没有经历过这种噩梦:线上服务器挂了,但没人记得当初是怎么配置的? 手动登录服务器、凭记忆敲命令、祈祷不要敲错——这就是传统运维的日常。基础设施即代码(Infrastructure as Code,IaC)彻底改变了这一切:用代码来定义和管理基础设施,让服务器配置像软件一样可版本控制、可复现、可审计。
这篇文章会带你学什么?
学完这章后,你将获得:
- 核心概念:理解 IaC 是什么,为什么它是现代运维的基石
- 工作流认知:掌握 Terraform 的 Write → Plan → Apply → Destroy 四阶段流程
- 工具选型:了解 Terraform、Pulumi、CloudFormation 等主流工具的优劣
- 风险意识:理解配置漂移的危害和检测方法
- 最佳实践:掌握 IaC 项目的工程化管理方法
| 章节 | 内容 | 核心概念 |
|---|---|---|
| 第 1 章 | IaC 概念 | 手动运维 vs 代码化管理 |
| 第 2 章 | Terraform 工作流 | Write → Plan → Apply |
| 第 3 章 | 工具对比 | Terraform、Pulumi、CDK |
| 第 4 章 | 配置漂移 | 检测、预防、修复 |
| 第 5 章 | 最佳实践 | 模块化、状态管理、CI/CD |
0. 全景图:为什么基础设施也需要"源代码"?
想象你是一个厨师。如果每道菜都凭感觉做,今天放一勺盐、明天放两勺,味道永远不稳定。但如果你把配方写下来——精确到每种调料的克数——任何人都能复现同样的味道。
基础设施管理面临的是同样的问题。一台服务器的配置可能涉及操作系统、网络规则、安全组、存储卷、环境变量等几十个参数。手动配置不仅容易出错,而且不可复现、不可审计、不可回滚。
IaC 的核心价值
- 可复现:同一份代码,无论执行多少次,结果都一样(幂等性)
- 可版本控制:基础设施变更通过 Git 管理,谁改了什么、为什么改,一目了然
- 可审计:所有变更都有记录,满足合规要求
- 可自动化:通过 CI/CD 流水线自动部署,消除人为操作风险
- 可协作:团队成员通过 Pull Request 审查基础设施变更,就像审查代码一样
1. IaC 概念:从"手动点击"到"代码声明"
传统运维的工作方式是:登录云平台控制台,手动点击创建服务器、配置网络、设置安全组。这种方式在管理几台服务器时还能应付,但当规模扩大到几十、几百台时,就变成了噩梦。
IaC 的核心思想是:用声明式代码描述你想要的基础设施状态,让工具自动帮你实现。你不需要告诉工具"先创建 VPC,再创建子网,再创建安全组"(命令式),只需要说"我要一个这样的网络环境"(声明式),工具会自动计算出需要执行的步骤。
| 对比维度 | 手动运维 | 基础设施即代码 |
|---|---|---|
| 可重复性 | 每次操作可能不同 | 代码保证完全一致 |
| 速度 | 分钟到小时级 | 秒到分钟级 |
| 审计追踪 | 依赖人工记录 | Git 历史自动记录 |
| 协作 | 口头传达、截图 | Code Review、PR 流程 |
| 回滚 | 几乎不可能 | git revert 一键回滚 |
| 维度 | 手动运维 | 基础设施即代码 |
|---|---|---|
| 操作方式 | 登录控制台点击 | 编写代码文件 |
| 可复现性 | 依赖文档和记忆 | 代码即文档,100% 可复现 |
| 变更追踪 | 无记录或记录不全 | Git 版本控制,完整历史 |
| 协作方式 | 口头沟通、文档传递 | Pull Request 审查 |
| 回滚能力 | 手动逆向操作 | git revert + 重新 apply |
| 一致性 | 环境间差异大 | 开发/测试/生产完全一致 |
声明式 vs 命令式
- 声明式(Declarative):描述"我要什么",工具自动计算"怎么做"。Terraform、CloudFormation 采用这种方式。优点是幂等性好,缺点是灵活性受限。
- 命令式(Imperative):描述"怎么做",一步步执行。Ansible、Shell 脚本采用这种方式。优点是灵活,缺点是难以保证幂等性。
- 混合式:Pulumi、AWS CDK 用通用编程语言编写,兼具声明式的状态管理和命令式的灵活性。
2. Terraform 工作流:Write → Plan → Apply
Terraform 是目前最流行的 IaC 工具,由 HashiCorp 开发。它的工作流程清晰直观,分为四个阶段,就像软件开发的"编码→审查→部署→清理"。
用声明式语言(HCL)描述你期望的基础设施状态。代码就是文档,可以提交到 Git 进行版本管理和 Code Review。
四阶段工作流
- Write(编写):用 HCL(HashiCorp Configuration Language)编写基础设施定义文件(.tf)。声明你需要的资源:服务器、数据库、网络等。
- Plan(计划):运行
terraform plan,Terraform 会对比当前状态和目标状态,生成一份"执行计划"——告诉你它打算创建、修改、删除哪些资源。这是安全网,让你在真正执行前确认变更。 - Apply(执行):确认计划无误后,运行
terraform apply,Terraform 按计划创建或修改资源。执行完成后,当前状态会保存到状态文件(terraform.tfstate)。 - Destroy(销毁):不再需要时,运行
terraform destroy清理所有资源,避免产生不必要的费用。
| 命令 | 作用 | 是否修改基础设施 | 使用场景 |
|---|---|---|---|
terraform init | 初始化项目,下载 Provider | 否 | 首次使用或添加新 Provider |
terraform plan | 预览变更,生成执行计划 | 否 | 每次变更前必须执行 |
terraform apply | 执行变更,创建/修改资源 | 是 | 确认 plan 后执行 |
terraform destroy | 销毁所有资源 | 是 | 清理测试环境、下线服务 |
terraform state | 查看/管理状态文件 | 视操作而定 | 状态迁移、资源导入 |
3. 工具对比:选择适合你的 IaC 工具
IaC 领域有多种工具,各有侧重。选择工具时需要考虑团队技术栈、云平台、项目规模等因素。没有"最好"的工具,只有最适合你场景的工具。
| 特性 | Terraform | CloudFormation |
|---|---|---|
| 厂商 | HashiCorp | AWS |
| 配置语言 | HCL | YAML / JSON |
| 声明式/命令式 | 声明式 | 声明式 |
| 多云支持 | 原生多云 | 仅 AWS |
| 状态管理 | State 文件 | AWS 托管 |
| 学习曲线 | 中等 | 中等偏高 |
| 社区生态 | 非常活跃 | AWS 生态 |
| 最佳场景 | 多云/混合云 | 纯 AWS 环境 |
| 工具 | 语言 | 云平台支持 | 学习曲线 | 适用场景 |
|---|---|---|---|---|
| Terraform | HCL | 多云(AWS/Azure/GCP) | 中等 | 多云环境、团队协作 |
| Pulumi | Python/TS/Go | 多云 | 低(熟悉编程语言) | 开发者友好、复杂逻辑 |
| AWS CloudFormation | JSON/YAML | 仅 AWS | 中等 | 纯 AWS 环境 |
| AWS CDK | Python/TS/Java | 仅 AWS | 低 | AWS + 编程语言偏好 |
| Ansible | YAML | 多云 + 裸机 | 低 | 配置管理、混合环境 |
如何选择?
- 初创团队 / 单云:CloudFormation(AWS)或对应云平台原生工具,生态集成最好
- 多云 / 中大型团队:Terraform,社区最大、Provider 最丰富、招聘最容易
- 开发者主导的团队:Pulumi 或 CDK,用熟悉的编程语言写基础设施,IDE 支持好
- 需要配置管理:Ansible,擅长服务器内部配置(安装软件、修改配置文件)
4. 配置漂移:无声的定时炸弹
配置漂移(Configuration Drift)是 IaC 实践中最隐蔽的敌人。它指的是实际基础设施状态与代码定义的状态之间逐渐产生偏差。
这种偏差通常是怎么产生的?有人为了"快速修复"一个线上问题,直接登录控制台手动改了安全组规则;有人为了调试,临时加大了某台服务器的配置但忘了改回来。这些"小改动"日积月累,最终导致代码和实际环境严重脱节。
团队使用 Terraform 部署了 3 台 Web 服务器,配置完全一致:Nginx 1.24、端口 443、2GB 内存。代码和实际状态完美匹配。
配置漂移的危害
- 不可复现:代码描述的环境和实际环境不一致,新建环境时会出问题
- 回滚失败:以为回滚到上一版本就能恢复,但实际环境已经被手动修改过
- 安全隐患:手动开放的端口、放宽的权限可能被遗忘,成为攻击入口
- 审计失效:合规审计基于代码,但代码不反映真实状态
| 预防措施 | 说明 |
|---|---|
| 禁止手动变更 | 通过 IAM 策略限制控制台操作权限 |
| 定期漂移检测 | 定时运行 terraform plan 检查差异 |
| 自动修复 | 检测到漂移后自动执行 apply 恢复一致性 |
| 变更审计 | 开启 CloudTrail 等审计日志,追踪所有变更来源 |
5. 最佳实践:让 IaC 项目可持续演进
IaC 代码和应用代码一样,需要良好的工程实践来保证可维护性。随着基础设施规模增长,没有章法的 IaC 代码会变成另一种形式的"技术债"。
# 忽略本地状态文件
*.tfstate
*.tfstate.backup
.terraform/
# 忽略敏感变量文件
*.tfvars
!example.tfvars六条核心最佳实践
- 模块化:将可复用的基础设施抽象为模块(如 VPC 模块、数据库模块),避免复制粘贴。就像写函数一样,一处定义、多处调用。
- 环境隔离:开发、测试、生产使用独立的状态文件和变量文件,通过 workspace 或目录结构隔离。
- 远程状态管理:状态文件(tfstate)存储在远程后端(S3 + DynamoDB),支持团队协作和状态锁定,避免并发冲突。
- 敏感信息管理:密码、密钥等敏感信息不要写在代码里,使用 Vault、AWS Secrets Manager 等工具管理。
- CI/CD 集成:将 terraform plan 集成到 PR 流程,apply 通过流水线自动执行,杜绝本地手动操作。
- 代码审查:基础设施变更和应用代码一样需要 Code Review,尤其是涉及安全组、IAM 策略的变更。
总结
基础设施即代码是现代云原生运维的基石。它把"不可描述的手动操作"变成了"可版本控制的代码",让基础设施管理从"艺术"变成了"工程"。
回顾本章的关键要点:
- IaC 的本质:用代码声明基础设施的期望状态,让工具自动实现
- Terraform 工作流:Write → Plan → Apply 三步走,Plan 是安全网
- 工具选型:多云选 Terraform,单云选原生工具,开发者团队选 Pulumi
- 配置漂移:最隐蔽的风险,需要通过流程和工具双重防护
- 工程化管理:模块化、环境隔离、远程状态、CI/CD 集成缺一不可
延伸阅读
- Terraform 官方教程 - 从零开始学 Terraform
- Pulumi 文档 - 用编程语言写基础设施
- AWS CDK Workshop - AWS CDK 实战教程
- Infrastructure as Code (O'Reilly) - IaC 领域的经典书籍
- Spacelift Blog - IaC 最佳实践和行业趋势
