626 字
2 分钟
Infrastructure as Code 基础设施即代码
凌晨两点,生产环境的数据库服务器配置被手动修改导致宕机,而没有人能说清楚到底改了什么。如果基础设施的每一项变更都像代码一样有版本记录、可审查、可回滚,这类事故就不会发生。Infrastructure as Code(IaC,基础设施即代码) 正是解决这个问题的方法论。
一、IaC 概述
1. IaC 核心概念
graph TB
subgraph "IaC 优势"
A["版本控制"] --> D["可重复"]
B["自动化"] --> D
C["一致性"] --> D
E["审计追踪"] --> D
end
| 特性 | 说明 |
|---|---|
| 声明式 | 定义期望状态 |
| 版本控制 | Git 管理基础设施 |
| 自动化 | 减少人工操作 |
| 可测试 | 验证基础设施变更 |
2. 工具对比
| 工具 | 类型 | 语言 | 适用场景 |
|---|---|---|---|
| Terraform | 声明式 | HCL | 多云资源管理 |
| Pulumi | 声明式 | Python/TS | 开发者友好 |
| Ansible | 过程式 | YAML | 配置管理 |
| CloudFormation | 声明式 | JSON/YAML | AWS 专用 |
二、Terraform 实践
1. 基础配置
Terraform 是 HashiCorp 开源的基础设施编排工具,使用 HCL(HashiCorp Configuration Language) 作为配置语言,支持多云资源管理。
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } }
backend "s3" { bucket = "tf-state-bucket" key = "prod/terraform.tfstate" region = "us-east-1" dynamodb_table = "tf-locks" }}
provider "aws" { region = "us-east-1"}
# 变量定义variable "environment" { type = string default = "production"}
# 资源定义resource "aws_instance" "app" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.medium"
tags = { Name = "app-${var.environment}" Environment = var.environment }}2. 模块化设计
module "vpc" { source = "./modules/vpc"
environment = var.environment cidr_block = var.vpc_cidr
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true single_nat_gateway = false}
# modules/vpc/variables.tfvariable "environment" { type = string}
variable "vpc_cidr" { type = string}
variable "private_subnets" { type = list(string)}
variable "public_subnets" { type = list(string)}3. 状态管理
State(状态文件) 是 Terraform 追踪真实基础设施与配置映射关系的核心机制,必须妥善存储和保护。
# 状态锁定terraform { backend "s3" { # DynamoDB 表用于状态锁定 lock_table = "terraform-locks" }}
# 导入现有资源terraform import aws_instance.existing i-1234567890abcdef0
# 查看状态terraform showterraform state listterraform state mv aws_instance.old aws_instance.new三、Ansible 实践
Ansible 是 Red Hat 维护的开源自动化工具,采用 Agentless(无代理) 架构,通过 SSH 连接目标主机执行任务。
1. 主机清单
[webservers]web1.example.com ansible_host=10.0.1.1web2.example.com ansible_host=10.0.1.2
[databases]db1.example.com ansible_host=10.0.2.1
[production:children]webserversdatabases
[production:vars]ansible_user=ubuntuansible_python_interpreter=/usr/bin/python32. Playbook
Playbook 是 Ansible 的任务编排文件,使用 YAML 格式定义配置、部署和编排的自动化流程。
- name: Deploy Application hosts: webservers become: yes
vars: app_version: "1.0.0" app_port: 8080
tasks: - name: Install dependencies apt: name: - nginx - python3-pip state: present update_cache: yes
- name: Deploy application git: repo: "https://github.com/org/app.git" dest: /opt/app version: "{{ app_version }}" force: yes
- name: Configure nginx template: src: nginx.conf.j2 dest: /etc/nginx/conf.d/app.conf notify: Restart nginx
- name: Start application systemd: name: app state: started enabled: yes daemon_reload: yes
- name: Wait for application wait_for: port: "{{ app_port }}" delay: 5 timeout: 60
handlers: - name: Restart nginx systemd: name: nginx state: restarted3. Roles 结构
Roles(角色) 是 Ansible 组织 Playbook 的标准方式,将任务、变量、模板和处理器按目录结构分离。
# roles 应用结构roles/├── common/│ ├── tasks/│ │ └── main.yml│ ├── handlers/│ │ └── main.yml│ └── templates/│ └── motd.j2├── nginx/│ ├── tasks/│ │ └── main.yml│ ├── handlers/│ │ └── main.yml│ └── templates/│ └── nginx.conf.j2└── app/ ├── tasks/ │ └── main.yml ├── templates/ │ └── app.conf.j2 └── vars/ └── main.yml四、Pulumi 实践
Pulumi 是新一代 IaC 工具,允许使用通用编程语言(如 TypeScript、Python、Go)定义基础设施,相比 HCL 更适合开发者。
1. TypeScript 示例
import * as pulumi from "@pulumi/pulumi";import * as aws from "@pulumi/aws";
// 创建 VPCconst vpc = new aws.ec2.Vpc("app-vpc", { cidrBlock: "10.0.0.0/16", enableDnsHostnames: true, enableDnsSupport: true, tags: { Name: "app-vpc", Environment: pulumi.getStack(), },});
// 创建子网const subnet = new aws.ec2.Subnet("app-subnet", { vpcId: vpc.id, cidrBlock: "10.0.1.0/24", availabilityZone: "us-east-1a", tags: { Name: "app-subnet", },});
// 创建 ECS 集群const cluster = new aws.ecs.Cluster("app-cluster", { name: "app-cluster", settings: [ { name: "containerInsights", value: "enabled", }, ],});
// 导出export const vpcId = vpc.id;export const clusterName = cluster.name;export const subnetId = subnet.id;2. 跨云部署
import * as aws from "@pulumi/aws";import * as azure from "@pulumi/azure-native";import * as gcp from "@pulumi/gcp";
// 统一的网络接口interface NetworkConfig { vpcCidr: string; tags: Record<string, string>;}
// AWS VPCexport function createAwsNetwork(config: NetworkConfig) { return new aws.ec2.Vpc("vpc", { cidrBlock: config.vpcCidr, tags: config.tags, });}
// Azure Virtual Networkexport function createAzureNetwork(config: NetworkConfig) { return new azure.network.VirtualNetwork("vnet", { resourceGroupName: "my-rg", addressSpace: [config.vpcCidr], tags: config.tags, });}
// GCP Networkexport function createGcpNetwork(config: NetworkConfig) { return new gcp.compute.Network("network", { autoCreateSubnetworks: false, routingConfig: { routingMode: "REGIONAL", }, });}五、CI/CD 集成
1. Terraform CI/CD
name: Terraform CI/CD
on: push: branches: [main] pull_request:
jobs: terraform: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3 with: terraform_version: 1.6.0
- name: Terraform Init run: terraform init env: TF_VAR aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }} TF_VAR aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Format Check run: terraform fmt -check
- name: Terraform Validate run: terraform validate
- name: Terraform Plan run: terraform plan -no-color env: TF_VAR aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }} TF_VAR aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Apply if: github.ref == 'refs/heads/main' && github.event_name == 'push' run: terraform apply -auto-approve env: TF_VAR aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }} TF_VAR aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}2. Ansible CI/CD
name: Ansible CI/CD
on: push: paths: - "ansible/**" - "inventory/**"
jobs: ansible-lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Install ansible-lint run: pip install ansible-lint
- name: Run ansible-lint run: ansible-lint
molecule-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Molecule Test run: | pip install molecule ansible molecule test六、总结
graph TB
A["IaC 工具"] --> B["Terraform"]
A --> C["Ansible"]
A --> D["Pulumi"]
B --> E["声明式 HCL"]
C --> F["过程式 YAML"]
D --> G["声明式代码"]
| 工具 | 优势 | 劣势 |
|---|---|---|
| Terraform | 多云支持、状态管理 | HCL 学习曲线 |
| Ansible | 简单易用、Agentless | 过程式、难以测试 |
| Pulumi | 开发者友好、类型安全 | 相对较新 |
最佳实践:
- 使用版本控制管理所有配置文件
- 模块化设计提高复用性
- 状态文件存储在远程后端
- 变更前先 plan 后 apply
- 自动化测试验证配置
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
Infrastructure as Code 基础设施即代码
https://blog.souloss.com/posts/deploy/deploy-infrastructure-as-code/ 部分信息可能已经过时
相关文章 智能推荐
1
综合实战:构建一个迷你容器运行时
容器运行时 综合实战——用 Go 从零构建一个迷你容器运行时——实现 Namespace 隔离(PID/Mount/UTS/IPC/Network)、Cgroup 资源限制(CPU/内存)、OverlayFS 分层文件系统、OCI Bundle 解析,最终实现一个能运行容器的 minirunc。将前 15 章的知识融会贯通,从「理解原理」到「动手实现」。
2
综合实战:构建事件驱动系统
消息队列与事件流 综合实战——构建订单事件驱动系统——Kafka + Schema Registry + Kafka Streams + 事务性发件箱。
3
揭开大模型的工作黑盒:Token与概率
AI 揭开大模型的工作黑盒——Token与概率
4
创意头脑风暴与思维碰撞
创意 创意头脑风暴方法论与思维碰撞技巧——从随机词联想到达芬奇笔记的创新实践,掌握系统化的创意生成方法。
5
内存知识
性能 内存硬件基础知识——内存类型、访问延迟、NUMA 架构与 CPU 缓存机制对程序性能的影响,以及缓存友好代码的编写模式。






