SREチームの安達 (@adachin0817)です。ランサーズやグループ会社ではTerraform v0.12.29を利用して、AWSのインフラコード化をしています。ようやくグループ会社すべてAWSに移行が完了となり、次なるチャレンジとしてはTerraformのバージョンアップを対応することとなりました。また、以下4/15にv0.15.0もリリースされたということもあり、非常に良い機会となりました。
まずは各プロジェクトについて簡単に説明をしていきたいと思います!
Terraform 0.15 is out, which can also be considered a pre-release for 1.0 if all goes well. ✨ It’s finally happening! Great quality of life improvements around Windows terminals, sensitive values, and more. https://t.co/efilxjlMiP
— Mitchell Hashimoto (@mitchellh) April 14, 2021
https://t.co/wojhhgL4eb
バージョンアップこの機会にやらねば…— adachin👾SRE (@adachin0817) April 14, 2021
各サービスとDeployサーバーについて
現状Terraformの管理としてはDeployサーバーの各ディレクトリごとにリポジトリがあり、terraform applyを実行して運用しています。ランサーズ本体はWordPressや社内で利用しているコンテナなどはTerraformで管理されていますが、それ以外は完全にTerraform化されていない状態です。今後はterraform importですべてのリソースをコード管理していく予定なので、その際はまたブログ致します。それ以外のプロジェクトであるLancers Creative、Prosheet、Lancers Agent、MENTAはECS/Fargateに移行しているので、すべてTerraformでコード管理しています。また、CircleCIでTerraform CI(validate,plan)を実行しているということもあり、今後terraform applyもCircleCIで行う予定なので、Deployサーバーでの運用は廃止していく予定です。会社的にも成長していく中でバージョンアップが疎かになっているのは事実でした。
Terraform CIに関しては個人ブログに書いていますので参考にしてみてください。
バージョンアップの流れとエラー対応について
流れ
- ブランチ作成後、DeployサーバーでTerraform v0.13.0に上げる
- terraform init -reconfigure
- terraform 0.13upgrade
- terraform planにより差分を修正する
- tfstateファイルの修正
- terraform planで差分がなくなったらv0.15.0にバージョンアップ
- terraform state replace-provider registry.terraform.io/-/aws hashicorp/aws によるプロバイダー変更
- terraform init
- terraform planで差分がなくなっていればバージョンアップ完了
エラー対応について以下まとめてみました。まず前提として、以下のようにv0.12系からいきなりv0.15にはバージョンアップができません。なのでv0.13にあげてから徐々に差分をなくすことが重要になります。
$ terraform init -reconfigure
│ Error: Invalid legacy provider address
│
│ This configuration or its associated state refers to the unqualified provider "aws".
│
│ You must complete the Terraform 0.13 upgrade process before upgrading to later versions.
$ terraform state replace-provider registry.terraform.io/-/aws hashicorp/aws
Terraform will perform the following actions:
~ Updating provider:
- registry.terraform.io/-/aws
+ registry.terraform.io/hashicorp/aws
Changing 33 resources:
また、legacy providerになっているので、providerも新しく変更しました。
- Warning: Version constraints inside provider configuration blocks are deprecated
$ terraform init -reconfigure
│ Warning: Version constraints inside provider configuration blocks are deprecated
│
│ on backend.tf line 5, in provider "aws":
│ 5: version = "= 3.36.0"
│
│ Terraform 0.13 and earlier allowed provider version constraints inside the provider configuration block, but that is now deprecated and will be removed in a future version of Terraform. To silence
│ this warning, move the provider version constraint into the required_providers block.
- backend.tf
provider "aws" {
region = "ap-northeast-1"
profile = "prd-menta-terraform"
}
terraform {
required_version = ">= 0.15"
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.36.0"
}
}
backend "s3" {
bucket = "prd-menta-terraform"
key = "terraform.tfstate"
region = "ap-northeast-1"
profile = "prd-menta-terraform"
}
}
v0.13以前ではプロバイダー構成がブロック内でプロバイダーバージョンの制約がありましたが、現在は非推奨になっています。なので上記のようにプロバイダーバージョンをrequired_providersに移行しました。
- Error: Invalid resource instance data in state
$ terraform plan
Error: Invalid resource instance data in state
on autoscale.tf line 86:
86: data "aws_iam_role" "ecs_service_autoscaling" {
Instance data.aws_iam_role.ecs_service_autoscaling data could not be decoded
from the state: unsupported attribute "assume_role_policy_document".
Error: Invalid resource instance data in state
on ecs.tf line 18:
18: resource "aws_ecs_service" "menta-app-service" {
Instance aws_ecs_service.menta-app-service data could not be decoded from the
state: unsupported attribute "placement_strategy".
0.13で廃止されたパラメーターがいくつがありますが、tfstateファイルに残っていると上記のようにエラーが起こります。対象パラメータを削除してterraform initし直せば解決します。必ずtfstateファイルはバックアップしましょう。以下不要なパラメーターの一覧を出してみました。対応後、terraform planが動作することができました。
・assume_role_policy_document
・role_id
・role_name
・adjustment_type
・placement_strategy
・cooldown
・metric_aggregation_type
・min_adjustment_magnitude
・step_adjustment
・vpc_id
・vpc_region
・request_parameters_in_json
- .terraform.lock.hclについて
https://www.terraform.io/upgrade-guides/0-14.html#opting-out-of-dependency-locking
次に、v0.15.0にバージョンアップをしてterraform initをするとterraform.lock.hclファイルというものが作成されます。これはv014.0から導入されましたが、.terraformサブディレクトリにキャッシュするロックファイルで、providerのバージョン指定がある場合に記録されます。こちらは公式がGitでバージョン管理すべきと記載されていたので対応しました。
- 最後にCircleCIのTerraform CIを修正
これにてバージョンアップは完了となります。下記のTerraform CIでも差分がないことを確認することができました。残り3つのプロジェクトも同様にバージョンアップします。
まとめ
Terraform v0.15.0の目立った新機能はあまり見受けられませんでしたが、バージョンアップの対応方法についてご紹介させていただきました。個人的に4つのプロジェクトをバージョンアップするにはなかなか荷が重かったですが、特にトラブルなく対応できたので良かったです。v0.15.0にしたということもあって、terraform planやapplyの速度が向上したと満足しております。この機会にv0.12系の方はぜひバージョンアップをしてみてください。
またSREも募集しておりますので、興味がある方はTwitterでDMいただければと思います!
※追記 2021/08/23
会社のTerraformをv0.15→v1.0.5にバージョンアップ完了した。特にトラブルなかったのでOK🙌
— adachin👾SRE (@adachin0817) August 23, 2021