TerraformでAWSインフラをAIと構築する際のノウハウ
WiseVineのSREエンジニアの高見です。TerraformでのAWSインフラ管理(IaC)は、弊社のインフラ管理でも中核を担っています。AIのコーディングがここ1年程度で飛躍的に進んだ昨今、インフラ管理もAIでのコーディングが主流になりつつあります。
しかし、AIは「万能のインフラエンジニア」ではなく、現時点では「文脈を読めない、意欲だけはある見習いアシスタント」に近い側面があります。指示が曖昧だと、彼らは良かれと思って「暴走」し、かえって事態を複雑にします。
本記事では、Terraform環境下でAIと協調してAWSインフラを構築する際に、AIの「暴走」を防ぎ、Terraformが持つ本来の強みを活かすための、実践的なノウハウと「AIへの指示書(ルール)」について解説します。
前提とするファイル構成
本記事で想定するTerraformの構成は、一般的でシンプルなものです。
-
terraform/modules/:再利用可能なリソース定義(VPC、ECS、RDSなど)を格納します。 -
terraform/envs/:環境(dev, stg, prdなど)固有の変数を定義し、modulesを呼び出します。
terraform/
├── modules/
│ ├── vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── ...
└── envs/
├── dev/
│ ├── main.tf
│ ├── terraform.tfvars
│ └── backend.tf
└── prd/
└── ...
ルール無しでAI任せで発生した「困ったこと」
-
自己中心的な実装:
- すでにリポジトリ内外に高品質な モジュールがあるにも関わらず、無視してゼロから
aws_vpc等のリソースを書き始めます。 -
envs/dev/main.tf内に、モジュール化すべきネットワークやセキュリティグループのロジックをすべて書き出そうとします。
- すでにリポジトリ内外に高品質な モジュールがあるにも関わらず、無視してゼロから
-
勝手な憶測:
- 「CIDRブロックはどうしますか?」と聞くべきところを、勝手に
10.0.0.0/16のような一般的な値を補完して実装を進めてしまいます。
- 「CIDRブロックはどうしますか?」と聞くべきところを、勝手に
-
品質・セキュリティ意識の欠如:
- 「Terraform RegistryのVPCモジュールを使って」と指示しても、なぜか数年前の古いバージョン(
version = "2.0.0"など)を参照しようとします。 - コメントを丁寧(過剰)に書きすぎて、コードの可読性を著しく低下させ、メンテナンスを困難にします。
- 「Terraform RegistryのVPCモジュールを使って」と指示しても、なぜか数年前の古いバージョン(
-
コミュニケーションとプロセスの無視:
- 「出来ました」とだけ報告し、何がどのように変更されたのかを明示せずにコミットしようとします。
- ローカルでの
terraform fmtやtflintを怠り、pre-commitフックで大量のエラーが検出されます。 - 最悪の場合、「計画が悪い」と判断したのか、人間の確認を待たずに
terraform applyを実行しようとすることさえありました。
これらの問題は、AIがプロジェクト全体の文脈、チームのルール、そして自身の役割を理解していないために発生します。
今回私が追加したルール
これらの問題を解決するため、AIに対して明確なルールセットを定義しました。これを.cursor/rules/infra.mdcやAGENT.mdやCLAUDE.mdあたりに記載することで、AIの行動を大幅に制御できます。
1. 実装前(計画フェーズ)
AIがコードを書き始める前に、まず「考える」ことを徹底させます。
- リポジトリ内の既存モジュールを最優先でチェックすること。
- 再利用可能なモジュールが無い場合のみ、公式のモジュールを確認し、利用すること
- 等、いくつかリストアップしておくと良いでしょう
- 個人開発の出自が不明瞭なモジュールは、いかなる理由があっても利用しないこと。
- 実装に必要な情報(例:CIDR、インスタンスタイプ、環境名)が不足している場合、勝手に補完せず、ユーザーに確認すべき質問をリストアップして提示すること。
2. 実装フェーズ
Terraformのベストプラクティスとプロジェクトの規律を守らせます。
-
モジュールと環境の責務分離:
- リソースの定義は、原則として
terraform/modules/内で行うこと。 -
terraform/envs/側では、可能な限りモジュールの参照のみとし、環境固有の値を渡すだけにすること。
- リソースの定義は、原則として
-
共通化の徹底:
- 環境共通の項目(例:デフォルトのタグ、命名規則)は可能な限りモジュール側に寄せ、
variables.tfのdefault値を活用すること。
- 環境共通の項目(例:デフォルトのタグ、命名規則)は可能な限りモジュール側に寄せ、
-
バージョン管理:
- 外部モジュールを利用する際は、最新の安定バージョンを利用すること。
- (作法による補足:可能であれば、
sourceのrefパラメータで特定のGit SHAを指定し、依存関係を固定化せよ。)
-
コードの可読性と保守性:
-
ignore_changesやcreate_before_destroyなどのlifecycleブロックを利用する際は、その理由を必ずコメントで明記すること。 -
depends_onの乱用を禁止する。リソース間の参照(aws_instance.foo.idなど)による暗黙的な依存関係を優先し、どうしても必要な箇所(明示的な依存関係)のみ利用すること。
-
-
メンテナンス性の確保:
- ソースコード内のコメントやモジュールの
README.mdに、バージョン情報や進捗状況などの頻繁なメンテナンスが必要となる情報(時と共に古くなる情報)は記載しないこと。
- ソースコード内のコメントやモジュールの
-
セキュリティと安全停止:
- 機密情報(AWSアクセスキー、APIキー、パスワードなど)を取得し、それをコード内に出力したと自己判断した場合は、即座に作業を中止し、ユーザーに判断を求めること。
3. 実装後(レビューフェーズ)
AIが「仕事をした」と主張する前に、品質保証のステップを踏ませます。ここがTerraformのワークフローに繋がる重要なポイントです。
-
ローカルでの品質チェック:
- コード生成後、必ず
terraform fmtを実行し、フォーマットを統一すること。 -
terraform validateを実行し、構文エラーがないことを確認すること。 -
tflintを実行し、ベストプラクティス違反がないかチェックすること。 - (推奨)
checkov,trivy,KICS,terrascanなどのセキュリティスキャンツールをローカルで実行し、脆弱性がないか確認すること。- これらはpre-commitフックに組み込むことも有効ですが、事前に実行することで、より早期に問題を検出できます。
- コード生成後、必ず
-
人間によるレビューの要求:
- 上記すべてのLinterおよびセキュリティチェックが通った後に、
terraform planを実行し、リソースの変更計画(plan)が適切であることを確認せよ。 - 一連のチェックがすべて完了したら、以下の情報を箇条書きにしてユーザーに報告し、次の指示(コミットや修正依頼)を待つこと
- 修正(実装)したポイントの概要
-
terraform planの概要 - 特筆すべき重要項目(例:DBの削除が含まれます、など)
- 上記すべてのLinterおよびセキュリティチェックが通った後に、
-
最重要ルール:
- AI自身による
terraform applyの実行は、いかなる状況でも固く禁止する。
- AI自身による
🤖 AIとTerraformを連携させる際の「勘所」
上記のルールを定義しても、AIの特性上、注意すべき点がいくつかあります。
-
AIの「記憶圧縮」を忘れない
セッションが長くなると(多くのやり取りを行うと)、AIはメモリ(コンテキスト)を圧縮し、初期に設定した重要なルールを「忘れる」ことがあります。ルールを忘れたような挙動を見せた場合は、再度ルールを提示するか、セッションを分けて(新しいチャットで)作業を依頼する必要があります。 -
「計画」と「進捗管理」を分離する
AIに「計画」(どのモジュールをどう修正するかの概要)を出力させ、その計画自体を人間がレビューすることが重要です。また、その計画と進捗を別途(テキストファイルや別の管理ツール)に記録させ、必要に応じて別のAIセッションに「引き継ぎ資料」として渡す手法も有効です。 -
AIの役割を明確にする
AIの役割は、あくまで「品質の高いTerraformコードを生成し、ローカルチェックを通過させる」、せいぜい「プルリクエストを作成する」ところまでです。人の目での確認とレビューの指摘は必須になります。
まとめ
こんな具合にルールを追加することで、いくらかAIは賢くインフラコードを書いてくれるようになります。逆にルールを記載せずに「VPCの設定をして」というと、再利用性やメンテナンス性の悪いコードが大量に出来上がります。まだまだAIは完璧ではなく、インフラ構築においても、適切にルールを伝え、最終的には人の目で見ることが重要になります。
Discussion