Terraform vs. Ansible:你到底需要哪个?
Terraform 和 Ansible 的实际对比,每个工具真正擅长的地方,以及在真实 IaC 流程中如何结合使用。
初学 Infrastructure as Code 的人通常会这样问:"我应该先学哪个工具" 或 "为什么团队同时使用两者"。简短的回答是 Terraform 和 Ansible 解决不同的问题,大多数生产环境的设置是两者结合使用,而不是只选一个。
Terraform 实际用途
Terraform 是一个供应工具。它声明基础设施应该是什么样的:一个 VPC、三个 EC2 实例、一个 RDS 数据库、一个具有特定策略的 S3 bucket。你用 HCL 描述最终状态,运行 terraform plan 看会发生什么变化,然后运行 terraform apply 使其生效。Terraform 保有一个状态文件(本地或在后端如带 DynamoDB 锁定的 S3 bucket),它将你的配置映射到云提供商中的真实资源 ID。
这里的优势在于跨提供商的依赖关系解析。如果你告诉 Terraform 创建一个安全组,然后将其附加到一个 EC2 实例,它会自动推断出顺序。它还通过相同的工作流在 AWS、Azure、GCP、Cloudflare、Datadog 和数十个其他提供商上工作,这在基础设施跨越多个供应商时很重要。
Terraform 在机器创建后发生的任何事情上都不擅长。它不安装包、不编辑配置文件、不以任何有意义的持续方式重启服务。remote-exec 这样的 Provisioner 存在,但 HashiCorp 本身建议除了引导之外不要使用它们。
Ansible 实际用途
Ansible 是一个配置管理工具。它通过 SSH(或 Windows 上的 WinRM)连接,对已存在的机器运行任务:安装 nginx、生成配置文件、创建用户、重启服务、确保 cron 任务存在。Playbook 是 YAML,模块在设计上是幂等的,所以运行相同的 playbook 两次,如果系统已经符合期望状态,第二次就不会改变任何东西。
Ansible 不需要在目标主机上安装代理,只需要 Python 和 SSH 访问权限,这使得它很容易应用到现有基础设施上。它也擅长不严格是 "供应" 的编排任务——在一个群体中滚动重启、蓝绿部署步骤、在一个主机上运行数据库迁移,然后更新负载均衡器。
重叠和困惑的地方
两个工具在技术上都可以做对方的一些工作。Ansible 有云模块(amazon.aws.ec2_instance、azure.azcollection.azure_rm_virtualmachine)可以启动基础设施。Terraform 有 Provisioner 可以在新实例上运行 shell 命令。但使用 Ansible 做供应意味着放弃 Terraform 的状态跟踪和 plan/diff 工作流,使用 Terraform Provisioner 做配置意味着放弃幂等的、可重复的配置管理。
大多数团队实际采用的做法是:
- Terraform 构建基础设施:网络、计算实例、负载均衡器、托管数据库、IAM 角色。
- Ansible 配置其上的内容:软件安装、用户、配置文件、服务状态、应用部署步骤。
交接的具体例子
假设你在 AWS 上在负载均衡器后面设置三个 Web 服务器。
resource "aws_instance" "web" {
count = 3
ami = data.aws_ami.ubuntu.id
instance_type = "t3.medium"
tags = { Name = "web-${count.index}" }
}
output "web_ips" {
value = aws_instance.web[*].public_ip
}
Terraform 创建实例并输出它们的 IP。你可以将该输出输入动态 Ansible 清单(amazon.aws.aws_ec2 清单插件直接读取 EC2 标签,无需手动复制粘贴),然后运行:
ansible-playbook -i aws_ec2.yml site.yml
其中 site.yml 安装 nginx、放入应用配置、启动服务。Terraform 从不涉及 nginx。Ansible 从不涉及 VPC。每个工具各守其位,每个都有自己的状态/幂等性模型,不会与另一个冲突。
值得避免的常见错误
将 Terraform 状态存储在 git 中是最常见的早期错误——状态文件可能以明文形式包含密钥,并且会导致合并冲突,破坏你的基础设施模型。从第一天开始就使用远程后端。
Ansible 的错误是编写实际上不幂等的 playbook——使用 shell 或 command 模块做有合适模块(ansible.builtin.apt、ansible.builtin.copy、ansible.builtin.systemd)的事,这些模块已经正确处理了先检查再执行的逻辑。
如果你在决定先学什么:做云供应和多环境设置就先学 Terraform,管理已有服务器的配置漂移就先学 Ansible。大多数 DevOps 角色在第一年内都应该熟悉两者。
关于状态管理、动态清单和围绕这些工具构建完整 CI/CD 流程的更多信息,查看 Korra Studio 上相关的 DevOps 和 Cloud 部分。
本文由人工智能协助撰写,经 Michal Pilch(CISSP)审核并发布,Korra Studio。
这是来自 Korra Studio 知识库的笔记之一——该平台将每个主题与一对一指导相结合。
免费开始arrow_forward