升级至Terraform 0.13
总结
由于Terraform 0.13发布,我立即尝试进行升级。基本流程可以在Terraform AWS Provider Version 3升级指南中找到,按照指南进行修改即可。然而,有一些可能会遇到困难的要点,我在下面列出。
验证版本
我們使用Terraform來管理AWS和Datadog的資源,並且分別使用了它們的下一個版本。
-
- Terraform: 0.13.0
AWS provider: 2.3.0
Datadog provider: 2.12.1
GitHub provider: 2.9.2
事前准备
在更新Terraform到最新的0.12版本和更新各种提供者到最新版本的同时,更新状态(state)可以更容易地进行故障排除。如果使用AWS作为提供者,由于模块通常使用 terraform-aws-modules,建议事先更新模块到0.13版以进行兼容。
升级流程
在升级到Terraform 0.13版本之后,在资源目录下进行以下操作。
# ステートファイルの更新
$ terraform init [-reconfigure]
# TFファイルの書式を更新
$ terraform 0.13upgrade
# 差分がないことを確認
$ terraform plan
即使在计划中没有错误,但在应用时可能会出现错误,所以为了谨慎起见,我会先应用并更新状态。
错误清单 (Error list)
状态中的资源实例数据无效
% terraform apply
Error: Invalid resource instance data in state
on main.tf line 4:
4: resource "aws_route53_zone" "this" {
Instance aws_route53_zone.this data could not be decoded from the state:
unsupported attribute "vpc_id"
当发生以下情况时,即如果在0.13版本中已废弃的参数仍然存在于状态文件中:从后端获取状态文件,删除相应参数(例如上述例子中的vpc_id),然后进行更新即可解决问题。
试图删除aws_route53_record
% terraform apply
Terraform will perform the following actions:
# module.acm.aws_acm_certificate_validation.default must be replaced
-/+ resource "aws_acm_certificate_validation" "default" {
certificate_arn = "***"
~ id = "***" -> (known after apply)
~ validation_record_fqdns = [
- "***",
] -> (known after apply) # forces replacement
- timeouts {}
}
# module.acm.aws_route53_record.validation will be destroyed
- resource "aws_route53_record" "validation" {
- allow_overwrite = true -> null
- fqdn = "***" -> null
- id = "***" -> null
- name = "***" -> null
- records = [
- "***",
] -> null
- ttl = 60 -> null
- type = "***" -> null
- zone_id = "***" -> null
}
# module.acm.aws_route53_record.validation[1] will be destroyed
- resource "aws_route53_record" "validation" {
- allow_overwrite = true -> null
- fqdn = "***" -> null
- id = "***" -> null
- name = "***" -> null
- records = [
- "***",
] -> null
- ttl = 60 -> null
- type = "***" -> null
- zone_id = "***" -> null
}
# module.acm.aws_route53_record.validation["subdomain.***"] will be created
+ resource "aws_route53_record" "validation" {
+ allow_overwrite = true
+ fqdn = (known after apply)
+ id = (known after apply)
+ name = "***"
+ records = [
+ "***",
]
+ ttl = 60
+ type = "***"
+ zone_id = "***"
}
# module.acm.aws_route53_record.validation["***"] will be created
+ resource "aws_route53_record" "validation" {
+ allow_overwrite = true
+ fqdn = (known after apply)
+ id = (known after apply)
+ name = "***"
+ records = [
+ "***",
]
+ ttl = 60
+ type = "CNAME"
+ zone_id = "Z3K9WE75AB6672"
}
由于 domain_validation_options 的类型从 List 更改为 Set,所以出现了问题。虽然 Upgrade Guide 中也有提到,但具体来说,可以使用 state mv 命令来更改与 ACM 相关的域记录的 ID。如果数量很多,可能会相当麻烦。
% terraform state mv 'module.acm.aws_route53_record.validation[0]' 'module.acm.aws_route53_record.validation["***"]'
% terraform state mv 'module.acm.aws_route53_record.validation[1]' 'module.acm.aws_route53_record.validation["subdomain.***"]'
无法从共享缓存中安装提供程序。
% terraform init -reconfigure
Initializing modules...
Initializing the backend...
Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Finding terraform-providers/datadog versions matching "2.12.1"...
- Using terraform-providers/datadog v2.12.1 from the shared cache directory
Error: Failed to install provider from shared cache
Error while importing terraform-providers/datadog v2.12.1 from the shared
cache directory: after linking
registry.terraform.io/terraform-providers/datadog from provider cache at
/app/terraform/plugins it is still not detected in the target directory; this
is a bug in Terraform.
在初始化Datadog提供程序时发生了问题。这可能与提供程序名称从hashicorp/datadog更改为terraform-providers/datadog有关。删除本地创建的.terraform目录后问题解决了。
无法加载插件
$ terraform apply
Error: Could not load plugin
Plugin reinitialization required. Please run "terraform init".
Plugins are external binaries that Terraform uses to access and manipulate
resources. The configuration provided requires plugins which can't be located,
don't satisfy the version constraints, or are otherwise incompatible.
Terraform automatically discovers provider requirements from your
configuration, including providers used in child modules. To see the
requirements and constraints, run "terraform providers".
Failed to instantiate provider "registry.terraform.io/-/aws" to obtain schema:
unknown provider "registry.terraform.io/-/aws"
在使用 Workspace 的目录中发生了问题。原因似乎是每个 Workspace 的 state 文件版本不同。如果 init 和 plan 没有问题,可以执行 apply 来更新 state 文件以解决该问题。