云原生技术07-Ansible vs Terraform:我该用哪个?2026年IaC工具选型指南
「知识图谱生成工具」:一键将文件夹内容变身为交互式知识图谱的免安装桌面工具(文末附免费下载链接)-CSDN博客
CSDN AI数字营销功能实测:CSDN AI内容创作,10分钟从技术选题到成文,技术博主最值得开通的功能,没有之一-CSDN博客
告别多平台搬运噩梦,CSDN 多平台发布功能让内容分发效率提升 10 倍-CSDN博客
目录
- 开篇:为什么你需要IaC?
- Terraform:声明式配置的王者
- Ansible:过程式运维的老将
- Pulumi:用代码写基础设施
- Terragrunt:Terraform的"大管家"
- Provider选择指南
- 实战对比:创建一套完整环境
- 2026年选型建议
- 文末三件套
开篇:为什么你需要IaC?
你是否遇到过手动创建云资源后忘记记录、环境重建时一脸懵、团队协作时"谁改了这台机器"的混乱?基础设施即代码(Infrastructure as Code,简称IaC)是云原生时代的必修课。
想象一下:凌晨2点,生产环境挂了。你手忙脚乱地登录AWS控制台,凭着记忆重新创建EC2实例——结果配置错了安全组,应用还是起不来。这时候你多么希望有一套"一键恢复"的魔法啊!
💡效率技巧:IaC就是那套魔法。它把你的基础设施变成可版本控制、可审计、可回滚的代码。
本文将对比Terraform和Ansible这两个IaC领域的"双子星",并引入Pulumi、Terragrunt等新势力,给出2026年最实用的选型建议。
Terraform:声明式配置的王者
什么是声明式?
Terraform的核心理念是声明式(Declarative):你告诉它"我想要什么",而不是"怎么做"。
就像你去餐厅点菜:
- 命令式:“先去冰箱拿牛肉,然后切薄片,再用大火爆炒…”
- 声明式:“来一份小炒黄牛肉,微辣。”
# Terraform:声明式 —— 我只关心结果 resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro" tags = { Name = "web-server" } }Terraform会自动计算依赖关系、并行创建资源、处理失败回滚。你不需要关心"先创建VPC还是先创建子网",Terraform的DAG(有向无环图)引擎会帮你搞定。
典型架构图
┌─────────────────────────────────────────────────────────────┐ │ Terraform Architecture │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │ │ │ main.tf │ │ variables.tf│ │outputs.tf │ │ │ │ (资源配置) │ │ (变量定义) │ │ (输出定义) │ │ │ └──────┬──────┘ └─────────────┘ └───────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Terraform Core (DAG引擎) │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │ │ │ │ │ Parse │───▶│ Plan │───▶│ Apply │ │ │ │ │ │ 解析 │ │ 规划 │ │ 执行 │ │ │ │ │ └─────────┘ └─────────┘ └─────────────────┘ │ │ │ └────────────────────────┬────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Provider Plugins │ │ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌──────────┐ │ │ │ │ │ AWS │ │ Azure │ │ GCP │ │ 阿里云 │ │ │ │ │ └────────┘ └────────┘ └────────┘ └──────────┘ │ │ │ └────────────────────────┬────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Cloud Providers │ │ │ │ (AWS / Azure / GCP / 阿里云等) │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘Terraform的核心优势
| 特性 | 说明 |
|---|---|
| 状态管理 | 通过terraform.tfstate记录资源状态,支持远程状态存储(S3、Consul等) |
| 执行计划 | terraform plan预览变更,避免"惊喜" |
| 模块化 | 可复用的模块系统,DRY原则(Don’t Repeat Yourself) |
| 多Provider | 支持AWS、Azure、GCP、阿里云、Kubernetes等200+ Provider |
⚠️避坑警告:千万不要手动修改Terraform管理的资源!下次apply时,Terraform会发现实际状态与期望状态不一致,可能导致资源被删除重建。如果必须手动修改,记得用
terraform import把资源纳管回来。
Ansible:过程式运维的老将
什么是过程式?
Ansible采用**过程式(Procedural)**范式:你写清楚"第一步做什么,第二步做什么"。
# Ansible:过程式 —— 我关心每一步 - name: 安装Nginx hosts: webservers tasks: - name: 更新apt缓存 apt: update_cache: yes - name: 安装Nginx apt: name: nginx state: present - name: 启动Nginx服务 service: name: nginx state: started enabled: yes - name: 复制配置文件 template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: reload nginx handlers: - name: reload nginx service: name: nginx state: reloadedAnsible的执行流程
┌─────────────────────────────────────────────────────────────┐ │ Ansible Execution Flow │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Inventory (主机清单) │ │ │ │ │ ▼ │ │ ┌─────────────┐ │ │ │ Playbook │ ──▶ 定义"要在哪些主机上执行什么任务" │ │ └──────┬──────┘ │ │ │ │ │ ▼ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Task 1 │──▶ │ Task 2 │──▶ │ Task 3 │ │ │ │ 安装依赖包 │ │ 安装软件 │ │ 配置服务 │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ SSH / WinRM 连接 │ │ │ │ (Ansible是无代理的,直接通过SSH操作目标机器) │ │ │ └────────────────────────┬────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Target Hosts (目标主机) │ │ │ │ (物理机 / 虚拟机 / 容器) │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘Ansible的核心优势
| 特性 | 说明 |
|---|---|
| 无代理 | 只需要SSH,目标机器无需安装任何Agent |
| 幂等性 | 多次执行结果一致,不会重复安装 |
| 即席命令 | ansible all -m ping快速批量操作 |
| 丰富的模块 | 3000+内置模块,覆盖几乎所有运维场景 |
💡效率技巧:Ansible的执行速度非常快——平均<1秒/机器。这意味着你可以在几秒钟内完成数百台服务器的配置更新。
Pulumi:用代码写基础设施
如果你觉得HCL(Terraform的配置语言)不够灵活,Pulumi可能是你的菜。
// Pulumi:用TypeScript写基础设施 import * as aws from "@pulumi/aws"; // 创建一个S3 Bucket const bucket = new aws.s3.Bucket("my-bucket", { acl: "private", tags: { Environment: "Production", Owner: "Platform Team" } }); // 创建一个EC2实例 const server = new aws.ec2.Instance("web-server", { ami: "ami-0c55b159cbfafe1f0", instanceType: "t3.micro", tags: { Name: "web-server" } }); // 导出资源ID export const bucketName = bucket.id; export const serverIp = server.publicIp;Pulumi支持TypeScript、Python、Go、C#、Java等主流编程语言。这意味着你可以:
- 用IDE的智能提示和类型检查
- 写单元测试验证基础设施逻辑
- 使用编程语言的循环、条件、函数等特性
⚠️避坑警告:Pulumi的灵活性是把双刃剑。团队需要建立严格的代码规范,否则容易出现"基础设施代码风格不一致"的问题。
Terragrunt:Terraform的"大管家"
当你的Terraform项目越来越大,你会发现:
- 同样的配置在dev/staging/prod重复写
- 状态文件管理混乱
- 变量传递像"传话游戏"
Terragrunt就是来解决这些问题的。
# terragrunt.hcl - 环境配置 include "root" { path = find_in_parent_folders() } terraform { source = "../../../modules//vpc" } # 自动注入变量 inputs = { environment = "production" vpc_cidr = "10.0.0.0/16" # 从YAML文件加载配置 tags = yamldecode(file("${get_terragrunt_dir()}/tags.yaml")) } # 远程状态配置 remote_state { backend = "s3" config = { bucket = "my-terraform-state" key = "${path_relative_to_include()}/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks" } }Terragrunt解决的问题
| 问题 | Terragrunt方案 |
|---|---|
| 配置重复 | DRY配置继承,环境间共享通用配置 |
| 状态管理 | 自动配置远程状态存储和锁 |
| 依赖管理 | dependency块显式声明模块依赖 |
| 多环境管理 | 目录结构清晰,环境隔离 |
infrastructure/ ├── modules/ │ ├── vpc/ │ ├── eks/ │ └── rds/ └── environments/ ├── dev/ │ ├── vpc/ │ │ └── terragrunt.hcl │ └── eks/ │ └── terragrunt.hcl ├── staging/ │ └── ... └── prod/ └── ...Provider选择指南
Terraform的强大之处在于其Provider生态系统。以下是主流云厂商的Provider选择建议:
AWS Provider
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } provider "aws" { region = "us-east-1" default_tags { tags = { Environment = "Production" ManagedBy = "Terraform" } } }💡效率技巧:使用
default_tags给所有资源自动打标签,省去重复劳动。
阿里云 Provider
terraform { required_providers { alicloud = { source = "aliyun/alicloud" version = "~> 1.200" } } } provider "alicloud" { region = "cn-hangzhou" } # 创建ECS实例 resource "alicloud_instance" "web" { instance_name = "web-server" instance_type = "ecs.c6.large" image_id = "ubuntu_22_04_x64_20G_alibase_20230515.vhd" vswitch_id = alicloud_vswitch.main.id security_groups = [alicloud_security_group.web.id] internet_max_bandwidth_out = 10 }Azure Provider
terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "~> 3.0" } } } provider "azurerm" { features {} } resource "azurerm_resource_group" "main" { name = "rg-production" location = "East Asia" }实战对比:创建一套完整环境
让我们用Terraform和Ansible分别创建一套Web应用环境,看看实际差异。
场景:创建VPC + EC2 + 部署Nginx
Terraform版本:
# main.tf terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } # VPC resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags = { Name = "production-vpc" } } # 子网 resource "aws_subnet" "public" { vpc_id = aws_vpc.main.id cidr_block = "10.0.1.0/24" availability_zone = "us-east-1a" map_public_ip_on_launch = true tags = { Name = "public-subnet" } } # 安全组 resource "aws_security_group" "web" { name_prefix = "web-sg" vpc_id = aws_vpc.main.id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["10.0.0.0/8"] } } # EC2实例 resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro" subnet_id = aws_subnet.public.id vpc_security_group_ids = [aws_security_group.web.id] user_data = <<-EOF #!/bin/bash apt-get update apt-get install -y nginx systemctl start nginx EOF tags = { Name = "web-server" } }执行:
terraform init terraform plan terraform applyAnsible版本:
# inventory.ini [webservers] web1 ansible_host=10.0.1.10 [webservers:vars] ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa# playbook.yml - name: 部署Web服务器 hosts: webservers become: yes tasks: - name: 更新apt缓存 apt: update_cache: yes cache_valid_time: 3600 - name: 安装Nginx apt: name: nginx state: present - name: 确保Nginx运行 service: name: nginx state: started enabled: yes - name: 复制首页文件 copy: content: "<h1>Hello from Ansible!</h1>" dest: /var/www/html/index.html notify: restart nginx handlers: - name: restart nginx service: name: nginx state: restarted执行:
ansible-playbook -i inventory.ini playbook.yml对比总结
| 维度 | Terraform | Ansible |
|---|---|---|
| 执行时间 | AWS资源创建平均2-5分钟/资源 | <1秒/机器(配置阶段) |
| 适用场景 | 创建云资源(VPC、EC2、RDS等) | 配置应用、系统运维 |
| 状态管理 | 自动维护tfstate | 无状态,每次执行重新检查 |
| 幂等性 | 自动计算差异,只改变化的部分 | 模块设计为幂等 |
| 学习曲线 | 需要理解HCL和资源依赖 | YAML语法,相对简单 |
💡效率技巧:最佳实践是Terraform负责基础设施,Ansible负责配置管理。两者可以配合使用:Terraform创建机器后,把IP输出给Ansible做进一步配置。
2026年选型建议
决策树
你需要做什么? │ ├─► 创建/管理云资源(VPC、EC2、RDS、K8s集群等) │ │ │ ├─► 团队熟悉编程语言(Python/TypeScript/Go) │ │ └── 选择 Pulumi —— 类型安全,IDE友好 │ │ │ └─► 团队更熟悉配置文件 │ ├─► 多环境、多团队共享配置 │ │ └── 选择 Terragrunt + Terraform │ │ │ └─► 简单场景、快速上手 │ └── 选择 Terraform │ ├─► 配置服务器、部署应用、系统运维 │ └── 选择 Ansible —— 无Agent、速度快、模块丰富 │ └─► 两者都要 └── Terraform创建资源 + Ansible配置应用 (业界最成熟的组合)各工具最佳场景
| 工具 | 最佳场景 | 避免场景 |
|---|---|---|
| Terraform | 云资源生命周期管理 | 频繁的配置变更(太慢) |
| Ansible | 应用部署、系统配置、补丁管理 | 创建云资源(无状态管理) |
| Pulumi | 复杂逻辑的基础设施、需要类型安全 | 简单场景(过度设计) |
| Terragrunt | 多环境、多团队的大型项目 | 小型项目(增加复杂度) |
幽默一刻
为什么DevOps工程师不喜欢玩捉迷藏?
因为每次他们藏好,Terraform都会把他们
terraform import回来。
文末三件套
1. 【源码获取】
关注此系列获取后续更新,后台回复’iac’获取完整源码链接。
2. 【思考题】
你们的IaC用的是哪种工具?是Terraform一统天下,还是Ansible独领风骚,亦或是Pulumi另辟蹊径?欢迎在评论区分享你的选型故事和踩坑经历!
3. 【系列预告】
下一篇我们将深入探讨:
- Helm—— Kubernetes包管理的"apt-get"
- K8s平台—— 构建企业级容器平台
- 安全扫描—— 把安全左移到IaC阶段
附录:快速参考
Terraform常用命令
terraform init # 初始化工作目录 terraform plan # 预览变更 terraform apply # 应用变更 terraform destroy # 销毁资源 terraform show # 显示状态 terraform state list # 列出资源 terraform import # 导入现有资源Ansible常用命令
ansible all -m ping # 测试连通性 ansible-playbook playbook.yml # 执行Playbook ansible-playbook --check playbook.yml # 干跑模式 ansible-playbook --tags web playbook.yml # 按标签执行 ansible-inventory --graph # 查看主机关系资源创建时间参考
| 资源类型 | 平均创建时间 |
|---|---|
| VPC | 1-2分钟 |
| Subnet | <30秒 |
| EC2实例 | 2-3分钟 |
| RDS实例 | 5-10分钟 |
| EKS集群 | 10-15分钟 |
写在最后:IaC不是银弹,但它能让你的基础设施像代码一样可管理、可审计、可回滚。选择适合团队的工具,比选择"最好"的工具更重要。毕竟,能跑起来的工具才是好工具,能落地的实践才是好实践。
本文首发于CSDN,转载请注明出处。
CSDN标签:Terraform, Ansible, Pulumi, IaC, 云资源, 基础设施即代码, 自动化运维
