0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TerraformのStateファイルどこに置くの問題、ちゃんと整理してみた件

0
Posted at

TerraformのStateファイルどこに置くの問題、ちゃんと整理してみた件

どうも、拓田です。
TerraformでAWSを構築していて、GitHub Actionsで自動化しようとしたら「リソースが既に存在する」エラーが連発しました。
原因はstateファイルの管理ができていなかったことで、その過程でstateファイルの保存先について色々調べたのでまとめます。


そもそもstateファイルって何?

Terraformは「今どんなリソースが作られているか」を記録したファイルを持っています。
それが stateファイル(terraform.tfstate) です。

terraform apply を実行
        ↓
AWSにVPC・EC2・RDSが作られる
        ↓
stateファイルに「これを作った」と記録される
        ↓
次回 terraform apply 時に「何が変わったか」を比較して差分だけ更新する

このstateファイルをどこに保存するかが backend の設定です。


stateファイルの保存先の種類

保存先 向いている環境
ローカル(デフォルト) 個人開発のみ。チームでは使えない
S3(AWS) AWSメインのチーム開発
Azure Blob Storage Azureメインのチーム開発
Google Cloud Storage GCPメインのチーム開発
HCP Terraform クラウド問わず使えるHashiCorp公式サービス
GitLab GitLabを使っているチーム向け

デフォルトはローカル保存ですが、チーム開発では必ず外部に保存する設定が必要です。


失敗談:S3 backendを後から追加したらハマった

GitHub Actionsで terraform apply を実行したところ、2回目以降にこんなエラーが出ました。

Error: DBSubnetGroupAlreadyExists: 
The DB subnet group 'terraform-db-subnet-group' already exists.

原因: stateファイルがGitHub Actionsの実行環境に保存されていたため、次回実行時には消えてしまっていた。Terraformが「何も作っていない」と思い込み、既存リソースを再作成しようとしてエラー。

S3 backendはmain.tfを作成する前に必ず設定してください。
後から追加すると、部分的に作られたリソースとstateの不整合が起きて手動削除が必要になります。

正しい順番はこちらです。

① S3バケットを作成する
        ↓
② main.tfにbackend設定を追加する  ← ここが先!
        ↓
③ AWSリソースを定義する
        ↓
④ terraform apply

AWSでのベストプラクティス:S3 + DynamoDB(※拓田調べ)

AWSメインのチームには S3 + DynamoDB の組み合わせが定番です。(※拓田調べ)

S3だけでは足りない理由:stateのロック問題

複数人が同時に terraform apply を実行するとstateファイルが壊れる可能性があります。
これを防ぐのが DynamoDBによるstateロック です。

Aさんが terraform apply を実行
        ↓
DynamoDBにロックを記録(「今Aさんが使用中」)
        ↓
Bさんが terraform apply を実行しようとする
        ↓
「ロック中です」とエラーになり、待機または中断
        ↓
Aさんの apply 完了後、ロック解除
        ↓
Bさんが実行できるようになる

設定方法

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

  backend "s3" {
    bucket         = "terraform-state-(バケット名)"
    key            = "terraform.tfstate"
    region         = "ap-northeast-1"
    dynamodb_table = "terraform-lock"  # ← ロック用テーブル
  }
}

S3バケットの設定

項目
バージョニング 有効にする(stateの変更履歴を残せる)
パブリックアクセス すべてブロック
暗号化 SSE-S3

HCP Terraformとは

HashiCorpが提供するTerraformのマネージドサービスです。
stateの管理からTerraformの実行まで、クラウドで一括管理できます。

主な機能

機能 内容
stateファイルの管理 保存・バージョン管理・ロック(自動)
GitHubとの連携 pushをトリガーにTerraformを自動実行
実行ログの管理 init/plan/applyの実行履歴をWeb UIで確認
planの承認フロー applyの前に人間が内容を確認してOKを出せる
変数・シークレット管理 GitHub Secretsの代わりにHCP側で管理できる
通知 Slack・メールへの実行結果通知
アクセス制御 チームメンバーごとに権限を設定できる

特に重要:planの承認フロー

本番環境での運用で特に強力な機能です。

GitHubにpush
        ↓
HCP TerraformがPlanを実行(何が変わるか表示)
        ↓
担当者がWeb画面で内容を確認・承認 ← 人間のレビューを挟める
        ↓
Applyが実行されてAWSに反映

GitHub Actionsだと -auto-approve で自動実行になりがちですが、
HCP Terraformでは意図しないリソース削除を防ぐ承認ステップを挟めます。


GitHub + HCP Terraform + AWSの連携構成

GitHub(コード管理)
    ↓ pushをトリガー
HCP Terraform(Terraformの実行・state管理)
    ↓ OIDCで認証
AWS(インフラの作成先)

各サービスの役割

サービス 役割
GitHub Terraformコードを管理・変更のトリガー
HCP Terraform Terraformを実行・stateファイルを管理
AWS 実際にリソースが作られる場所

S3 + DynamoDB vs HCP Terraform

S3 + DynamoDB HCP Terraform
stateの保存 S3 HCP側が管理
ロック DynamoDB 自動で管理
Web UI なし あり(実行履歴が見られる)
planの承認フロー 自前で実装が必要 標準機能
クラウド依存 AWSに依存 クラウド問わず使える
料金 S3・DynamoDBの従量課金 小規模なら無料
セットアップの手軽さ やや手間 比較的シンプル

状況別おすすめ構成

状況 おすすめ
個人・ローカル開発 ローカル(デフォルト)
AWSオンリーのチーム GitHub Actions + OIDC + S3 + DynamoDB
マルチクラウド・大規模チーム GitHub + HCP Terraform + AWS
書籍で学習したい HCP Terraform(書籍はこちらが多い)

まとめ

  • stateファイルはTerraformが「何を作ったか」を記録するファイル
  • チーム開発では必ずS3などの外部に保存する
  • AWSなら S3 + DynamoDB がベストプラクティス(DynamoDBはロック用)
  • S3 backendの設定はmain.tf作成前に必ずやること(後からだとハマる)
  • より高機能な管理がしたければ HCP Terraform が選択肢
  • planの承認フローは本番運用で特に重要

stateファイルの管理をちゃんとするだけで、チーム開発での事故がぐっと減ります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?