Terraform
管理 Terraform 版本
HashiCorp 积极开发和维护 Terraform。要访问新的 Terraform 功能,您需要升级配置使用的 Terraform 版本。设置 required_version 来控制配置使用的 Terraform 版本,并使更新更具可预测性。
在本教程中,您将更新现有的配置以使用最新版本的 Terraform,并学习如何在团队内管理不同版本的 Terraform。
先决条件
您需要以下内容才能完成本教程
- 本地安装的 Terraform CLI,版本 1.2 或更高版本。
- An AWS account.
- Your AWS credentials configured locally with your access keys and a default region.
- git CLI。
克隆示例仓库
克隆此教程的 示例 GitHub 仓库。
$ git clone https://github.com/hashicorp-education/learn-terraform-versions
进入该目录。
$ cd learn-terraform-versions
此仓库包含一个完整的 Terraform 配置,该配置在 AWS 上部署一个示例 Web 应用程序。但是,此配置使用了较旧版本的 Terraform。你将更新它以使用较新版本的 Terraform。
查看示例配置
打开 terraform.tf,并查看 terraform 块。
terraform {
required_providers {
aws = {
version = "~> 5.52.0"
}
random = {
version = "~> 3.6.2"
}
}
required_version = "~> 1.1.9"
}
此配置将 required_version 设置为 ~> 1.1.9。 ~> 符号允许补丁版本大于 9,但要求主版本和次版本 (1.1) 与配置指定的版本匹配。 如果你尝试使用高于 1.1.x 的版本,Terraform 会报错,因为这个 required_version 设置。
使用 version 子命令来检查你的 Terraform 版本以及你的配置正在使用的任何提供程序的版本。
$ terraform version
Terraform v1.7.5
on darwin_arm64
Your version of Terraform is out of date! The latest version
is 1.8.4. You can update by downloading from https://www.terraform.io/downloads.html
Terraform 也会告知你是否有较新版本的 Terraform 可用。
尝试使用 terraform init 初始化你的项目。 Terraform 会打印出一个错误,告诉你你本地的 Terraform 版本对于此配置的 required_version 约束来说太新了。
$ terraform init
Initializing the backend...
╷
│ Error: Unsupported Terraform Core version
│
│ on terraform.tf line 11, in terraform:
│ 11: required_version = "~> 1.1.9"
│
│ This configuration does not support Terraform version 1.7.5. To proceed, either choose another supported Terraform version or update this version constraint.
│ Version constraints are normally set for good reason, so updating the constraint may lead to other errors or unexpected behavior.
╵
HashiCorp 使用 major.minor.patch 格式来表示 Terraform 版本。 HashiCorp 频繁更新 Terraform,因此使用针对早期 Terraform 版本编写的配置是很常见的。 Terraform 的新次版本和补丁版本与其先前版本编写的配置向后兼容。 因此,你可以升级到较新的 Terraform 次版本,并仍然使用你现有的配置。 但是,升级你的 Terraform 版本可能会产生其他后果,例如需要更新你的提供程序版本。 某些版本更新可能会刷新你的状态文件版本,或者需要编辑配置文件以实现新功能。 使用 required_version 设置来控制哪些 Terraform 版本将与你的配置一起使用,以确保对基础设施的更新安全且可预测。
在 terraform.tf 中,将 1.1.9 替换为你的当前 Terraform 版本,如 terraform version 命令所打印。 务必保存文件。
terraform.tf
terraform {
required_providers {
## ...
}
required_version = "~> <TERRAFORM_VERSION>"
}
现在初始化你的配置。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.52.0"...
- Finding hashicorp/random versions matching "~> 3.6.2"...
- Installing hashicorp/random v3.6.2...
- Installed hashicorp/random v3.6.2 (signed by HashiCorp)
- Installing hashicorp/aws v5.52.0...
- Installed hashicorp/aws v5.52.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
现在应用此配置以创建示例基础设施。 记住用 yes 回应确认提示。
$ terraform apply
data.aws_ami.amazon_linux: Reading...
data.aws_ami.amazon_linux: Read complete after 1s [id=ami-0676a735c5f8e67c4]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.web will be created
+ resource "aws_instance" "web" {
+ ami = "ami-0676a735c5f8e67c4"
+ arn = (known after apply)
## ...
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
application_url = "ec2-35-94-148-223.us-west-2.compute.amazonaws.com/index.php"
domain_name = "ec2-35-94-148-223.us-west-2.compute.amazonaws.com"
检查 Terraform 状态文件
当你运行 Terraform 命令时,Terraform 会将当前版本存储在你的项目的状态文件中,以及状态文件版本格式。 由于 Terraform 将其状态文件存储为文本,因此你可以检查状态以确定哪个版本的 Terraform 生成了它。
$ grep -e '"version"' -e '"terraform_version"' terraform.tfstate
"version": 4,
"terraform_version": "1.7.5",
Terraform 只有当 Terraform 的新版本需要更改状态文件的格式时,才会更新状态文件 version。每当您使用更新的 Terraform 版本应用配置更改时,Terraform 都会更新 terraform_version。
通常,Terraform 将继续适用于给定状态文件在小版本更新之间。对于主要或次要版本,如果需要,Terraform 会更新状态文件版本,并且如果您尝试使用不受支持的状态文件版本的旧版 Terraform 运行,则会给出错误。
如果您尝试使用不支持当前状态文件版本的旧版 Terraform 再次应用此配置,Terraform 将返回状态锁定错误并显示所需的版本。
$ terraform apply
Error: Error locking state: Error acquiring the state lock: state snapshot was
created by Terraform v1.7.5, which is newer than current v0.12.29; upgrade to
Terraform v1.7.5 or greater to work with this state
Terraform acquires a state lock to protect the state from being written
by multiple users at the same time. Please resolve the issue above and try
again. For most commands, you can disable locking with the "-lock=false"
flag, but this is not recommended.
一旦您在给定项目中使用较新版本的 Terraform 的状态文件格式,就无法支持还原为使用旧版状态文件版本。
Terraform 独立于 Terraform 本身的版本管理提供程序版本。有时,旧版本的提供程序将无法与较新版本的 Terraform 配合使用。每当您升级 Terraform 时,请查看您的提供程序版本并考虑同时升级它们。请尝试我们的 锁定和升级提供程序版本的教程,以了解如何管理提供程序版本。
Terraform 版本约束
下表总结了您可以在 required_version 设置中固定 Terraform 版本的几种方法,假设您的当前目标版本为 Terraform v0.15.0。请参阅 Terraform 文档,以获取版本约束的详细说明。
| 所需版本 | 含义 | 注意事项 |
|---|---|---|
1.7.5 | 仅 Terraform v1.7.5 确切版本 | 要升级 Terraform,请首先编辑 required_version 设置 |
>= 1.7.5 | 任何 Terraform v1.7.5 或更高版本 | 包括 Terraform v2.0.0 及以上版本 |
~> 1.7.5 | 任何 Terraform v1.7.x 版本,但不包括 v1.8 或更高版本 | 补丁版本更新应该不会造成破坏 |
>= 1.7.5, < 1.9.5 | Terraform v1.7.5 或更高版本,但低于 v1.9.5 | 避免特定的版本更新 |
通常,我们建议您使用最新版本的 Terraform 以利用最新的功能和错误修复。但是,除非您需要特定的功能或错误修复,否则每次使用 Terraform 时都不需要将您的 Terraform 项目升级到最新版本。
作为最佳实践,请考虑使用 ~> 样式版本约束,以固定您的主要和次要 Terraform 版本。这样做将允许您和您的团队使用补丁版本更新,而无需更新您的 Terraform 配置。然后,您可以计划何时要升级您的配置以使用 Terraform 的新版本,并仔细检查更改以确保您的项目仍然按预期工作。
例如,如果您使用 Terraform 1.0.0 编写 Terraform 配置,您将向 terraform { } 块添加 required_version = "~> 1.0.0"。这将允许您和您的团队使用任何 Terraform 1.0.x 版本,但您需要更新您的配置以使用 Terraform 1.1.0 或更高版本。
清理你的基础设施
销毁在本教程中创建的基础设施。对确认提示回复 yes。
$ terraform destroy
random_pet.name: Refreshing state... [id=ruling-sunbeam]
data.aws_ami.amazon_linux: Reading...
data.aws_ami.amazon_linux: Read complete after 1s [id=ami-0676a735c5f8e67c4]
aws_instance.web: Refreshing state... [id=i-0711f6d7f58958fea]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_instance.web will be destroyed
- resource "aws_instance" "web" {
- ami = "ami-0676a735c5f8e67c4" -> null
- arn = "arn:aws:ec2:us-west-2:949008909725:instance/i-0711f6d7f58958fea" -> null
## ...
Plan: 0 to add, 0 to change, 2 to destroy.
Changes to Outputs:
- application_url = "ec2-35-94-148-223.us-west-2.compute.amazonaws.com/index.php" -> null
- domain_name = "ec2-35-94-148-223.us-west-2.compute.amazonaws.com" -> null
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
aws_instance.web: Destroying... [id=i-0711f6d7f58958fea]
aws_instance.web: Still destroying... [id=i-0711f6d7f58958fea, 10s elapsed]
aws_instance.web: Still destroying... [id=i-0711f6d7f58958fea, 20s elapsed]
aws_instance.web: Still destroying... [id=i-0711f6d7f58958fea, 30s elapsed]
aws_instance.web: Still destroying... [id=i-0711f6d7f58958fea, 40s elapsed]
aws_instance.web: Destruction complete after 41s
random_pet.name: Destroying... [id=ruling-sunbeam]
random_pet.name: Destruction complete after 0s
Destroy complete! Resources: 2 destroyed.
下一步
现在你已经使用 Terraform CLI 管理了 Terraform 版本。在生产中使用 Terraform 时,我们强烈建议你和你的团队制定计划和流程,以确定如何管理 Terraform 版本和处理升级。
HCP Terraform 和 Terraform Enterprise 包含帮助团队协同处理 Terraform 项目的功能,例如为 Terraform 提供托管执行环境以及对团队和权限的支持。当你使用 HCP Terraform 或 Terraform Enterprise 时,你可以配置每个 HCP Terraform 工作区以使用你指定的 Terraform 版本。
有关本教程涵盖的主题的更多信息,请查看以下资源。
- 在 Terraform Cloud 中管理 Terraform 版本教程。
- Terraform 版本约束文档,了解有关版本约束的详细说明。
- 锁定和升级提供程序版本教程。