前書き
以前までは、DynamoDBを使用して State Locking の管理を行っていたが、S3自体で State Locking をサポートできることを知った。今回は備忘録も兼ねて、DynamoDBを使わずにS3のみで State Locking を有効化する方法を記載する。
State Lockingの概要
Terraformでは、インフラの状態を terraform.tfstate ファイルで管理している。複数の開発者が同時に terraform apply を実行すると、ステートファイルの競合が発生し、インフラの整合性が崩れる危険がある。
これを防ぐために「State Locking」という機能が存在する。
State Lockingは、ステートファイルに対して「排他ロック」を行い、同時操作を防止する仕組みである。
従来はDynamoDBテーブルを利用してロック情報を管理していたが、Terraform v1.10以降はS3バックエンド自体でロックを行えるようになった。これにより、構築コストと運用負荷を大幅に減らすことができる。
構築前提条件
- Terraformを動作させる環境が存在する
- AWSの認証は、AWS-Vaultの設定方法を参考に設定している
- Terraformのバージョンが
v1.10以上
ディレクトリー構成
最終的に完成した際のディレクトリー構成。
.
├── terraform/
│ ├── .terraform # ⇦ 自動生成
│ ├── .terraform.lock.hcl # ⇦ 自動生成
│ ├── backend.tf
│ ├── providers.tf
│ └── main.tf
├── modules/
│ └── s3/
│ └── tfstate_management.tf
└── .gitignore
構築手順
tfstateを保存するバケットを作成
Terraformの状態ファイルを格納するためのS3バケットを用意する。以下のコードを tfstate_management.tf に記載する。
推奨事項
- バケットは、バージョニングを有効にしておく
- 誤って
tfstateを上書きした際の復旧に役立つ
# バケットの作成
resource "aws_s3_bucket" "terraform_state" {
bucket = "terraform-state-locking-example"
lifecycle {
prevent_destroy = true
}
}
# S3バケットのバージョニング機能(Versioning)を有効化する設定
resource "aws_s3_bucket_versioning" "terraform_state_versioning" {
bucket = aws_s3_bucket.terraform_state.id
versioning_configuration {
status = "Enabled"
}
}
Terraformのbackend設定を記述する
Terraformの設定ファイル(例:backend.tf)に、以下のようにS3バックエンドを設定する。use_lockfile = true を設定することで、S3による State Locking が有効化される。
terraform {
backend "s3" {
bucket = "terraform-state-locking-example"
key = "terraform.tfstate"
region = "ap-northeast-1"
use_lockfile = true # ⇦ 変更ポイント
}
}
State Lockingの設定を反映
バックエンドの設定を反映するために terraform init を実行する。
terraform init
実行完了後、S3の ステートファイル および ロックファイル が作成される。これにより、そのS3バケットで管理している tfstateファイル に対して State Locking が有効な状態となる。
注意事項
既存のバックエンド設定を変更したい場合は、terraform init -reconfigure を使用する。
(例:DynamoDBで設定していた State Locking をS3で行えるように変更した場合に使用する)
terraform init -reconfigure
動作確認
同じ環境で別の端末から terraform apply を同時に実行する。先にロックを取得したプロセスが完了するまで、もう一方はロック解除を待機する。これにより、DynamoDBを使わずともステートファイルの整合性が保たれていることが確認できる。
参考資料
- [公式] State Locking
- State Locking の仕組みを DynamoDB State Locking から S3 State Locking ヘ移行してみた
- Terraform v1.10 からは S3 Backend の State Lock に DynamoDB が必要なくなる
- Terraform S3 Backend でステートロックのための DynamoDB が不要になる use_lockfile = true
感想
これまでは、DynamoDBを使用したState Lockingを当たり前のように利用していましたが、S3でも同様のことができることを今回初めて知りました。今後は、新規環境の構築時にはS3を活用した方法へ切り替えていこうと思います。また、環境構築の際には、常に新しい手法やベストプラクティスがないかを確認することが大切だと感じました。これからの開発では、最新の情報に注意を払いながら構築を進めていこうと思います。