LESSON 30分

plan/apply/destroyワークフロー

ストーリー

「Terraformのワークフローは3つのコマンドが中心だ。 planapplydestroy。この3つを正しく使いこなせれば、 インフラの構築・変更・削除が安全にできる」

木村先輩が強調した。

「特にplanは必ず実行しろ。applyの前にplanで確認する。 これは鉄則だ。planなしのapplyは、 レビューなしのmainマージと同じくらい危険だ」


Terraformの基本コマンドフロー

Terraform実行フロー

  terraform init        terraform plan        terraform apply
  ┌──────────┐        ┌──────────┐          ┌──────────┐
  │初期化      │  →    │変更       │    →    │適用       │
  │プロバイダ   │       │プレビュー  │        │リソース    │
  │ダウンロード │       │差分表示    │        │作成/変更   │
  └──────────┘        └──────────┘          └──────────┘

  terraform destroy
  ┌──────────┐
  │リソース    │
  │全削除      │
  └──────────┘

terraform init

プロジェクトの初期化を行います。最初に1回、またはプロバイダ変更時に実行します。

bash
# 基本的な初期化
terraform init

# 出力例
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.31.0...
- Installed hashicorp/aws v5.31.0

Terraform has been successfully initialized!

initが必要なタイミング

タイミング理由
プロジェクト初回プロバイダのダウンロード
プロバイダ追加/変更新しいプロバイダのダウンロード
バックエンド変更State保存先の変更
モジュール追加新しいモジュールのダウンロード

.terraform.lock.hcl

プロバイダのバージョンをロックするファイルです。必ずGitにコミットしてください。

hcl
# .terraform.lock.hcl(自動生成、Gitにコミット)
provider "registry.terraform.io/hashicorp/aws" {
  version     = "5.31.0"
  constraints = "~> 5.0"
  hashes = [
    "h1:abcdef...",
  ]
}

terraform plan

変更内容のプレビューを表示します。実際のリソースには影響しません。

bash
# 基本的なplan
terraform plan

# 変数ファイルを指定
terraform plan -var-file="production.tfvars"

# planの結果をファイルに保存
terraform plan -out=plan.tfplan

plan出力の読み方

terraform plan の出力

# リソース作成(+)
  + resource "aws_instance" "web" {
      + ami                          = "ami-0abcdef1234567890"
      + instance_type                = "t3.micro"
      + public_ip                    = (known after apply)
      + tags                         = {
          + "Name" = "web-server"
        }
    }

# リソース変更(~)
  ~ resource "aws_instance" "web" {
      ~ instance_type = "t3.micro" -> "t3.small"
        # (other attributes unchanged)
    }

# リソース削除(-)
  - resource "aws_instance" "old" {
      - ami           = "ami-0abcdef1234567890" -> null
      - instance_type = "t3.micro" -> null
    }

# 削除して再作成(-/+)
-/+ resource "aws_instance" "web" {
      ~ ami           = "ami-old" -> "ami-new"  # forces replacement
      ~ instance_type = "t3.micro" -> "t3.micro"
    }

Plan: 1 to add, 1 to change, 1 to destroy.

planシンボルの意味

シンボル意味影響
+新規作成新しいリソースが作られる
-削除既存リソースが削除される
~変更(インプレース)リソースを再作成せず更新
-/+削除して再作成リソースが一度削除され、新しく作られる
<=データソース読み取り既存リソースの情報を取得

terraform apply

planの内容を実際に適用します。

bash
# 対話的にapply(確認プロンプトあり)
terraform apply

# plan結果を直接apply(確認済み)
terraform apply plan.tfplan

# 自動承認(CI/CDで使用)
terraform apply -auto-approve

# 変数を指定
terraform apply -var="environment=production"

apply実行時の確認

terraform apply

Plan: 2 to add, 0 to change, 0 to destroy.

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 と入力

aws_vpc.main: Creating...
aws_vpc.main: Creation complete after 3s [id=vpc-0abc123def456]
aws_subnet.public: Creating...
aws_subnet.public: Creation complete after 1s [id=subnet-0def789abc123]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

terraform destroy

管理しているリソースを全て削除します。

bash
# 全リソース削除(確認あり)
terraform destroy

# 特定リソースのみ削除
terraform destroy -target=aws_instance.web

# 自動承認(テスト環境のクリーンアップ等)
terraform destroy -auto-approve

destroyの注意点

注意点対策
本番環境での誤destroyprevent_destroy ライフサイクルを設定
データの消失RDS, S3 は skip_final_snapshot 等を確認
依存リソースの順序Terraform が自動で逆順に削除
hcl
# 誤削除の防止
resource "aws_s3_bucket" "important" {
  bucket = "critical-data-bucket"

  lifecycle {
    prevent_destroy = true    # terraform destroy で削除されない
  }
}

その他の重要コマンド

terraform validate

構文チェックを行います(APIは呼び出さない)。

bash
terraform validate

# 出力例
Success! The configuration is valid.

terraform fmt

コードをフォーマットします。

bash
# フォーマット
terraform fmt

# 再帰的にフォーマット
terraform fmt -recursive

# チェックのみ(CI向け)
terraform fmt -check -recursive

terraform output

出力値を表示します。

bash
# 全出力を表示
terraform output

# 特定の出力
terraform output vpc_id

# JSON形式
terraform output -json

安全なワークフロー

推奨ワークフロー

安全なTerraformワークフロー

  1. ブランチを作成
     git checkout -b feature/add-rds

  2. .tf ファイルを編集
     vim main.tf

  3. フォーマット & バリデーション
     terraform fmt -recursive
     terraform validate

  4. Plan で確認
     terraform plan -out=plan.tfplan

  5. PR を作成 & レビュー
     git push && gh pr create

  6. レビュー承認後に Apply
     terraform apply plan.tfplan

  7. 結果を確認
     terraform output

CI/CDでのワークフロー

CI/CD × Terraform

PR 作成時:
  terraform fmt -check    → フォーマットチェック
  terraform validate      → 構文チェック
  terraform plan          → 変更内容をPRにコメント

マージ後:
  terraform apply -auto-approve  → 自動適用

まとめ

ポイント内容
initプロジェクト初期化、プロバイダダウンロード
plan変更のプレビュー、必ず apply 前に実行
apply変更の適用、plan結果を指定可能
destroyリソースの全削除、prevent_destroy で保護

チェックリスト

  • init → plan → apply のワークフローを実行できる
  • plan出力のシンボル(+, -, ~, -/+)を読み取れる
  • destroy の注意点と prevent_destroy を理解した
  • validate と fmt をCIに組み込む方法を把握した

次のステップへ

Step 4 の内容をチェックポイントクイズで確認しましょう。 Terraformの基礎が固まったら、Step 5で実際にAWSインフラをコード化します。


推定読了時間: 30分