1. 概要
この記事では、以下の内容を解説します。
terraform init/plan/apply/destroyの役割と実行フローterraform planの出力記号(+/-/~/-/+/+/-)の読み方terraform applyの安全な実行方法と危険なオプションterraform destroyで一部リソースだけ削除する方法- よくある失敗パターンと対処法
TerraformのCLIコマンドは4つを順番に実行します。この記事では各コマンドの役割・主要オプション・出力の読み方を完全解説します。
2. 4コマンドの実行フローと役割
terraform init # 1. 初期化(プロバイダーのダウンロード等)
terraform validate # 2. 構文チェック(任意・推奨)
terraform plan # 3. 変更内容を確認(実際には何も変えない)
terraform apply # 4. 変更を適用(リソースを作成・変更・削除)
terraform destroy # 必要なときのみ: すべてのリソースを削除
| コマンド | 役割 | AWSリソースへの影響 |
|---|---|---|
terraform init | プロバイダーDL・バックエンド初期化 | なし |
terraform validate | HCL構文チェック | なし |
terraform plan | 変更差分の計算・表示 | なし |
terraform apply | 差分をAWSに適用 | あり |
terraform destroy | 全リソースを削除 | あり(破壊的) |
3. terraform init
何をするコマンドか
terraform initは作業ディレクトリを初期化するコマンドです。以下の処理を行います。
required_providersに書いたプロバイダーをダウンロードして.terraform/に保存backend設定がある場合はリモートバックエンドに接続.terraform.lock.hclを作成・更新してプロバイダーのバージョンを固定
# 基本の実行
terraform init
# 実行例(出力)
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.50.0...
- Installed hashicorp/aws v5.50.0 (signed by HashiCorp)
Terraform has been successfully initialized!
💡 ポイント:
terraform initは.terraform/ディレクトリが存在しない場合に必ず実行します。プロバイダーバージョンを変更したときや、新しいメンバーがリポジトリをクローンしたときも実行が必要です。
よく使うオプション
| オプション | 説明 | 使うタイミング |
|---|---|---|
-upgrade | プロバイダーを最新バージョンに更新 | バージョンを上げたいとき |
-reconfigure | バックエンド設定を再設定(Stateは移行しない) | バックエンド設定変更後 |
-migrate-state | バックエンド変更時にStateを移行 | S3バックエンドへの移行時 |
-backend=false | バックエンドの初期化をスキップ | CI環境等でバックエンド不要なとき |
# プロバイダーを最新バージョンに更新
terraform init -upgrade
# バックエンドを変更してStateを移行
terraform init -migrate-state
4. terraform plan
terraform planはTerraformコードとStateを比較し、「何を変更するか」を表示します。実際のリソースには何も変更を加えません。
terraform plan
# planをファイルに保存(apply時に使用)
terraform plan -out=tfplan
出力記号の読み方
planの出力で最も重要なのが記号による変更種別の表示です。
Terraform will perform the following actions:
# aws_instance.web will be created
+ resource "aws_instance" "web" { # + 新規作成
# aws_instance.old will be destroyed
- resource "aws_instance" "old" { # - 削除
# aws_instance.web will be updated in-place
~ resource "aws_instance" "web" { # ~ 変更(既存を更新)
# aws_instance.web must be replaced
-/+ resource "aws_instance" "web" { # -/+ 削除してから再作成(ダウンタイムあり)
# aws_instance.web must be replaced
+/- resource "aws_instance" "web" { # +/- 作ってから削除(create_before_destroy)
| 記号 | 意味 | ダウンタイム |
|---|---|---|
+ | 新規作成(create) | なし |
- | 削除(destroy) | あり |
~ | 変更(update in-place) | 通常なし |
-/+ | 置換(destroy→create) | あり |
+/- | 置換(create→destroy) | なし(create_before_destroy) |
⚠️
-/+(置換)が出たときは要注意。 本番環境でのダウンタイムや、RDS・S3のデータ消失リスクがあります。必ず内容を確認してからapplyしてください。
planの詳細な出力内容
# 変更のサマリー(plan出力の最終行)
Plan: 3 to add, 1 to change, 0 to destroy.
# 変更なし
No changes. Your infrastructure matches the configuration.
planをファイルに保存する(-out)
# planをファイルに保存
terraform plan -out=tfplan
# 保存したplanを使ってapply(差分が変わらないことを保証)
terraform apply tfplan
CI/CDパイプラインではplanとapplyを別ステップで実行することが多く、-outを使うことで「planした内容と同じものをapplyする」ことを保証できます。
5. terraform apply
terraform applyはplanの差分をAWSに適用します。デフォルトではplanを再計算して内容を表示し、yesの入力を求めます。
基本的な実行方法
# 基本の実行(planを再計算 → 確認 → 適用)
terraform apply
# 出力例
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes ← "yes" と入力して実行
planファイルを指定して実行する
# 事前に保存したplanを使ってapply(確認プロンプトなし)
terraform plan -out=tfplan
terraform apply tfplan
-auto-approve の危険性
# ❌ 本番環境での -auto-approve は危険
terraform apply -auto-approve # 確認なしで即実行される
-auto-approveは確認プロンプトをスキップします。CI/CDのステージング環境では使われますが、本番環境では使用を避けてください。 意図しない削除(-/+)が確認なしで実行されます。
-target オプションの注意点
# 特定リソースだけapplyする(応急処置用)
terraform apply -target=aws_instance.web
terraform apply -target=module.vpc
-targetは特定のリソースだけを対象にapplyします。依存関係が壊れた場合の応急処置として有効ですが、日常的な使用は推奨しません。 Stateと実際のリソースの整合性が崩れる原因になります。
-refresh-only(旧 terraform refresh)
# AWSの現在の状態をStateに同期する(リソースは変更しない)
terraform apply -refresh-only
AWS側で手動変更があった場合に、その状態をTerraformのStateに取り込みます。旧来のterraform refreshコマンドは非推奨となり、terraform apply -refresh-onlyが推奨されています。
6. terraform destroy
terraform destroyはTerraformが管理するすべてのリソースを削除します。
全削除の流れ
terraform destroy
# 削除される内容が表示される
Plan: 0 to add, 0 to change, 5 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure,
as shown above. There is no undo. Only 'yes' will be
accepted to confirm.
Enter a value: yes
⚠️ 警告:
terraform destroyはStateファイルで管理しているすべてのリソースを削除します。本番環境では絶対に実行しないでください。prevent_destroy = trueが設定されたリソースは削除をブロックします。
一部リソースだけ削除する方法
# 特定リソースだけ削除(-targetオプション)
terraform destroy -target=aws_instance.web
terraform destroy -target=module.old_service
# for_eachのリソース1つだけ削除
terraform destroy -target='aws_instance.web["dev"]'
または、for_eachやcountのソースデータから対象を削除してterraform applyする方法が安全です。
# before: dev/stg/prd の3つが存在
locals {
environments = { dev = "t3.micro", stg = "t3.small", prd = "t3.medium" }
}
# after: stg だけ削除したい → mapからstgを除いてapply
locals {
environments = { dev = "t3.micro", prd = "t3.medium" }
}
7. よくある失敗パターン
Error: No valid credential sources found
│ Error: No valid credential sources found
│ Please see https://registry.terraform.io/providers/hashicorp/aws
│ for more information about providing credentials.
原因: AWSの認証情報が設定されていない。
解決方法:
# 環境変数で設定
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_REGION="ap-northeast-1"
# または AWS CLIのプロファイルを使用
export AWS_PROFILE="myprofile"
Error: Failed to install provider
│ Error: Failed to install provider
│
│ Error while installing hashicorp/aws v5.50.0: could not query
│ provider registry for registry.terraform.io/hashicorp/aws
原因1: ネットワーク接続の問題(プロキシ環境等)
解決方法: プロキシ設定を確認する。.terraform.lock.hclが存在する場合は削除してから再度terraform initを実行する。
planとapplyの間に差分が生じる
│ Error: Provider produced inconsistent result after apply
原因: planとapply実行の間にAWS側でリソースの状態が変化した(別の人がapplyした、手動変更があった等)。
解決方法: 再度terraform planを実行して最新の差分を確認する。チームでTerraformを使う場合はState lockを活用して同時実行を防ぐ。
Error: Backend configuration changed
│ Error: Backend configuration changed
│
│ A change in the backend configuration has been detected,
│ which may require migrating existing state.
原因: backendブロックの設定を変更したのにterraform initを再実行していない。
解決方法:
terraform init -reconfigure # Stateは移行せず再設定
terraform init -migrate-state # Stateを新しいバックエンドに移行
8. 関連記事
- resourceブロックの使い方 — applyで作成されるリソースの書き方
- backendの設定方法 — Stateのリモート管理
- state管理とは — Stateファイルの役割とリスク
- lifecycleブロックの使い方 — destroy時の誤削除防止
- Terraformよくあるエラー集 — CLIエラー一覧
9. まとめ
terraform init→ プロバイダーのダウンロードと初期化。.terraform/を作成するterraform plan→ 変更内容の確認のみ。AWSには何も変更しない- plan出力の記号:
+=作成 /-=削除 /~=更新 /-/+=置換(要注意) terraform apply→ planを適用してAWSリソースを実際に変更する-auto-approveは本番環境では使わない。-targetは応急処置用terraform destroyはすべてのリソースを削除する破壊的コマンド- planは必ず
-outで保存してからapplyすると安全
動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/cli/commands