くりにっき

フルスタックキュアエンジニアです

AWSのTerraformでDynamoDB state lockingからS3-native state lockingに移行する

前置き

先日Terraform 1.10がリリースされました。

www.hashicorp.com

github.com

Experimentalではありますが個人的には Introduce S3-native state locking (Terraform実行時のロックでDynamoDBが不要になる)がアツイ機能で、いち早く使いたいと思っていました。

github.com

しかし、軽くググった感じ移行ガイド的なものが見つからなかったので手順をまとめました。(英語版は末尾にあります)

手順

Terraformのbackendを書き換える

backendで dynamodb_table を指定してる箇所を use_lockfile *1 に書き換えます。

 terraform {
   backend "s3" {
-    dynamodb_table = "terraform-lock"
+    use_lockfile = true
   }
 }

Terraformで使ってるIAMユーザやIAMロールがterraform.tfstate.tflockにアクセスできるようにする

S3-native state lockingはBackendで利用しているS3バケットのtflockファイルへの s3:PutObject が必要になります。

例えば下記のようなkeyの場合、末尾に .tflock を付与した terraform.tfstate.tflock にも権限が必要です。*2

terraform {
  backend "s3" {
    key = "terraform.tfstate"
  }
}

そのため、下記のように変更が必要です。(TerraformがAmazonS3FullAccessを持っている場合には不要)

Before

{
  "Action": [
    "s3:GetObject",
    "s3:PutObject",
    "s3:DeleteObject"
  ],
  "Resource": "arn:aws:s3:::YOUR-BACKEND-BUCKET-NAME/terraform.tfstate",
  "Effect": "Allow"
},

After

{
  "Action": [
    "s3:GetObject",
    "s3:PutObject",
    "s3:DeleteObject"
  ],
  "Resource": [
    "arn:aws:s3:::YOUR-BACKEND-BUCKET-NAME/terraform.tfstate",
    "arn:aws:s3:::YOUR-BACKEND-BUCKET-NAME/terraform.tfstate.tflock"
  ],
  "Effect": "Allow"
},

一応

"Resource": "arn:aws:s3:::YOUR-BACKEND-BUCKET-NAME/terraform.tfstate*"

みたいなこともできるとは思いますが、AWSでは 最小特権アクセス許可を適用する のをベストプラクティスに挙げているので .tflock だけに権限を追加するのがいいと思っています。

https://github.com/sue445/terraform-aws-template/blob/main/cloud_formation/setup-terraform.yml のようにTerraform実行に必要なリソースをCloudFormationでセットアップしてるのであればその時に使ったテンプレートファイルを編集して再実行するのが一番楽だと思います。

この時点でTerraform実行時にDynamoDBが不要になっているはずなのでTerraformを実行する

問題なければTerraform実行用のDynamoDBのテーブルと、そのテーブルへの権限を消す

小規模利用のAWSアカウントであればTerraform実行用のDynamoDBがアカウント全体の費用のそれなりの割合を占めているはずなので、この時点で消していいでしょう。

中規模以降のAWSアカウントであればTerraform実行用のDynamoDBの費用の割合なんて微々たるものなので消しても消さなくてもどっちでもいいと思います。

あとがき1

僕がメンテしてる https://github.com/sue445/terraform-aws-template でもS3-native state lockingに移行したのですが*3、terraform-aws-templateの利用者のための移行手順は下記に書いています。

github.com

あとがき2

自分のリポジトリでは https://github.com/hashicorp/terraform/pull/35661 だけを見て移行したので気づかなかったんですが、 https://developer.hashicorp.com/terraform/language/backend/s3 にはS3-native state lockingに利用するtflockオブジェクトに対する権限が含まれていなかったので追記するPRを出してます。(マージ済)

github.com