Terraform 命令
一旦在你的机器上安装 Terraform 之后,就可以在根模块所在的目录下,通过命令来与 Terraform 进行交互。本文涵盖的常见命令包括 terraform init、terraform plan、terraform apply、terraform destroy 和 terraform fmt。
-
terraform init:用于初始化和自动下载提供商的插件。
-
terraform plan:提供在执行 terraform apply 后将创建的资源的预览。
-
terraform apply:创建基础设施资源。
-
terraform destroy:销毁基础设施资源。
-
terraform fmt:自动格式化代码以匹配规范约定。
初始化阶段(Init)
terraform init 命令在初始化阶段运行,它是在完成 Terraform 配置后运行的第一个命令。terraform init 确保阿里云提供商的插件已完成下载,并安装在当前工作目录的子目录中,同时还包括各种其他记录文件。
terraform {
required_providers {
alicloud = {
source = "aliyun/alicloud"
version = "1.225.0"
}
}
}
提供商的代码定义块中包括一个 source 属性,指定从哪里下载提供商插件。
Terraform 是基于插件的架构来实现对多种基础设施和服务提供商支持的。每个 "提供商" 是一个独立的二进制文件,它与 Terraform 本身独立分发。terraform init 命令将自动下载和安装 Terraform 配置中使用到的任何提供者的二进制文件,如在本例中,提供商是 alicloud。
terraform init 运行之后,你会看到一个 "Initializing provider plugins" 的消息,告诉你 Terraform 将找到指定版本的插件并下载相关文件。命令运行完成之后,在当前工作目录中将会创建一个隐藏的 .terraform 目录,该目录中保存了已经下载的插件。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding aliyun/alicloud versions matching "1.225.0"...
- Reusing previous version of hashicorp/alicloud from the dependency lock file
- Installing aliyun/alicloud v1.225.0...
- Installed aliyun/alicloud v1.225.0 (verified checksum)
...
Terraform has been successfully initialized!
terraform init 命令的输出会告诉你 Terraform 已安装的提供商版本,在此例中是 1.225.0 版本。
预览阶段(Plan)
terraform plan 创建一个执行计划,并详细展示了在执行 terraform apply 时将创建、修改或销毁的所有资源信息。
运行 terraform plan 时,Terraform 会:
-
读取现有资源的在远端的当前状态,以确保 Terraform 状态是最新的。
-
将当前配置与先前状态进行比较,并记录任何差异。
-
构建一个执行计划,只修改达成你所需状态所必要的部分。
terraform plan 实际上不会创建或更改任何基础设施资源,而是为你提供预览基础设施创建和变更的机会。例如,在将 Terraform 配置提交到版本控制之前,你可能想要运行此命令,以确保其行为跟预期是一样的。
resource "alicloud_vswitch" "main_vswitch" {
vpc_id = "vpc-2zekfrr69r6qmotbmru1m"
cidr_block = "10.0.1.0/24"
zone_id = "cn-hangzhou-k"
vswitch_name = "main-vswitch"
}
运行 terraform plan 后,输出的执行计划中,配置文件中指定的 vpc_id、cidr_block、zone_id、vswitch_name 值会映射到计划输出的对应属性:text
Terraform will perform the following actions:
# alicloud_vswitch.main_vswitch will be created
+ resource "alicloud_vswitch" "main_vswitch" {
+ availability_zone = (known after apply)
+ cidr_block = "10.0.1.0/24"
+ create_time = (known after apply)
+ id = (known after apply)
+ ipv6_cidr_block = (known after apply)
+ ipv6_cidr_block_mask = (known after apply)
+ name = (known after apply)
+ status = (known after apply)
+ vpc_id = "vpc-2zekfrr69r6qmotbmru1m"
+ vswitch_name = "main-vswitch"
+ zone_id = "cn-hangzhou-k"
}
Plan: 1 to add, 0 to change, 0 to destroy.
资源和参数旁边的符号表示对资源计划执行的具体操作:
-
加号(+)
资源旁边的加号意味着 Terraform 将创建该资源,并展示将要设置的属性
-
减号斜线加号(-/+)
表示 Terraform 将销毁当前资源并重新创建一个新的资源,而不是就地更新它的属性
-
波浪号(~)
表示 Terraform 将就地更新资源属性
-
减号(-)
表示销毁当前资源实例
运行 terraform plan 命令时,你可以使用可选参数 -out=<文件名> 将生成的计划保存到磁盘上的文件中,以便之后可以将文件作为执行计划传递给 terraform apply 来执行。
$ terraform plan -out=tf.tfplan
执行阶段(Apply)
terraform apply 执行通过 terraform plan 创建的执行计划,或者直接生成执行计划并确认执行,进而完成资源的创建和相互之间依赖关系的建立。
terraform apply 对执行计划的执行有两种方式:
-
直接执行 terraform plan 生成的执行计划。terraform plan 通过 -out 参数将执行计划保存为文件(比如文件命名为 tf.tfplan),terraform apply 可以直接使用该文件作为执行计划直接执行,无需等待确认:
$ terraform apply tf.tfplan
-
自身重新生成执行计划并等待确认再执行
和 terraform plan 命令一样,terraform apply 在执行时也会显示资源变更详情,并尝试创建执行计划等待用户确认执行。如果执行计划成功创建,Terraform 会暂停并等待确认再继续;如果计划中有任何不正确或不安全的地方,你可以在这里中止而不改变你的基础设施。
resource "alicloud_vswitch" "main_vswitch" {
vpc_id = "vpc-2zekfrr69r6qmotbmru1m"
cidr_block = "10.0.1.0/24"
zone_id = "cn-hangzhou-k"
vswitch_name = "main-vswitch"
}
$ terraform apply
Terraform will perform the following actions:
# alicloud_vswitch.main_vswitch will be created
+ resource "alicloud_vswitch" "main_vswitch" {
+ cidr_block = "10.0.1.0/24"
+ vpc_id = "vpc-bp1y88bqtlunfdvvctuuy"
+ vswitch_name = "main-vswitch"
+ zone_id = "cn-hangzhou-k"
+ …
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
如果 terraform apply 执行失败,请阅读错误消息并解决问题。
资源销毁(Destroy)
terraform destroy 用于销毁资源。terraform destroy 类似于 terraform apply,但它的行为就像配置中将所有资源定义删除并执行 terraform apply 一样。
Terraform 销毁资源主要有三种方式:
-
terraform destroy 命令
和 terraform apply 命令一样,terraform destroy 在执行时也会显示资源销毁的详情,并尝试创建销毁计划等待用户确认执行。如果销毁计划成功创建,Terraform 会暂停并等待确认再继续;如果计划中有任何不正确或不安全的地方,你可以在这里中止而不会销毁你的基础设施。
$ terraform destroy Terraform will perform the following actions: # alicloud_vswitch.main_vswitch will be destroyed - resource "alicloud_vswitch" "main_vswitch" { - cidr_block = "10.0.1.0/24" -> null - id = "vsw-bp1svwz2meo2mqj8c9ewz" -> null - vpc_id = "vpc-bp1y88bqtlunfdvvctuuy" -> null - vswitch_name = "main-vswitch" -> null - zone_id = "cn-hangzhou-k" -> null - ... } Plan: 0 to add, 0 to change, 1 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes alicloud_vswitch.main_vswitch: Destroying... [id=vsw-bp1svwz2meo2mqj8c9ewz] alicloud_vswitch.main_vswitch: Destruction complete after 4s Destroy complete! Resources: 1 destroyed. -
terraform plan 创建资源销毁的执行计划
可以通过 terraform plan 的可选参数 -destroy 来生成一个销毁计划,并通过 terraform apply 来执行这个销毁计划。
$ terraform plan -destroy -out=tf.tfplan
如果想要销毁某个特定的资源,你也可以通过命令中的可选参数 -target=resource 来指定要销毁的特定资源。
-
删除配置并创建资源销毁执行计划
从 Terraform 配置中删除所有资源或者单个想要销毁的资源的代码定义,并通过 terraform plan 和 terraform apply 来完成所有资源或者指定资源的销毁。
与 terraform plan 类似,Terraform 在销毁资源时将确定需要销毁的顺序,例如,如果 vSwitch 交换机中仍有资源(如 ECS 实例,RDS 实例等),阿里云将不允许删除 vSwitch 交换机,Terraform 会在实例被销毁后再销毁交换机。
terraform destroy 需要谨慎使用,它将销毁任何资源及其相关数据。例如,如果 OSS Bucket 中有数据,在运行 terraform destroy 时要小心,因为这些数据无法恢复。
在生产环境中销毁基础设施是罕见的事件,但如果你使用 Terraform 创建多个环境(例如开发、测试和预发布),那么销毁往往是一个有用的操作,可以用 terraform destroy 方便地清理临时对象。
代码格式化(fmt)
最后,我们来讨论一些代码格式化的最佳实践:
-
将元参数与资源参数分开,放在代码的最前面或最后,并留出空行
元参数是指 HCL 提供的预留参数,比如 count,for_each 等
-
参数从块定义开始缩进两个空格
-
当在一个块中定义两个或两个以上的参数时,让等号对齐
-
当一个块包含嵌套块时,将该块放在所有参数之后
-
最后,当代码包含多个块时,用空行将它们分开以提高可读性
# ❌ 错误示例
resource "alicloud_instance" "instance" {
data_disks { # 嵌套的代码块在最上面
size = 20
category = "cloud_efficiency"
}
count = 10 # 元参数在中间
instance_name="terraform-example" # 等号未对齐
…
}
# ✅ 正确示例
resource "alicloud_instance" "instance" {
count = 10 # 元参数在最上面
instance_name = "terraform-example" # 等号对齐
…
data_disks { # 嵌套的代码块在最下面
size = 20
category = "cloud_efficiency"
}
}
运行 terraform fmt 将基于所有格式规则和推荐的样式自动对模块和代码进行格式化,以提高代码可读性和一致性。terraform fmt 自动保持一致的格式,因此你不必手动更改配置以确保其符合标准。