将个人开发的Terraform升级至v0.12

概括

这篇文章总结了我和朋友(@kobayashi-m42)一起使用的服务Mindexer(ミンデクサー)在升级到Terraform v0.12时所做的处理工作。

关于Mindexer(ミンデクサー)的信息。

我使用AWS + Laravel + Vue.js开发了一个整理Qiita收藏的服务!【个人开发】在这里解释了服务的概要,希望您也能看一下?我还介绍了后端和前端技术,并附带了源代码。

目标读者

    TerraformとAWSを運用レベルで利用している方

希望查看源代码的人们

如果您想快速查看更改时的差异,请查看 这里。

这将是执行升级时的差异。

大部分的修改是由terraform 0.12升级命令进行的,稍后会进行解释。

事前准备

根据《升级到Terraform v0.12》中的内容,我们将进行升级的前期准备工作。

请确保完成升级至0.11.4版本。

按照《升级到Terraform v0.12》的指示,首先确保成功升级到0.11.4版本。

根据您当前使用的版本来看,直接升级到0.12版本可能会出现问题,因此最好事先做好准备。

为了能够使用与0.12版本兼容性检查命令,在0.11.4版本中已经可以执行此命令,因此为了利用它,首先升级到0.11.4版本是一个安全的选择。

在0.11.4的版本上执行terraform apply。

执行terraform apply,并保持无差异的状态。

为了避免麻烦,最好提前做这件事是明智的。

使用 Terraform 0.12 checklist 进行兼容性检查。

在版本0.11.4中,添加了一个名为0.12checklist的子命令。

移动到管理 tfstate 的目录下,执行以下命令。

terraform 0.12的检查清单

由于 Mindexer 在以下目录中进行 tfstate 管理,因此我在以下目录中执行了操作。

- providers/aws/environments/10-network
- providers/aws/environments/11-acm
- providers/aws/environments/12-ecr
- providers/aws/environments/20-bastion
- providers/aws/environments/21-api
- providers/aws/environments/22-frontend
- providers/aws/environments/23-rds

如果显示出以下结果,则升级准备工作已经完成。

Looks good! We did not detect any problems that ought to be
addressed before upgrading to Terraform v0.12.

This tool is not perfect though, so please check the v0.12 upgrade
guide for additional guidance, and for next steps:
    https://www.terraform.io/upgrade-guides/0-12.html

如果有需要升级的提供商,请按照消息中的指示进行升级。

由于我在 Mindexer 中使用 terraform-provider-aws ,所以我将其版本更新为最新版。

进行0.12的升级

将Terraform升级到0.12版本。

进行terraform 0.12升级

通过执行upgrade命令,可以进行源代码的修正。

在负责管理 tfstate 的目录中运行 terraform 0.12 升级命令。

- providers/aws/environments/10-network
- providers/aws/environments/11-acm
- providers/aws/environments/12-ecr
- providers/aws/environments/20-bastion
- providers/aws/environments/21-api
- providers/aws/environments/22-frontend
- providers/aws/environments/23-rds
This command will rewrite the configuration files in the given directory so
that they use the new syntax features from Terraform v0.12, and will identify
any constructs that may need to be adjusted for correct operation with
Terraform v0.12.

We recommend using this command in a clean version control work tree, so that
you can easily see the proposed changes as a diff against the latest commit.
If you have uncommited changes already present, we recommend aborting this
command and dealing with them before running this command again.

Would you like to upgrade the module in the current directory?
  Only 'yes' will be accepted to confirm.

  Enter a value:

按下“确认”按钮后,将完成修改。

如果从同一个项目中导入模块,那么无法修改该模块内的代码,因此在这种情况下,还需要对每个模块进行执行。

terraform 0.12upgrade ../../../../modules/aws/vpc/
terraform 0.12upgrade ../../../../modules/aws/acm/
terraform 0.12upgrade ../../../../modules/aws/ecr/
terraform 0.12upgrade ../../../../modules/aws/api/
terraform 0.12upgrade ../../../../modules/aws/bastion/
terraform 0.12upgrade ../../../../modules/aws/frontend/
terraform 0.12upgrade ../../../../modules/aws/rds/

修复 terraform init 执行时出现错误的部分。

请在管理tfstate的以下目录中执行terraform init。

- providers/aws/environments/10-network
- providers/aws/environments/11-acm
- providers/aws/environments/12-ecr
- providers/aws/environments/20-bastion
- providers/aws/environments/21-api
- providers/aws/environments/22-frontend
- providers/aws/environments/23-rds

由于仅通过terraform 0.12的升级无法修复的部分,因此我们将努力地进行修正。

处理事项

以下所述的是在terraform 0.12升级中无法改写的部分。

修正缩进错误和空行

执行terraform 0.12升级时出现了缩进错误和额外的空行被添加的问题。

由于运行 terraform fmt 后未修复,因此我自己手动修复了这部分。

在v0.10版本中,terraform.env属性已被弃用,并在v0.12版本中移除。

我已经将使用 terraform.env 的部分更改为 terraform.workspace。

顺便提一下,在 v0.10 版本的时候,这个功能就已经被弃用了,所以其实应该更早一点修正的。

Error: Invalid "terraform" attribute

  on ../../../../modules/aws/vpc/main.tf line 2, in resource "aws_vpc" "vpc":
   2:   cidr_block           = lookup(var.vpc, "${terraform.env}.cidr", var.vpc["default.cidr"])

The terraform.env attribute was deprecated in v0.10 and removed in v0.12. The
"state environment" concept was rename to "workspace" in v0.12, and so the
workspace name can now be accessed using the terraform.workspace attribute.

错误:属性键含义不明确

在 Mindexer 中,我们使用 terraform.workspace 来区分不同的环境,例如开发环境和生产环境。

我曾经使用了一种技巧,根据 terraform.workspace 的值来为每个环境设置环境变量。

variable "vpc" {
  type = "map"

  default = {
    default.az_1a      = "ap-northeast-1a"
    default.az_1c      = "ap-northeast-1c"
    default.az_1d      = "ap-northeast-1d"
    default.name       = "prod-qiita-stocker-vpc"
    stg.name           = "stg-qiita-stocker-vpc"
    default.cidr       = "10.1.0.0/16"
    stg.cidr           = "10.3.0.0/16"
  }
}

resource "aws_vpc" "vpc" {
  cidr_block           = "${lookup(var.vpc, "${terraform.env}.cidr", var.vpc["default.cidr"])}"
  enable_dns_support   = "true"
  enable_dns_hostnames = "true"

  tags {
    Name = "${lookup(var.vpc, "${terraform.env}.name", var.vpc["default.name"])}"
  }
}

执行terraform计划会出现大量如下错误。

Error: Ambiguous attribute key

  on ../../../../modules/aws/vpc/variable.tf line 5, in variable "vpc":
   5:     default.az_1a      = "ap-northeast-1a"

If this expression is intended to be a reference, wrap it in parentheses. If
it's instead intended as a literal name containing periods, wrap it in quotes
to create a string literal.

处理方法很简单,只需要将使用的map.default键名用””括起来。

通过进行以下修正,使之能够像升级之前一样进行使用。

variable "vpc" {
  type = map(string)

  default = {
    "default.az_1a"      = "ap-northeast-1a"
    "default.az_1c"      = "ap-northeast-1c"
    "default.az_1d"      = "ap-northeast-1d"
    "default.name"       = "prod-qiita-stocker-vpc"
    "stg.name"           = "stg-qiita-stocker-vpc"
    "default.cidr"       = "10.1.0.0/16"
    "stg.cidr"           = "10.3.0.0/16"
  }
}

resource "aws_vpc" "vpc" {
  cidr_block           = lookup(var.vpc, "${terraform.workspace}.cidr", var.vpc["default.cidr"])
  enable_dns_support   = "true"
  enable_dns_hostnames = "true"

  tags = {
    Name = lookup(var.vpc, "${terraform.workspace}.name", var.vpc["default.name"])
  }
}

Terraform fmt的规范有变化吗?

以前的版本(直到0.11.4),只需在项目根目录下运行 terraform fmt,即可将所有 .tf 文件格式化。但现在为了做同样的事情,需要在执行命令时加上 -recursive 选项。

自动格式化当前目录下所有 Terraform 文件及其子目录中的文件。

最后

这次升级至0.12版本是一个具有破坏性变化的重大版本更新。

尽管如此,官方文档中详细列出了迁移方法,并且提供了诸如terraform 0.12upgrade等辅助命令,因此我们能够相对顺利地进行升级。

谢谢您一直阅读到最后。

bannerAds