Terraformは、実リソースのメタデータと依存関係をtfstateに保持します。バックエンドを指定しない場合はローカルステート(terraform.tfstate)が既定で使われます。
ローカル運用は素早い検証に向きますが、チーム利用や機密性・可用性の要件には注意が必要です。Associate試験では、ローカルの性質・限界・安全な移行策を理解していることが問われます。
バックエンドを明示しない場合、Terraformは作業ディレクトリにterraform.tfstate(JSON)を作成し、そこに管理対象リソースのID・属性・依存関係を保存します。これは実態と計画の差分計算や、参照(dataソース、出力値)に必須です。
ローカルバックエンドは状態ロックを提供しません。つまり、同じステートを複数のプロセスが同時に更新しても保護されません。チームや自動化での並行実行には不向きです。
tfstateにはシークレット相当の値が含まれることがあります。ローカルでは暗号化されず、OSのファイル権限やディスク暗号化に依存します。誤ってVCSにコミットしないよう.gitignoreが必須です。
ローカルステートの流れ
最小構成(バックエンド未指定=ローカル)と基本コマンド
# main.tf(例)
resource "null_resource" "example" {}
# 初期化と差分
terraform init
terraform plan
terraform apply
# ステートの確認
terraform state list
terraform state show null_resource.exampleローカルステートは、個人の検証、短命なサンドボックス、CIのエフェメラル実行(毎回クリーンに作って破棄)に向きます。ステートを共有しない前提なら、構成が簡単でスピード重視の運用が可能です。
一方で、チームで同じ環境(同じステート)を操作する場合は、ロック・監査・バックアップの面で制約が大きく、リモートバックエンド(S3+DynamoDB、Terraform Cloud/Enterpriseなど)が実務では標準的です。
| バックエンド | ロック | 共有性 | バックアップ容易さ |
|---|---|---|---|
| ローカル(既定) | なし | 基本的に不可(手渡しは非推奨) | 手動コピーやstate pull/push |
| S3 + DynamoDB | DynamoDBロックあり | URLで共有、IAM制御 | バージョニングとライフサイクル |
| Terraform Cloud/Enterprise | 組み込みロック | 組織内でワークスペース共有 | 自動バックアップと履歴 |
VCSへの誤コミット防止(推奨 .gitignore)
# .gitignore
terraform.tfstate
terraform.tfstate.backup
.crash.log
.terraform/
*.tfplan
# ステートに派生する一時ファイルも除外
最も大きなリスクは並行実行です。ローカルバックエンドはロックを持たないため、同じtfstateを2つのterraform applyが同時に更新すると、上書きや不整合が発生し得ます。これはリソースの重複作成や削除ミスの原因になります。
また、tfstateは平文JSONであり、秘匿情報が含まれる可能性があります。アクセス権限(例: chmod 600)とディスク暗号化の適用、バックアップファイルの管理が必須です。さらに、誤ってVCSにコミットすると、取り返しがつきません。
リファクタリング時にアドレスを変える場合(モジュール化、for_eachの導入など)は、tfstateの直接編集ではなく、terraform state mv / rm / import といったコマンドで整合性を取るのが安全です。
最低限のファイル保護と安全なリファクタリング
# ファイル権限の強化(Unix系)
chmod 600 terraform.tfstate terraform.tfstate.backup || true
# リソースアドレス変更時の安全な移動
terraform state mv aws_instance.web module.app.aws_instance.web
# 不要エントリの削除(実体リソースは消さない)
terraform state rm aws_security_group.legacy
# 既存リソースの取り込み
terraform import aws_s3_bucket.logs my-logs-bucket適用前後にステートのバックアップを取得しておくと、破損時の復旧が容易です。cpでのコピーに加えて、terraform state pullで現在のステートを安全に取得できます。
復旧時はterraform state pushでバックアップを反映できます。直接JSONを編集するより、stateコマンド群で最小変更に留めるのが安全です。バージョン差異や競合を避けるため、復旧は単一プロセス・単一端末で実施してください。
バックアップと復旧の実例
# バックアップの取得(ローカル/リモート双方で有効)
terraform state pull > backup-$(date +%Y%m%d%H%M%S).tfstate
# ローカルバックエンドへの復旧
terraform state push backup-20240101090000.tfstate
# ファイルコピーによる簡易バックアップ
cp terraform.tfstate terraform.tfstate.backup
# 計画ファイルの保存
terraform plan -out=tfplan
# 内容確認
terraform show -json tfplan > tfplan.jsonチーム運用や本番向けには、ロック・共有・監査が揃うリモートバックエンドへ移行します。S3+DynamoDBではオブジェクトバージョニングとテーブルロック、Terraform Cloudでは組み込みのロックと履歴が利用できます。
移行はbackendブロックを追加し、terraform init -migrate-stateを実行します。適切な権限(S3/DynamoDBのIAM、Terraform Cloudのトークン)を準備し、移行後にterraform state listで整合性を確認します。
S3+DynamoDBへの移行例
# backend設定(versions等は省略)
terraform {
backend "s3" {
bucket = "my-tfstate-bucket"
key = "envs/prod/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "my-tf-locks"
encrypt = true
}
}
# 事前準備(例)
# - S3: バージョニング有効、暗号化
# - DynamoDB: パーティションキー=LockID のテーブル
# - IAM: S3/DynamoDBへの適切な権限
# マイグレーション
terraform init -migrate-state
# 検証
terraform state list
terraform plan試験では、ステートの目的、ローカルの既定挙動、ロックの有無、機密情報の扱い、バックアップと復旧、そしてリモートバックエンドの利点と移行手順が問われやすいです。CLIコマンドの正確な使い分けも確認しましょう。
頻出コマンドの再確認
# ステート操作
terraform state list
terraform state show <address>
terraform state mv <from> <to>
terraform state rm <address>
terraform state pull > backup.tfstate
# 計画と適用
terraform plan -out=planfile
terraform apply planfileAssociate
問題 1
2名のエンジニアが同じディレクトリでローカルバックエンド(terraform.tfstate)を用い、ほぼ同時に terraform apply を実行しようとしています。最も適切な対策はどれですか?
正解: B
ローカルバックエンドは状態ロックを提供しないため、並行実行の競合を防げません。チーム運用では、ロックと共有を備えたリモートバックエンド(S3+DynamoDBやTerraform Cloud/Enterprise)へ移行するのが正解です。-lockはロック対応バックエンドで有効です。ワークスペースやplanファイルは競合回避の代替にはなりません。
ローカルステートは暗号化されていますか?
いいえ。terraform.tfstateは平文JSONとして保存され、暗号化はバックエンド依存です。ローカルではOSの権限設定やディスク暗号化を用い、VCSにコミットしない運用が必須です。
チームでローカルステートを安全に共有できますか?
基本的に非推奨です。ロック・監査・バックアップの観点から、S3+DynamoDBやTerraform Cloudなどのリモートバックエンドを利用してください。どうしても暫定運用が必要なら、同一ステートを絶対に共有しない(環境ごとに分離)ことが最低条件です。
tfstateを直接編集してもよいですか?
緊急時以外は避けてください。整合性を保つには terraform state mv / rm / import などのコマンドを使います。直接編集は破損リスクが高く、最後の手段です。編集前に必ずバックアップを取得してください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける
Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...
Terraform Authoring & Ops Pro: 上位資格の範囲と対策
上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...
Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす
Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...
Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義
Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...
Terraform Data Source徹底理解:既存リソースの参照で壊さず足す
Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...