简介
想象一下,你正在点咖啡。如果菜单上只写着「咖啡」,你每次可能都会拿到黑咖啡。但如果菜单提供了「尺寸」或「牛奶类型」等选项,你就可以自定义订单,而咖啡师不需要为每种组合学习新的配方。
在 Terraform 中,变量可以让配置重复使用。你只需修改输入值,无需重写整个文件。
输出可以让 Terraform 报告重要的结果值,例如 ID、名称或地址。变量和输出结合使用,可以让 Terraform 配置更加模块化,也更实用。
完成本实验后,你将拥有一个灵活的 Terraform 配置,可以根据需要创建具有不同名称的容器。
变量将配置逻辑与环境特定的数据分离开来。输出则负责将有用的结果值发布给用户或后续自动化流程。
创建变量文件
优秀的厨师会在开始烹饪前整理好食材。在 Terraform 中,最佳实践是将自定义选项(变量)放在独立文件中,而不是与主要配置混在一起。
这个文件的标准名称是 variables.tf。创建该文件不会改变 Terraform 的工作方式——Terraform 会读取目录中的所有 .tf 文件,并将它们视为一本完整的配置文件——但这样可以让配置更加有条理。
在 IaC 中,这种组织方式非常重要,因为实际配置通常会快速增长。将变量、资源和输出清晰分开,可以大幅简化后续维护。
进入项目目录并创建这个文件:
cd ~/project
touch variables.tf
现在已经有一个空文件,可以在其中定义变量。下一步将向文件中添加内容。
定义变量
现在需要声明有哪些可用选项。这就像在订单表单中添加一个「名称」字段。
使用 nano 打开 variables.tf:
nano variables.tf
添加以下代码块。它告诉 Terraform:「有一个名为 container_name 的选项,该选项接受文本(字符串);如果用户没有提供值,就使用 ExampleNginxContainer 作为名称。」
variable "container_name" {
description = "Value of the name for the Docker container"
type = string
default = "ExampleNginxContainer"
}
保存并退出 nano(按 Ctrl+O,然后按 Enter,最后按 Ctrl+X)。
现在表单字段已经存在,接下来需要在配置中使用它。创建一个使用该变量的 main.tf 文件。
创建 main.tf:
nano main.tf
粘贴以下代码。注意 name = var.container_name。这就是将变量接入配置的方式。
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
provider "docker" {}
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = var.container_name
ports {
internal = 80
external = 8000
}
}
记得保存并退出 nano。
使用 var.container_name 表示:「不要将名称直接写死;读取 container_name 变量中的值,并使用该值作为名称。」
定义输出
购买商品时,你会收到一张收据。在 Terraform 中,输出就像收据一样,会显示刚刚创建的资源的重要信息。
这对于获取资源创建前无法知道的信息非常有用,例如系统分配的随机 ID 或公共 IP 地址。
当某个基础设施组件需要将信息交给操作人员、另一个 Terraform 模块或后续自动化步骤时,输出尤其有用。
创建名为 outputs.tf 的文件,用于整理这些返回值。使用 nano 打开它:
nano outputs.tf
添加以下代码块。它告诉 Terraform:「完成操作后,输出 nginx 容器的 ID。」
output "container_id" {
description = "ID of the Docker container"
value = docker_container.nginx.id
}
保存并退出 nano。
现在运行配置。
首先初始化项目,以下载 Docker provider:
terraform init
接下来应用配置。这次不指定容器名称,因此 Terraform 会使用默认值(ExampleNginxContainer)。使用 -auto-approve 可以跳过「yes」确认提示,节省时间。
terraform apply -auto-approve
查看输出的最底部。你应该会看到 Outputs:,其后显示 container_id。
覆盖变量
变量的真正优势在于:无需重写代码即可修改变量值。假设你想启动第二个容器,并为它设置不同的名称。你不需要编辑 main.tf。
只需使用 -var 选项告诉 Terraform 覆盖默认值即可。这就像告诉咖啡师:「实际上,把它改成大杯。」
运行以下命令:
terraform apply -var="container_name=MyDynamicContainer" -auto-approve
仔细查看输出。Terraform 会显示:docker_container.nginx must be replaced。
为什么会这样?因为在 Docker 中,运行中的容器不能轻易重命名。要更改名称,Terraform 会先销毁旧容器(-),再使用新名称创建一个新容器(+)。这体现了不可变基础设施的一个重要原则:我们通过替换对象来完成变更,而不是直接修改对象。
确认新容器正在运行:
docker ps --format "{{.Names}}"
你应该会看到 MyDynamicContainer。
总结
恭喜!你已经成功让 Terraform 代码具有动态性。
在本实验中,你学习了:
- 变量:如何使用
variables.tf为代码创建灵活的「表单字段」。 - 引用:如何使用
var.variable_name将这些值插入主要配置。 - 输出:如何使用
outputs.tf在运行结束后显示重要数据(即「收据」)。 - 覆盖值:如何在命令行中使用
-var输入新值,从而在不同场景中复用同一份代码。



