はじめに
株式会社AJA でバックエンドエンジニアをしている片山です。
Infrastructure as Code (IaC) の運用において、Terraform は広く使われていますが、その運用方法は組織によって様々です。私たちのチームでは、当初 Dev Container 上で Terraform を実行していましたが、運用上の課題を抱えていました。また、module を積極的に活用していたことで、管理コストの増加にも悩まされていました。
この記事では、Dev Container での Terraform 運用から Atlantis へ移行した経緯と、module 戦略の見直しによって得られた恩恵を紹介します。
想定読者:
- Terraform をローカルまたは Dev Container で運用している方
- IaC の運用課題(誰が何を変更したか分からない、オペレーションが属人化など)を抱えているチーム
- module の管理コストに課題を感じているチーム
この記事で得られること:
- Dev Container 運用の課題とその解決アプローチ
- Atlantis を使ったプルリクエスト(PR)ベースの Terraform 運用の実例
- module 化を最小限に抑える方針とそのメリット
Dev Container 運用での課題
まず、Dev Container で Terraform を運用していた際に抱えていた課題を整理します。
① いつ、誰が修正したか分からない
ローカル実行では、GitHub の PR やコメントに実行履歴が残りません。そのため、いつ誰がどのような変更を加えたのか追跡が困難で、オペレーションが暗黙知になりがちでした。
② ローカル実行は事前の plan と差分が生まれやすい
Dev Container での実行は、事前にレビューした plan 結果と、実際の apply 時の結果に差分が生まれるリスクがあります。
③ 破壊的な変更への対応が属人化
tfstate が一致していない状態で破壊的な変更が生まれると、一致させる作業が必要になります。しかし、旧オペレーションを知っている人しか対応できず、これもまたチーム全体でのリードタイムを増加させていました。
Atlantis とは
これらの課題を解決するために、Atlantis の導入を決めました。Atlantis は、PR ベースで Terraform 運用を自動化するツールです。CNCF Sandbox プロジェクトとして開発が進められており、エンタープライズでの採用実績も豊富です。
主な機能:
- GitHubコメントで Terraform 操作:PR にコメントするだけで
terraform planやterraform applyを実行 - plan/apply 結果の可視化:実行結果がすべて GitHub のコメントに記録されるため、レビュー可能
- 同一ディレクトリ実行の禁止:ロック機構があるため、同一環境を同時に変更してしまうリスクがない
- 未 approve の場合 apply を禁止:承認フローを組み込める(生成 AI による自動化のガードレールとしても働く)
など、多くの機能が提供されています。
実行環境の選定
Atlantis の導入にあたり、まず実行環境を検討しました。GKE と Cloud Run の 2 つの選択肢を検討しましたが、以下の理由で最終的に GKE を選択しました。
Cloud Run を選択しなかった理由:
- Cloud Run はステートレスなコンテナ環境のため、Atlantis のロック情報を永続化するには外部ストレージの追加構成が必要
- チームとして Cloud Run の運用経験が少ないため、導入・運用の負荷が高くなる
GKE を選択した理由:
- PersistentVolume を使用でき、Atlantis のデフォルト構成をそのまま利用可能
- チームに GKE の運用経験があり、トラブルシューティングがしやすい
アーキテクチャ
GKE にデプロイされた Atlantis のアーキテクチャは以下のようになります。

コンポーネント:
- Atlantis Server:GitHub からの Webhook を受け取り、Terraform コマンドを実行
- Google Cloud Resource:Terraform で管理するリソース群
各経路の認証方式は以下のとおりです。
| 経路 | 認証方式 |
|---|---|
| GitHub → Atlantis(Webhook) | Webhook Secret の HMAC 認証 |
| Atlantis → Google Cloud(plan/apply) | Workload Identity |
| Atlantis → GitHub(コメント) | GitHub App の Installation Access Token |
この設計により、永続的な権限を払い出すことがなく、セキュリティリスクを最小化しています。
アクセス制御
Atlantis は Terraform を実行するため、Google Cloud リソースを変更できる強い権限を持ちます。そのため、アクセス制御は慎重に設計しなければなりません。
一方で、Atlantis は GitHub からの Webhook を受け取るため、エンドポイントをインターネットに公開する必要があります。しかし、そのままでは Atlantis UI も外部からアクセス可能になってしまいます。Identity-Aware Proxy を使うと GitHub の Webhook が通らなくなるため、Cloud Armor で IP ベースのアクセス制御を実装しました。
許可する IP:
- GitHub Webhook の送信元 IP(GitHub Meta API で取得可能)
- 社内ネットワークの IP
これにより、Webhook の受信を維持しつつ、UI へのアクセス制限を可能にしました。
リポジトリ構成と module 戦略
ここまで Atlantis のインフラ設計について説明しました。次に、Terraform コード自体の管理方針について紹介します。
リポジトリ構成
Atlantis の導入に合わせて、リポジトリ構成と module 戦略も見直しました。これまではアプリケーションコードと同じモノレポで Terraform を管理していましたが、以下の理由から独立したリポジトリに切り出しました。
- インフラとアプリケーションの変更サイクルが異なる
- マージルールやレビュー体制を分けられる
ディレクトリ構成は以下のとおりです。
├── modules # 共通module
│ ├── CLOUD_SERVICE # Cloud Service ごとにディレクトリを区別
│ │ ├── MODULE_NAME # サービス側の利用を想定したmodule
: : :
│
├── platform # 基盤システムのリソース
│ ├── CLOUD_SERVICE # Cloud Service ごとにディレクトリを区別
│ │ ├── SYSTEM_NAME # システム名
│ │ │ ├── ENVIRONMENT # 動作環境名
: : :
│
├── services # 各チームが管理するサービスのリソース
│ ├── CLOUD_SERVICE # Cloud Service ごとにディレクトリを区別
│ │ ├── SERVICE_NAME # サービス名
│ │ │ ├── ENVIRONMENT # 動作環境名
Terraform のディレクトリ分割には唯一の正解がないため、チームで議論しながら決めました。また、生成 AI にも伝わりやすい明確なルールにしておくとコード生成時にも役立ちます。
module 化の方針
リポジトリ移行前は module を積極的に活用していましたが、運用を続ける中で課題が見えてきました。
- 認知負荷の増加
- provider と異なる独自仕様にドキュメントが追いつかない
- どんな module があるか暗黙知になりやすい
- バージョン管理の複雑化
- provider のアップデートに追従しようとすると影響範囲が甚大
- 同一機能の複数バージョンが混在し、どれを使うべきか不明確
- 設計の問題
- 異なるユースケースを 1 つの module に押し込めた結果、例外対応のためのフラグが増殖
- 過度に細分化すると module 化のメリットが薄れる
これらを踏まえ「module の利用は最小限に留め、provider のリソースを直接利用する」という方針に切り替えました。結果として、公式ドキュメントベースで開発できるようになり、生成 AI との相性も良くなりました。
Atlantis での Plan / Apply フロー
ここからは開発時の操作フローを説明します。

Plan は、PR を作成する(もしくは plan とコメントする)と自動で terraform plan が実行され、結果が PR にコメントされます。レビュアーはこのコメントを見て変更内容を確認できます。
Apply は、レビュー完了後に atlantis apply とコメントすることで実行されます。apply の結果も PR にコメントされるため、誰がいつ適用したかが記録に残ります。
実際の PR では以下ように表示されます。

移行してみた結果
Atlantis 導入、module 化を最小限にしたことによって、実際に感じた恩恵は以下です。
- PR に操作が記録される
- すべての操作履歴が GitHub に残るため、振り返りが容易
- 過去の操作を生成 AI に few-shot prompting として渡せる
- いつ誰が何を変更したかが明確
- tfstate の不整合の調整も GitHub 上に残る
- 直前の plan が必ずコメントに残るため意図しない変更を防げる
- レビュー時に plan 結果を確認可能
- apply 前の最終確認が容易
- module の管理コストが下がった
- 新しいリソースは公式ドキュメントを見れば分かる
- 生成 AI を活用した実装もスムーズ
- バージョン更新の影響範囲が限定的
まとめ
Atlantis 導入と module 戦略の見直しにより、Terraform 運用の属人化を脱却させることができました。module 化を最小限に抑えるという判断は、保守性と学習コストのバランスを取る上で重要なポイントでした。公式 provider の仕様に沿った実装により、新規メンバーでも理解しやすく、生成 AI の活用もしやすい環境を実現できています。
Terraform や IaC の運用に課題を感じている方は、ぜひ Atlantis の導入を検討してみてください。
また、今回は jun06t さんにご協力いただき、Terraform 運用の改善を行いました。設計から実装まで多くの議論を重ね、より良い運用体制を構築できました。この場を借りて改めて感謝いたします。
