継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

Terraform AWS Provider v3 -> v4 へ移行するのに役立つツール『tfrefactor』を試してみる

タダです.

Terraform AWS Provider の v4 が出てきたことでバージョンアップされた方も多いと思います.v4 へのバージョンアップでは S3 周りの変更が多く苦労するという情報が見かけられ,その変更をサポートするツールとして tfrefactor が紹介されてたので検証で試した内容をこの記事にまとめていきます.

github.com

tfrefactor とは

tfrefactor の特徴は以下の3つがあります.v4 以降の aws_s3_bucket リソースの移行,AWS Provider のバージョン制約の更新,リソースのインポートが必要があるが,そのサポートとしての CSV 出力があげられてます.

・Migrate aws_s3_bucket resource arguments to independent resources available since v4.0.0 of the Terraform AWS Provider.

・Update version constraints of the Terraform AWS Provider defined in configurations.

・Get a table (in .csv format) of each new resource with its parent aws_s3_bucket to enable resource import.

tfrefactor の導入

tfrefactor は Go で開発されており,バージョン 1.17以上なら次のコマンドで導入できます.

$ ghq get https://github.com/anGie44/ohmyhcl
$ make install
cd ./tfrefactor && go mod download
cd ./tfrefactor && go install
$ which tfrefactor
/Users/hoge/go/bin/tfrefactor

検証用の Terraform 設定

まずは Provider の設定や S3 のコードは次のようにしました.

terraform {
  required_version = ">= 1.0.0"

  backend "s3" {
    encrypt        = true
    bucket         = "hoge"
    key            = "hoge.tfstate"
    region         = "ap-northeast-1"
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.8.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_s3_bucket" "v3_test" {
  bucket = "hoge"
  acl = "private"
  cors_rule {
    allowed_origins = [ "*" ]
    allowed_methods = ["GET"]
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        kms_master_key_id = data.aws_kms.hoge.arn
        sse_algorithm     = "aws:kms"
      }
    }
  }

  versioning {
    enabled = true
  }
}

この状態で terraform plan で確認すると v3 では問題なかった定義がエラーとして表示されるようになりました.

╷
│ Error: Value for unconfigurable attribute
│ 
│   with aws_s3_bucket.v3_test,
│   on s3.tf line 9, in resource "aws_s3_bucket" "v3_test":
│    9: resource "aws_s3_bucket" "v3_test" {
│ 
│ Can't configure a value for "versioning": its value will be decided automatically based on the result of applying this configuration.


│ Error: Value for unconfigurable attribute

│   with aws_s3_bucket.v3_test,
│   on s3.tf line 9, in resource "aws_s3_bucket" "v3_test":
│    9: resource "aws_s3_bucket" "v3_test" {

│ Can't configure a value for "cors_rule": its value will be decided automatically based on the result of applying this configuration.
╵
╷
│ Error: Value for unconfigurable attribute
│ 
│   with aws_s3_bucket.v3_test,
│   on s3.tf line 9, in resource "aws_s3_bucket" "v3_test":
│    9: resource "aws_s3_bucket" "v3_test" {
│ 
│ Can't configure a value for "server_side_encryption_configuration": its value will be decided automatically based on the result of
│ applying this configuration.


│ Error: Value for unconfigurable attribute

│   with aws_s3_bucket.v3_test,
│   on s3.tf line 11, in resource "aws_s3_bucket" "v3_test":
│   11:   acl = "private"

│ Can't configure a value for "acl": its value will be decided automatically based on the result of applying this configuration.

tfrefactor の実行

そこで,tfrefactor の出番です.対象のリソースとファイル名を指定してコマンドを実行すると,s3_migrated.tf というファイルが新規に作成されます.コマンドオプションとして -c をつければ CSV 出力がされます(s3_new_resources.csvという名前のファイルが作成されます).

$ tfrefactor resource aws_s3_bucket s3.tf

作成されたファイルの内容を確認すると,エラーになっていた属性値が別リソースとして定義し直されています.もともとあったファイルは別名に変更して terraform plan をかけたら実行計画の確認が成功しましたが,新規リソースが作られるため,terraform importを使ってリソースの紐付けを行わないといけないです.

resource "aws_s3_bucket" "v3_test" {
  bucket = "hoge"
}
resource "aws_s3_bucket_acl" "v3_test_acl" {
  bucket = aws_s3_bucket.v3_test.id
  acl    = "private"
}

resource "aws_s3_bucket_cors_configuration" "v3_test_cors_configuration" {
  bucket = aws_s3_bucket.v3_test.id
  cors_rule {
    allowed_origins = [ "*" ]
    allowed_methods = ["GET"]
  }
}

resource "aws_s3_bucket_versioning" "v3_test_versioning" {
  bucket = aws_s3_bucket.v3_test.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "v3_test_server_side_encryption_configuration" {
  bucket = aws_s3_bucket.v3_test.id
  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = data.aws_kms.hoge.arn
      sse_algorithm     = "aws:kms"
    }
  }
}

terraform plan の確認

$ terraform plan
~中略~
Plan: 5 to add, 0 to change, 0 to destroy.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform
apply" now.

まとめ

tfrefactor の紹介と試しに使ってみた内容をまとめました.業務でも v4 へのバージョンアップを行うのでこの検証した内容を生かしていきたいです.

関連

sadayoshi-tada.hatenablog.com