Terraform 解释:从“这到底是什么?”到真正掌握 🚀

发布: (2026年3月1日 GMT+8 12:29)
13 分钟阅读
原文: Dev.to

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 控制台完成这些操作,情况会是这样:

  1. 你要在 15 个页面之间点击才能创建 EC2 实例。
  2. 你忘记关联 IAM 角色。
  3. 于是你回去再修正。
  4. 你还得为 staging 环境做完全相同的事情
  5. 你弄错了某个设置——staging 和 production 因此毫无理由地出现差异。
  6. 有新同事加入,却对你搭建的内容和原因一无所知。

使用 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 的文件,用来记录它已经创建的资源。它会依据该文件判断在你更新配置时需要做哪些更改。

我通过实践学到的两件重要事项:

  1. 绝不要手动编辑它。 虽然它是 JSON 格式,看起来可以编辑,但随意修改会导致 Terraform 出现严重错误。
  2. 如果文件中包含机密信息,切勿提交到 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 控制台中点击操作,也不会忘记任何设置。只需代码。

初学者错误(我全都犯过)

  1. 未在 apply 之前使用 terraform plan
    我直接多次运行 apply。有一次它修改了我不想动的生产资源。一定要先执行 plan。

  2. 将状态文件或 .terraform 文件夹提交到 Git
    立即将以下内容添加到你的 .gitignore

    .terraform/
    *.tfstate
    *.tfstate.backup
  3. 硬编码敏感值
    绝不要在 .tf 文件中直接写入 AWS 密钥、数据库密码或任何凭证。请使用环境变量或 AWS Secrets Manager 等工具。

  4. 未理解 Terraform 是声明式的
    你描述的是 想要的状态,而不是 如何实现。我花了很久才摆脱过程式思维。

  5. Terraform 创建资源后手动更改资源
    如果你在控制台手动调整 EC2 实例的大小,Terraform 不会感知。下次 plan 会显示漂移,并可能尝试恢复你的更改。

Terraform 在真实 DevOps 工作流中的角色

在实际的公司里,Terraform 并不是只在开发者的笔记本电脑上运行。它已经深度集成到 CI/CD 流水线中。

典型的设置:

  • 开发者提交包含基础设施变更的 PR。
  • CI(例如 GitHub Actions)自动运行 terraform plan,并将输出作为评论发布在 PR 上。
  • 经过审查并合并后,CI 自动运行 terraform apply
  • 状态远程存储在 S3 中,并使用 DynamoDB 锁定,确保不会有两个人同时执行 apply。

Terraform CloudAtlantis 这样的工具可以让这一过程更加顺畅。这样就能完整记录谁在何时、为何更改了哪些基础设施——就像对应用代码进行代码审查一样。

这也是为什么在 2025 年,掌握 Terraform 已不再是可有可无的技能;如果你对云或 DevOps 认真的话,它是核心能力。

我从中真正学到的

  • 从小做起:一个资源,一个提供者,使其工作。
  • 阅读你所使用的特定资源的 Terraform 文档——它们实际上非常好。
  • 对于团队项目,远程状态不是可选的;请尽早设置。
  • 把你的基础设施代码当作应用代码来对待:审查、版本管理、编写文档。

terraform destroy 令人满足,但也令人恐惧。请谨慎使用。

最后思考

Terraform 看起来从外部很吓人,但一旦你写出第一个可工作的配置,就会完全明白。概念并不复杂——只是起初不熟悉。

如果你是学生或刚入职的工程师,想进入 DevOps 或云领域,学习 Terraform 与 Docker 和 Kubernetes 并行是一种真正强大的组合。这是一项几乎出现在每个职位描述中的技能。

我正在公开记录我的学习过程——如果你也在类似的旅程中,欢迎联系或查看我的 GitHub,我会在上面推送小项目和笔记。

你使用 Terraform 的经历如何? 在评论中告诉我——尤其是如果你犯了比我更糟的错误 👇

0 浏览
Back to Blog

相关文章

阅读更多 »