Terraform 解释:从“这到底是什么?”到真正掌握 🚀
Source: Dev.to
Posted by a 3rd‑year engineering student who broke prod at 2 AM and lived to tell the tale.
想象一下:你手动在 AWS 上设置了一个 EC2 实例——安全组、IAM 角色、VPC 配置——全部通过控制台手工完成。它可以运行。你觉得自己像个天才。
然后你的队友不小心把它删掉了。
你盯着屏幕。记不起自己选择了哪些设置。你本来要写的文档只是一页空白的 Notion。现在是凌晨 2 点,离演示只有六个小时。
正是这种情况让我停止在 AWS 控制台里乱点,真正坐下来学习 Terraform。说实话?我真希望自己早点开始。
Terraform 实际解决了什么问题?
让我用一个真实的例子来说明,而不是教材式的答案。
假设你需要在 AWS 上搭建以下资源:
- 一个 EC2 实例(你的服务器)
- 一个安全组(防火墙规则)
- 一个 S3 存储桶(文件存储)
- 一个 IAM 角色(权限)
如果你手动通过 AWS 控制台完成这些操作,情况会是这样:
- 你要在 15 个页面之间点击才能创建 EC2 实例。
- 你忘记关联 IAM 角色。
- 于是你回去再修正。
- 你还得为 staging 环境做完全相同的事情。
- 你弄错了某个设置——staging 和 production 因此毫无理由地出现差异。
- 有新同事加入,却对你搭建的内容和原因一无所知。
使用 Terraform 时,你把所有这些写成 一份文件,进行版本控制,可重复部署。如果 staging 和 prod 需要保持一致,只需运行同一套代码。如果有同事加入,他们只要阅读这份文件就能立刻了解全部内容。
这就是核心承诺:你的基础设施成为代码,而不是谜团。
Infrastructure as Code — Let Me Explain It Like You’re My Classmate
好吧,先把正式定义抛到一边。
你知道开发者写代码来构建应用吗?应用在代码被执行之前根本不存在。 基础设施即代码 (IaC) 是同样的概念——不过不是在构建网页应用,而是在构建服务器、网络、数据库和云资源。
在 IaC 出现之前,系统管理员会通过 SSH 登录服务器,手动配置所有内容。它能工作,但有以下问题:
- 速度慢。
- 不一致(每台服务器都有细微差别)。
- 没有任何文档记录。
- 如果出现故障,没人知道该如何精确地重建它。
IaC 颠覆了这种方式。你在文件中描述想要的内容,运行一个命令,工具就会为你构建——每次都完全相同。
把它想象成食谱。厨师可以使用同一份食谱做出 100 道相同的菜。没有食谱时,每道菜都会因当天的厨师而略有不同。
为什么我选择 Terraform 而不是其他工具
- 它是云无关的。 同一个工具可以用于 AWS、GCP、Azure 等。我不想为了尝试不同的云而学习三种不同的工具。
- 庞大的社区。 当我卡住时(经常会),总能在 Stack Overflow 的答案、博客文章或 GitHub issue 中找到已经解决我同样问题的资源。
- 它是企业实际使用的工具。 我查看招聘信息,几乎所有 DevOps/Cloud 岗位都会列出 Terraform。学习它感觉是一次真正的投资。
- 学习曲线值得。 它并不 容易,但在做了几个项目后就能上手。
核心概念 — 真正重要的内容
🔌 提供者
提供者本质上是一个插件,告诉 Terraform 要与哪个云或服务进行交互。
provider "aws" {
region = "us-east-1"
}
这段代码告诉 Terraform:“我们在使用 AWS,并且希望在 us-east-1 区域创建资源。” 还有针对 GCP、Azure、Kubernetes、GitHub、Datadog 等几乎所有服务的提供者。
🧱 资源
资源是你实际想要创建的东西——比如 EC2 实例、S3 存储桶、数据库。
resource "aws_instance" "my_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
格式始终是:resource "type" "local_name"。本地名称仅用于在代码的其他地方引用该资源。
📦 变量
与其在每处硬编码数值,不如使用变量。这让你的代码更易复用。
variable "instance_type" {
default = "t2.micro"
}
resource "aws_instance" "my_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.instance_type
}
现在如果想更改实例类型,只需在一个地方修改——不必在十个文件中逐一查找。
🗂️ 状态文件
这部分最初让我感到困惑。Terraform 会维护一个名为 terraform.tfstate 的文件,用来记录它已经创建的资源。它会依据该文件判断在你更新配置时需要做哪些更改。
我通过实践学到的两件重要事项:
- 绝不要手动编辑它。 虽然它是 JSON 格式,看起来可以编辑,但随意修改会导致 Terraform 出现严重错误。
- 如果文件中包含机密信息,切勿提交到 GitHub。 对于团队项目,请使用远程状态(例如 S3 + DynamoDB)来存储。
⚙️ 核心命令
terraform init # 下载提供者,初始化工作目录
terraform plan # 在执行任何操作前显示将会发生的变化
terraform apply # 实际创建/修改基础设施
terraform destroy # 销毁所有资源
terraform plan 是你的最佳伙伴。始终在 apply 之前运行它。它会准确展示 Terraform 将要执行的创建、修改或销毁操作,避免意外。
📝 HCL(HashiCorp 配置语言)
HCL 是编写 Terraform 配置文件所使用的语言。它既不是 JSON,也不是 YAML,而是一种独立的语法。不过,一旦熟悉后,它的可读性相当好。上面的示例全部都是 HCL。
实际示例:在 AWS 上启动 EC2 实例
以下是一个简单、可运行的 Terraform 配置,用于启动带安全组的 EC2 实例:
# main.tf
provider "aws" {
region = "us-east-1"
}
variable "instance_type" {
default = "t2.micro"
}
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh"
description = "Allow SSH inbound traffic"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "my_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.instance_type
vpc_security_group_ids = [aws_security_group.allow_ssh.id]
tags = {
Name = "MyTerraformServer"
}
}
output "instance_ip" {
value = aws_instance.my_server.public_ip
}
运行它:
terraform init
terraform plan
terraform apply
就这么简单。无需在 AWS 控制台中点击操作,也不会忘记任何设置。只需代码。
初学者错误(我全都犯过)
-
未在
apply之前使用terraform plan
我直接多次运行apply。有一次它修改了我不想动的生产资源。一定要先执行 plan。 -
将状态文件或
.terraform文件夹提交到 Git
立即将以下内容添加到你的.gitignore:.terraform/ *.tfstate *.tfstate.backup -
硬编码敏感值
绝不要在.tf文件中直接写入 AWS 密钥、数据库密码或任何凭证。请使用环境变量或 AWS Secrets Manager 等工具。 -
未理解 Terraform 是声明式的
你描述的是 想要的状态,而不是 如何实现。我花了很久才摆脱过程式思维。 -
Terraform 创建资源后手动更改资源
如果你在控制台手动调整 EC2 实例的大小,Terraform 不会感知。下次plan会显示漂移,并可能尝试恢复你的更改。
Terraform 在真实 DevOps 工作流中的角色
在实际的公司里,Terraform 并不是只在开发者的笔记本电脑上运行。它已经深度集成到 CI/CD 流水线中。
典型的设置:
- 开发者提交包含基础设施变更的 PR。
- CI(例如 GitHub Actions)自动运行
terraform plan,并将输出作为评论发布在 PR 上。 - 经过审查并合并后,CI 自动运行
terraform apply。 - 状态远程存储在 S3 中,并使用 DynamoDB 锁定,确保不会有两个人同时执行 apply。
像 Terraform Cloud 或 Atlantis 这样的工具可以让这一过程更加顺畅。这样就能完整记录谁在何时、为何更改了哪些基础设施——就像对应用代码进行代码审查一样。
这也是为什么在 2025 年,掌握 Terraform 已不再是可有可无的技能;如果你对云或 DevOps 认真的话,它是核心能力。
我从中真正学到的
- 从小做起:一个资源,一个提供者,使其工作。
- 阅读你所使用的特定资源的 Terraform 文档——它们实际上非常好。
- 对于团队项目,远程状态不是可选的;请尽早设置。
- 把你的基础设施代码当作应用代码来对待:审查、版本管理、编写文档。
terraform destroy 令人满足,但也令人恐惧。请谨慎使用。
最后思考
Terraform 看起来从外部很吓人,但一旦你写出第一个可工作的配置,就会完全明白。概念并不复杂——只是起初不熟悉。
如果你是学生或刚入职的工程师,想进入 DevOps 或云领域,学习 Terraform 与 Docker 和 Kubernetes 并行是一种真正强大的组合。这是一项几乎出现在每个职位描述中的技能。
我正在公开记录我的学习过程——如果你也在类似的旅程中,欢迎联系或查看我的 GitHub,我会在上面推送小项目和笔记。
你使用 Terraform 的经历如何? 在评论中告诉我——尤其是如果你犯了比我更糟的错误 👇