メインコンテンツへスキップ

Terraform tfstate管理の鶏と卵問題

·
インフラ Terraform AWS 実践
目次

今日学んだこと
#

Terraformでリモートバックエンド(S3 + DynamoDB)を使う場合、 「tfstate用のS3/DynamoDBだけは先に別で作る」必要があることを学びました。 これは「鶏と卵問題」と呼ばれます。

学習内容
#

鶏と卵問題とは
#

Terraformで S3, CloudFront, Route53... を作りたい
↓
tfstateをS3に保存したい
↓
でも、そのS3自体をTerraformで作ると...
↓
「tfstate用S3のtfstate」はどこに保存する? ← 無限ループ

この循環参照を断ち切るため、tfstate用のS3/DynamoDBだけは最初に別で作成します。

各リソースの役割
#

サービス役割
S3tfstateファイルの保存場所
DynamoDBロック機構(同時編集防止)

解決策:backend-setupディレクトリ
#

fumi-til-infrastructure/
├── backend-setup/          ← 最初にこれだけ実行
│   ├── main.tf
│   └── terraform.tfstate   ← ローカルに残る
└── environments/
    └── prod/               ← backend-setup完了後に実行
        └── main.tf

注意点
#

  • backend-setup自体のtfstateはローカルに残る
  • .gitignoreで除外しつつ、ローカルで大切に保管

補足:この方法は唯一の正解ではない
#

本記事で紹介した「backend-setupディレクトリでtfstate用インフラを作成する」方法は、よく使われる方法の一つですが、唯一の正解ではありません。

Terragruntの開発元であるGruntworkの公式ディスカッションでは、以下の方法が並列で紹介されています。

方法概要メリットデメリット
手動作成(コンソール/CLI)AWSコンソールやCLIで直接作成シンプル、鶏と卵問題なしIaC原則に反する、手順が残らない
Terraformで作成(本記事の方式)別ディレクトリでTerraform管理IaCで管理可能ローカルtfstateの管理が課題
CloudFormation/CDKAWSネイティブツールで作成AWS内で完結ツール混在
Terragrunt自動でバックエンド作成DRY、環境管理が楽学習コスト
Terraform Cloud/Enterpriseマネージドサービス運用が楽有料

Gruntworkの見解
#

Gruntworkのディスカッションでは、手動作成について以下のように述べられています。

「これは始めるための簡単な方法です。管理するバックエンドが少数(例:会社全体で1〜3個のS3バケットのみ)であれば、このアプローチで十分うまくいきます。」

一方で、手動作成のデメリットとして「手動プロセスである」「すべてのインフラをコードで管理できていない」「バックエンドのセットアップ方法がドキュメント化されない」も指摘されています。

ディスカッションの内容を自分なり解釈すると「規模が小さい場合はS3/DynamoDBなどを使用する。開発規模が大きくなり、自動化などが必要の場合はTerragruntによる自動作成がおすすめ」という印象でした。

状況別の推奨
#

状況推奨方法
個人開発・学習手動作成 or Terraform(本記事の方式)
小規模チームTerraform + tfstateをS3に手動コピー
中規模以上Terragrunt or Terraform Cloud
エンタープライズTerraform Cloud/Enterprise

重要なのは、チームの規模やスキルセットに合った方法を選ぶことです。

まとめ
#

  • tfstate用のS3/DynamoDBは「先に別で作る」必要がある(鶏と卵問題)
  • backend-setup自体のtfstateはローカル管理となる
  • S3は保存、DynamoDBはロックの役割
  • 本記事の方法は「よく使われる方法の一つ」であり、状況に応じて他の方法も検討すべき

参考
#