MENU

Terraformのtfstate、チームで使うならS3に置くべき理由

terraform plan と apply、何気なく打ってたけど違いを説明を説明する画像

おはようございます、YASUです。

先日「tfstateはTerraformの記憶そのもの」という話を書きましたが、記事の最後で「実務ではこのファイルをS3などの共有ストレージに置くのが基本」と少し触れたまま終わっていました。今日はその続き、リモートステートについて整理してみます。

目次

結論

tfstateファイルを自分のPCに置いたままにしていると、チームで作業する時に大きな事故につながります。S3などの共有ストレージに置く「リモートステート」という仕組みを使うことで、みんなが同じ「今の状態」を見ながら安全に作業できるようになります。

まず、tfstateをローカルに置いたままだと何が起きるか

tfstateは「今、実際のAWS上に何が存在しているか」を記録した台帳でした。これが自分のPCの中(ローカル)にしかない状態で、チームの別のメンバーも同じインフラをTerraformで触るとします。

Aさん:自分のPCのtfstateを見て「今の状態」を把握 → applyで変更
Bさん:自分のPCのtfstateを見て「今の状態」を把握 → applyで変更

ここで問題になるのが、AさんとBさんが持っているtfstateの中身が、実は微妙にズレてしまうということです。Aさんが変更した後の最新状態を、Bさんのローカルのtfstateはまだ知りません。その状態でBさんがapplyしてしまうと、Aさんの変更を意図せず巻き戻してしまったり、二重にリソースを作ろうとしてエラーになったりします。

リモートステートという解決策

この問題を解決するのが、tfstateを個人のPCではなく、S3のような「みんなが共通してアクセスできる場所」に置く、という考え方です。

terraform {
  backend "s3" {
    bucket = "my-terraform-state-bucket"
    key    = "prod/terraform.tfstate"
    region = "ap-northeast-1"
  }
}

この設定を書いておくと、tfstateはローカルではなく指定したS3バケットに保存されるようになります。チームの誰がapplyしても、常に同じ「最新の状態」を参照することになるので、AさんとBさんのtfstateがズレる、という事故がなくなります。

もう一つの重要な仕組み:ステートロック

S3に置くだけでは、実はまだ問題が残っています。AさんとBさんが「まったく同じタイミング」でapplyを実行してしまったらどうなるでしょうか。これを防ぐのが「ステートロック」という仕組みです。

誰かがapplyを実行している間、そのtfstateに「ロック」がかかり、他の人は同時にapplyできないようになります。実務ではDynamoDBをロック用のテーブルとして併用する構成がよく使われます(バックエンドのバージョンによっては、S3単体でロック機能を持つ場合もあります)。

terraform {
  backend "s3" {
    bucket         = "my-terraform-state-bucket"
    key            = "prod/terraform.tfstate"
    region         = "ap-northeast-1"
    dynamodb_table = "terraform-lock"
  }
}

これで「今、誰かが作業中です。少し待ってください」という状態を作れるので、同時実行による事故を防げます。

なぜS3が使われるのか

単に「共有できる場所」であればどこでもいいわけではなく、S3が選ばれるのには理由があります。

  • バージョニング機能があり、過去のtfstateの状態に戻せる
  • 暗号化に対応しており、機密性の高い情報(場合によってはパスワードなどが含まれることもある)を保護できる
  • 可用性が高く、AWSサービスとの相性も良い

まとめ

  • tfstateをローカルのままにしておくと、チーム開発で状態のズレによる事故が起きやすい
  • S3などに置く「リモートステート」で、みんなが同じ最新状態を参照できるようにする
  • 同時実行を防ぐための「ステートロック」も合わせて設定するのが実務での基本

個人の練習ではローカルのtfstateで十分ですが、チーム開発を意識するなら、このリモートステートの考え方は早めに触れておいて損はないと思います。それでは、また明日!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次