CTS-KB
インフラ

Terraform IaC 実践ガイド:準備編

#Terraform #IaC #Google Cloud #AWS #Azure

⚠️ なぜ「準備」が最も重要なのか

Terraform で最も多いトラブルは、準備不足のまま terraform apply を実行することで起きます。

よくある失敗パターン:

  • 権限不足で apply 失敗 → 中途半端なリソースが残る
  • API が有効化されておらず 403 SERVICE_DISABLED
  • State の保存先を決めずにローカルで実行 → チームで共有できない
  • 手動で作ったリソースと Terraform が衝突する

コードを書く前に、環境を整える。 これが Terraform 運用の鉄則です。

🗺️ 準備の全体像

Terraform を導入する前に、以下の 5 つを整理します。

1. クラウドアカウント設計

2. 認証方式の選定

3. 権限(IAM)設計

4. State 管理の設計

5. ディレクトリ構成の設計

順番が重要です。上から順に決めないと、後工程で手戻りが発生します。

☁️ 1. クラウドアカウント設計

環境分離の原則

本番・ステージング・開発は、プロジェクト(アカウント)レベルで分離します。

クラウド分離単位
Google Cloudプロジェクトmyapp-prod, myapp-stg
AWSアカウント本番アカウント、検証アカウント
Azureサブスクリプション本番サブスクリプション、検証サブスクリプション

同一プロジェクト内で環境を分けると、本番リソースを誤って削除するリスクが生まれます。

マルチクラウドの場合

クラウドごとに役割を明確にします。

例:
  Google Cloud → メインクラウド(Cloud Run, Cloud SQL 等)
  AWS          → 認証基盤のみ(Cognito)

「両方で同じことをやる」のではなく、各クラウドの得意領域を活かす設計にします。

🔐 2. 認証方式の選定

サービスアカウントキーは使わない

Terraform の認証で最も避けるべきは、サービスアカウントキー(JSON キー)の利用です。

方式セキュリティ運用コスト推奨
サービスアカウントキー漏洩リスクありキーのローテーション必要NG
Workload Identity Federation (WIF)キーレスローテーション不要推奨
gcloud auth(ローカル開発)個人認証手動ログイン開発のみ

Workload Identity Federation(WIF)

CI/CD パイプラインからの認証は WIF を使います。GitLab / GitHub Actions の OIDC トークンで、キーなしに Google Cloud や AWS に認証できます。

CI/CD ランナー
  ↓ OIDC トークン
Workload Identity Pool
  ↓ トークン交換
サービスアカウント(権限あり)
  ↓ 認証済み
Terraform 実行

クロスクラウド認証

Google Cloud と AWS の両方を Terraform で管理する場合:

GitLab Runner
  ├→ GCP WIF で Google Cloud に認証
  └→ GCP SA の OIDC トークン → AWS STS AssumeRoleWithWebIdentity
     → AWS IAM Role で AWS に認証

キーの受け渡しなしで、クラウド間の認証が成立します。

🛡️ 3. 権限(IAM)設計

最小権限の原則

Terraform 用のサービスアカウントには、必要最小限の権限だけを付与します。

✗ roles/owner(何でもできる → 危険)
✗ roles/editor(広すぎる)
○ 必要なロールだけを個別に付与

サービスアカウントの分離

1 つのサービスアカウントで全部やらず、用途別に分離します。

サービスアカウント用途権限
Terraform SAインフラ構築・変更リソース作成・変更権限
App Deployer SAアプリデプロイCloud Run デプロイ権限のみ
Monitoring SA監視読み取り専用

API の有効化を忘れない

Terraform でリソースを作る前に、対象の API を有効化する必要があります。

# Google Cloud の場合
gcloud services enable run.googleapis.com           # Cloud Run
gcloud services enable sqladmin.googleapis.com       # Cloud SQL
gcloud services enable secretmanager.googleapis.com  # Secret Manager

これを忘れると 403 SERVICE_DISABLED エラーになります。新しいサービスを使う際は、必ず確認してください。

💾 4. State 管理の設計

State とは

Terraform の State は、「Terraform が管理しているリソースの一覧」 です。

State ファイル(terraform.tfstate)
  ├ Cloud Run サービス A → 実際の GCP リソース
  ├ Cloud SQL インスタンス B → 実際の GCP リソース
  └ S3 バケット C → 実際の AWS リソース

State がないと、Terraform はどのリソースを自分が作ったのか判別できません。

リモートバックエンド必須

State はリモートに保存します。ローカルに置くと、チームで共有できません。

GCS に統合する

マルチクラウド構成(GCP + AWS + Azure)の場合、State の保存先をクラウドごとに分けると管理が煩雑になります。GCS(Cloud Storage)に統合すると、State の管理対象が 1 箇所にまとまり、運用がシンプルになります。

# GCP のスタックも、AWS のスタックも、同じ GCS バックエンド
terraform {
  backend "gcs" {
    bucket = "my-project-tfstate"
  }
}

State バケットの作成

State 保存用のバケットは Terraform 管理外で作成します(鶏と卵の問題)。

gsutil mb -l asia-northeast1 gs://my-project-tfstate
gsutil versioning set on gs://my-project-tfstate

バージョニングは必ず有効化します。State を壊した場合の復旧に必要です。

📁 5. ディレクトリ構成の設計

module / envs 分離パターン

terraform/
├── modules/
│   └── infra/
│       ├── gcp/              # GCP モジュール
│       │   ├── cloud-run/
│       │   ├── cloud-sql/
│       │   ├── load-balancer/
│       │   └── dns-zone/
│       └── aws/              # AWS モジュール
│           ├── cognito/
│           └── ses/

└── envs/                     # 環境別エントリーポイント
    ├── stg/
    │   ├── my-app/           # GCP スタック
    │   └── ec-auth/          # AWS スタック
    └── prod/
        ├── my-app/
        └── ec-auth/

設計原則

原則説明
単一責任各モジュールは 1 つの責務のみ
環境差分は変数でコードの重複を排除
State はスタック単位envs/prod/my-app ごとに 1 つの State

モジュールに環境固有の値をハードコードしてはいけません。すべて変数で渡すのが原則です。

🚫 やってはいけないこと

禁止事項理由
CLI で直接リソース作成State と実態が不一致になる
ローカルから本番に直接 apply事故のリスク、CI/CD を通すこと
State ファイルをコミット機密情報が含まれる
サービスアカウントキーの利用漏洩リスク、WIF を使う
本番環境で terraform destroy多層防御で禁止すべき

特に CLI で直接リソースを作ると、State との不整合(State drift) が発生します。Terraform で管理すると決めたら、すべて Terraform 経由で変更してください。

📚 シリーズ記事

#タイトル内容
1概要IaC の全体像と基本方針
2準備編(本記事)アカウント設計・認証・権限・State 管理
3モジュール設計編(公開予定)再利用可能なモジュールの設計原則
4CI/CD パイプライン編(公開予定)GitLab CI/CD による自動化・WIF 認証フロー
5運用編(公開予定)State drift 解消・トラブルシューティング