Terraform と CI/CD の統合
Terraform によるインフラ管理と CI/CD によるアプリケーションデプロイの責任範囲を明確にするものです。
設計方針
Terraform の責任範囲
Terraform は初期環境構築のみを担当し、以下のリソースを管理します:リソースグループ、Virtual Network / サブネット、Container App Environment、Container App(リソース自体の作成)、Database(MySQL Flexible Server)、Storage Account(File Share / Blob Container)、User Assigned Identity、カスタムドメイン設定
CI/CD の責任範囲
CI/CD パイプラインはアプリケーションデプロイを担当し、以下を管理します:Docker イメージとタグ(template.container.image)、環境変数(template.container.env)、Revision 管理(新しいリビジョンのデプロイとトラフィック制御)
Terraform のignore_changes設定
目的
CI/CD がデプロイした内容を Terraform が上書きしないようにするため、Container App リソースにignore_changesを設定しています。
実装
以下の項目が Terraform の差分検出から除外されています:Docker イメージとタグ(template[0].container[0].image)、環境変数(template[0].container[0].env)
対象テンプレート
- Frontend-Backend Template: Frontend Container App、Backend Container App
- Monolith Template: Frontend Container App(Monolith 構成)
ワークフロー
1. 初期環境構築(Terraform)
infra generate <tenant> <env> --non-interactive
infra plan <tenant> <env>
infra apply <tenant> <env> --auto-approve
この時点で、Container App はデフォルトのイメージとタグで作成されます。
2. アプリケーションデプロイ(CI/CD)
CI/CD パイプラインは以下を実行します:Docker イメージのビルドとプッシュ(ACR へ) → Azure CLI を使用して Container App を更新(イメージと環境変数を設定)
3. インフラ変更(Terraform)
インフラリソース(CPU/メモリ、レプリカ数、ネットワーク設定など)を変更する場合のみ Terraform を使用します:terraform.tfvarsを更新 → infra plan(image と env は差分に表示されない) → infra apply
# 差分確認(imageとenvは差分に表示されない)
infra plan <tenant> <env>
# 適用(--auto-approve または --yes を使用可能)
infra apply <tenant> <env> --auto-approve
責任範囲の詳細
Terraform が管理する項目
| 項目 | 説明 |
|---|---|
| Container App リソース | リソースの存在自体 |
| CPU/メモリ | 割り当て設定 |
| レプリカ数 | 最小/最大レプリカ数 |
| ネットワーク設定 | ingress、IP 制限 |
| Volume 設定 | File Share のマウント |
| Identity 設定 | Managed Identity |
| その他インフラ設定 | - |
CI/CD が管理する項目
| 項目 | 説明 |
|---|---|
| Docker イメージ | イメージ名とタグ |
| 環境変数 | 実行時の設定 |
| Revision 管理 | デプロイとトラフィック制御 |
注意事項
Terraform 実行時の動作
terraform plan実行時、ignore_changesで指定された項目は差分として表示されません- CI/CD で変更されたイメージタグや環境変数は、Terraform 実行後も維持されます
- インフラ変更(CPU/メモリなど)を適用してもアプリケーションの設定は上書きされません
環境変数の管理
Terraform で定義された環境変数は初期値として設定されますが、以降は CI/CD で管理されます。
推奨アプローチ:
- インフラ関連の環境変数(DB 接続情報など): Terraform で管理
- アプリケーション設定の環境変数: CI/CD で管理
実際には、CI/CD が全ての環境変数を上書きする運用を推奨します。
詳細は 環境変数ガイド を参照してください。
Revision URL
Container App の各リビジョンには固有の URL が割り当てられますが、これらはignore_changesで無視されるため、Terraform の状態ファイルと実際の Azure 上のリソースで差異が生じることがあります。これは正常な動作です。
トラブルシューティング
Q: Terraform で環境変数を変更したいが、ignore_changes で無視される
回答: 一時的にignore_changesから env を削除し、適用後に再度追加してください。ただし、CI/CD で管理している環境変数が上書きされる可能性があるため注意が必要です。
推奨: CI/CD で環境変数を管理してください。
Q: CI/CD でデプロイしたイメージが、Terraform 実行後に元に戻った
回答: ignore_changesが正しく設定されているか確認してください。また、Terraform のバージョンによっては動作が異なる場合があります。
確認方法:
# テンプレートのバージョンを確認
cat terraform/modules/applications/*/v*/main.tf | grep -A 10 "lifecycle"
Q: 新しい環境変数を追加したい
回答: CI/CD パイプラインで環境変数を追加してください。Terraform の variables 定義を変更する必要はありません。
手順:
- アプリケーションリポジトリの
.env.<environment>を編集 infra env encryptで暗号化- Git にコミット
- GitHub Actions でデプロイ
詳細は 環境変数の管理 を参照してください。
Q: terraform plan で差分が表示される
回答: Terraform の状態ファイルをリフレッシュしてください:
infra refresh <tenant> <env>
それでも解決しない場合は、ignore_changesの設定を確認してください。
メリット
1. ドリフトの防止
Terraform 実行時に CI/CD で設定した値が上書きされることがありません。
2. デプロイの高速化
アプリケーションのデプロイに Terraform が不要になり、CI/CD だけで完結します。
3. 責任範囲の明確化
技術的な仕組みによって、インフラチームとアプリ開発チームの責任範囲が保証されます。
4. 柔軟性の向上
インフラの変更とアプリケーションの変更を独立して実行できます。
検証方法
1. ignore_changes の動作確認
# terraform planを実行
infra plan <tenant> <env>
# 期待結果: Container Appのimageとenvに差分が表示されない
2. CI/CD デプロイ後の確認
# CI/CDでイメージを更新
az containerapp update \
--name <container-app-name> \
--resource-group <resource-group> \
--image <new-image>:${TAG}
# 再度terraform planを実行
infra plan <tenant> <env>
# 期待結果: 差分が表示されない
3. 実際のリソース確認
# Container Appの現在のイメージを確認
az containerapp show \
--name <container-app-name> \
--resource-group <resource-group> \
--query "properties.template.containers[0].image"
# 環境変数を確認
az containerapp show \
--name <container-app-name> \
--resource-group <resource-group> \
--query "properties.template.containers[0].env"
マイグレーション手順
既存のテナントに対してこの設定を適用する手順:
ステップ 1: コードの更新
# 最新のコードをpull
git pull origin main
ステップ 2: terraform plan で確認
# 差分を確認(imageとenvは表示されないはず)
infra plan <tenant> <env>
ステップ 3: terraform apply で適用
# lifecycleブロックの変更を適用(--auto-approve または --yes を使用可能)
infra apply <tenant> <env> --auto-approve
ステップ 4: 動作確認
# CI/CDでデプロイ
# その後、再度planを実行して差分がないことを確認
infra plan <tenant> <env>
関連ドキュメント
- Frontend-Backend Template - フロントエンド/バックエンド分離構成
- Monolith Template - モノリシック構成
- テンプレート概要 - テンプレートの選び方
- 役割分担とワークフロー - チーム間の責任範囲
- 環境変数ガイド - 環境変数の管理方法
- Terraform Lifecycle Meta-Argument - 公式ドキュメント