人人都能学编程
English 开始学习
专项 · 云与 SRE第 1 课 / 共 5 课免费阅读

Terraform 基础 · 云与可靠性

怎么用代码而不是点鼠标来创建服务器和存储?

课程目录

为什么需要它

在云控制台里点来点去,做一次没问题。但没人记得勾过哪些选项,测试环境会慢慢和生产环境走样,灾难之后重建要花好几天。基础设施即代码把服务器、存储桶和网络写进文件:像代码一样评审,存在 Git 里,每次都用同样的方式应用。Terraform 是最常用的工具。

直觉理解

Terraform 文件描述的是你想要的资源:

resource "aws_s3_bucket" "assets" {
  bucket = "shop-assets-${var.env}"
}
  • resource "类型" "名字":类型来自云服务商;名字由你取。两者合起来就是地址 aws_s3_bucket.assets。
  • 变量让一个文件适用于多个环境:variable "env" { default = "staging" },用 var.env 引用,在文字里写成 ${var.env}。
  • count 生成多个副本:count = 3 得到 aws_instance.web[0]、[1]、[2];在里面,count.index 依次是 0、1、2。
  • 输出(output)在应用之后打印有用的值,比如地址或名字。

你写的不是步骤,而是最终结果。terraform plan 把它和现有的东西比较,显示它将要做什么:

+ aws_s3_bucket.assets will be created
Plan: 1 to add, 0 to change, 0 to destroy.

然后 terraform apply 去执行。在这里点 运行 可以看到计划;不会真的创建任何东西。

定义

基础设施即代码

Describing servers, networks and storage in files that are versioned, reviewed and applied by a tool.
用文件描述服务器、网络和存储,这些文件有版本、经过评审,由工具来应用。

资源

One thing in the cloud that Terraform manages, addressed as TYPE.NAME (with [i] when it uses count).
Terraform 管理的一个云上的东西,地址是 类型.名字(用了 count 时还有 [i])。

计划

Terraform's preview of what it will create (+), change (~), replace (-/+) or destroy (-).
Terraform 对将要创建(+)、修改(~)、替换(-/+)或销毁(-)的东西的预览。

示例

一个存储桶和一台服务器

在互动课里运行

运行它:在一个空账号上,所有东西都会被创建。

variable "env" {
  default = "staging"
}

resource "aws_s3_bucket" "assets" {
  bucket = "shop-assets-${var.env}"
}

resource "aws_instance" "web" {
  ami           = "ami-0abc123"
  instance_type = "t3.micro"
  tags = {
    Name = "web-${var.env}"
  }
}

output "bucket_name" {
  value = aws_s3_bucket.assets.bucket
}
逐步执行
  1. L1一个带默认值的变量;其他环境可以传入不同的值。
  2. L6在文字里,${...} 插入一个值:shop-assets-staging。
  3. L9它的地址是 aws_instance.web。
  4. L17应用之后,Terraform 会打印存储桶的名字。

用 count 生成多个副本

在互动课里运行

count 把一个块变成编了号的多个资源。

variable "web_count" {
  default = 2
}

resource "aws_instance" "web" {
  count         = var.web_count
  ami           = "ami-0abc123"
  instance_type = "t3.micro"
  tags = {
    Name = "web-${count.index}"
  }
}
逐步执行
  1. L1两个副本:aws_instance.web[0] 和 aws_instance.web[1]。
  2. L10第一个是 0,第二个是 1:名字分别是 web-0 和 web-1。

常见错误

又在控制台里手动改

在控制台里手动修改,会让现实和文件不一致(漂移)。下一次 plan 会试图把它改回去。应该去改文件。

把各环境的值写死

叫 shop-logs-staging 的存储桶没法给生产环境复用。把各环境之间不同的东西放进变量。

不看计划就应用

计划就是安全检查。输入 yes 之前一定要读一遍,特别是带 - 和 -/+ 的行。

小测验

1. `terraform plan` 做什么?

  1. A显示会发生哪些变化,但什么都不改
  2. B创建资源
  3. C删除文件里没有的一切
查看答案

答案:A

plan 是预览;apply 才会真正修改。

2. `resource "aws_instance" "api"`,`count = 2`。地址是什么?

  1. Aaws_instance.api[0] 和 aws_instance.api[1]
  2. Baws_instance.api1 和 aws_instance.api2
  3. Capi.aws_instance[2]
查看答案

答案:A

类型.名字,用了 count 时再加一个从 0 开始的下标。

动手练习

3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。

  1. 预测输出数一数资源

    在一个空账号上,terraform plan 会创建多少个资源?

  2. 改需求用上变量

    这个文件只适用于测试环境。加一个变量 env(默认 "staging"),用在存储桶名字里(shop-logs-<env>);再加一个变量 instance_type(默认 "t3.micro"),用在服务器上。

  3. 从零写服务器和备份存储桶

    用 Terraform 写出:

    • 一个变量 replicas,默认 3
    • aws_instance.api,每个副本一台(count),ami = "ami-0abc123",instance_type = "t3.small",标签 Name 依次是 api-0、api-1……
    • aws_s3_bucket.backups,bucket = "shop-backups"
    • 一个输出 backup_bucket,值是存储桶的名字

在互动课里练这一课

打开互动课,这些例子都能直接改、直接运行,练习题提交马上判题。免费开始,不用注册。

本课术语

术语中文英文定义
Infrastructure as code基础设施即代码Cloud resources described in versioned files.
TerraformTerraformA tool that creates and updates cloud resources from files.
terraform planterraform planA preview of what Terraform would change.