1. AWS网络基础设施即代码工程导论
在传统AWS网络建设中,VPC、子网、路由表、安全组、NAT网关、对等连接等资源通常通过控制台逐项点击创建。这种方式在单账号、单环境、少量资源时勉强可行,但一旦扩展到多账号、多可用区、多环境,手工操作就会带来三类问题:配置漂移、变更不可追溯、环境无法快速复制。基础设施即代码(Infrastructure as Code,IaC)正是为了解决这些问题而出现的工程实践。
本课程的目标不是简单介绍某个工具的命令,而是建立一套完整的工程能力:能够用代码描述AWS网络拓扑,能够把代码安全地应用到多个账号和环境,能够对网络变更进行审查、测试和回滚,并最终把网络基础设施纳入持续交付流水线。学完本课程后,你应该能够独立设计一个可复用的AWS网络IaC工程结构,并用它管理生产级VPC网络。
核心概念:从“点击”到“声明”
IaC的核心思想是声明式描述:你不再告诉AWS“先创建VPC,再创建子网”,而是声明“我需要一个CIDR为10.0.0.0/16的VPC,以及三个公有子网和三个私有子网”。工具负责计算差异并执行变更。这里有两个关键概念:
- 期望状态:代码中声明的网络资源规格,例如VPC的CIDR、子网的可用区、路由表的关联关系。
- 实际状态:AWS中当前真实存在的资源。IaC工具通过对比期望状态和实际状态,生成执行计划。
另一个重要概念是状态管理。以Terraform为例,它使用state文件记录资源与代码的映射关系。state文件不是“配置文件”,而是“账本”:它告诉Terraform“代码里的aws_vpc.main对应AWS中的vpc-0abc123”。如果state丢失或损坏,Terraform就无法正确判断资源是否需要重建。因此,远程state存储(如S3 + DynamoDB锁)是生产环境的基本要求。
IaC在AWS网络中的价值
AWS网络资源具有强关联性:VPC包含子网,子网关联路由表,路由表包含路由条目,安全组引用其他安全组。手工创建时,这些依赖关系靠人脑记忆;IaC则通过依赖图自动排序。例如,Terraform会先创建VPC,再创建子网,最后创建路由表关联,因为代码中通过引用表达了依赖。
具体价值可以归纳为四点:
| 价值维度 | 手工操作 | IaC工程 |
|---|---|---|
| 可重复性 | 依赖操作者记忆,容易遗漏 | 同一份代码可反复部署出相同网络 |
| 变更审查 | 无法提前看到影响范围 | plan输出可审查,变更前可知增删改 |
| 多环境一致性 | 开发、测试、生产网络容易不一致 | 通过变量和模块复用同一套逻辑 |
| 灾难恢复 | 重建网络耗时且易错 | 代码即文档,可快速重建 |
以“新增一个私有子网”为例。手工操作需要在控制台选择VPC、填写CIDR、选择可用区、关联路由表、配置NAT路由,至少五步。IaC中只需在子网资源列表中增加一个声明,并在路由表关联中增加一条引用。执行terraform plan后,输出会明确显示“将新增1个子网、1个路由表关联”,其他资源不变。这种可预测性正是网络工程最需要的。
工具链概览
AWS网络IaC的工具链可以分为四层:
- 描述层:Terraform(HCL)、AWS CloudFormation(YAML/JSON)、AWS CDK(TypeScript/Python)。Terraform跨云通用,CDK适合熟悉编程语言的团队,CloudFormation与AWS集成最深。
- 状态与后端层:Terraform state存于S3,DynamoDB提供锁;CloudFormation由AWS托管状态。
- 验证层:
terraform validate检查语法,terraform plan检查变更,tflint检查规范,checkov检查安全合规。 - 交付层:GitHub Actions、GitLab CI、AWS CodePipeline,把plan和apply纳入流水线,实现审批后自动部署。
本课程以Terraform为主线,因为它在AWS网络场景中生态最成熟、模块最丰富。但所讲的工程方法——模块化、环境隔离、状态管理、变更审查——同样适用于CloudFormation和CDK。
学习路径与工程习惯
本课程按“先单点、后组合、再流水线”的路径展开。第一阶段掌握VPC、子网、路由表、安全组等基础资源的代码化;第二阶段学习模块化,把可复用的网络模式封装成模块;第三阶段引入多环境、多账号和远程状态;第四阶段把IaC接入CI/CD,实现变更审查和自动部署。
在开始写第一行代码前,建议先建立三个工程习惯。第一,所有网络资源都进代码,包括安全组规则和路由条目,不要留“控制台手工补一条”的尾巴。第二,每次变更先plan后apply,把plan输出当作代码审查的一部分。第三,用变量区分环境,不要把生产CIDR硬编码在资源块里。例如:
variable "vpc_cidr" {
description = "VPC CIDR block"
type = string
default = "10.0.0.0/16"
}
variable "azs" {
description = "Availability Zones"
type = list(string)
default = ["us-east-1a", "us-east-1b", "us-east-1c"]
}
这样,开发环境可以用10.1.0.0/16,生产环境用10.0.0.0/16,而子网划分逻辑完全复用。判断IaC工程是否合格,有一个简单标准:把代码仓库交给另一位工程师,他能否在不问你的情况下,部署出一套与你完全相同的网络?如果答案是肯定的,说明你的代码已经具备了可重复性和自描述性。