Terraform v0.12.29 → v0.15.0にバージョンアップしました

Terraform v0.12.29 → v0.15.0にバージョンアップしました

SREチームの安達 (@adachin0817)です。ランサーズやグループ会社ではTerraform v0.12.29を利用して、AWSのインフラコード化をしています。ようやくグループ会社すべてAWSに移行が完了となり、次なるチャレンジとしてはTerraformのバージョンアップを対応することとなりました。また、以下4/15にv0.15.0もリリースされたということもあり、非常に良い機会となりました。

まずは各プロジェクトについて簡単に説明をしていきたいと思います!


各サービスとDeployサーバーについて

現状Terraformの管理としてはDeployサーバーの各ディレクトリごとにリポジトリがあり、terraform applyを実行して運用しています。ランサーズ本体WordPressや社内で利用しているコンテナなどはTerraformで管理されていますが、それ以外は完全にTerraform化されていない状態です。今後はterraform importですべてのリソースをコード管理していく予定なので、その際はまたブログ致します。それ以外のプロジェクトであるLancers CreativeProsheetLancers AgentMENTAはECS/Fargateに移行しているので、すべてTerraformでコード管理しています。また、CircleCIでTerraform CI(validate,plan)を実行しているということもあり、今後terraform applyもCircleCIで行う予定なので、Deployサーバーでの運用は廃止していく予定です。会社的にも成長していく中でバージョンアップが疎かになっているのは事実でした。

Terraform CIに関しては個人ブログに書いていますので参考にしてみてください。

[AWS]CircleCIでTerraformのCI/CD環境を実装してみた


バージョンアップの流れとエラー対応について

流れ

  • ブランチ作成後、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