注意:実際にデモを実施したのは 8 月ごろですので、この記事の情報は古くなっている可能性があります。あらかじめご了承いただければと思います。
はじめに
商用 LLM 全盛期の時代ですね。多くの人は AI エージェントの有用性を実感し爆速で仕事を進めていると思います。
一方で、世の中には AI エージェントの活用が個人開発やサンドボックス環境にとどまり、業務への本格導入にはまだ至っていない企業も少なくないのではないでしょうか。
新技術に積極的な組織であればともかく、一般的な企業にとっては、このような新しい概念に踏み込む際、具体的なイメージが湧きにくく、「本当に業務改善につながるのか」という点で判断に迷うことが多いように思います。納得感のある意思決定につなげるためには、コスト面などのメタ情報だけでなく、実務の中でどのように組み込まれるのかを示し、デモを通じて AI エージェントと協働する体験を共有することが重要だと感じています。
そこで今回は、terraform(terragrunt)を題材に、先方に向けて Claude Code のデモを行う機会をいただいたため、その内容を共有しようと思います。
50 人以上の観衆の前での発表となり、自分史上前代未聞の経験ではありましたが、terraform で既存リソースを import するタスクを題材にすることで、限られた時間の中でも機能を網羅的に紹介することができました。その結果、先方にも十分に納得していただき、導入の意思決定につなげることができたと感じています。
前提情報
飛ばせる人は飛ばして読んでください。
IaC
ご存知の方多いと思いますが、本題に入る前に軽く IaC の概念の説明をします。
IaC(Infrastructure as Code)は、インフラ構成をコードとして定義・管理する手法であり、terraform はその代表的な実装手段の一つです。
サーバやデータベース、ネットワーク、権限設定といった各種リソースをコードとして記述・管理することで、主に次のようなメリットが得られます。
- 再現性:同じコードを使えば、同じ環境を何度でも構築可能
- 可視化:設定内容がコードとしてレビュー・バージョン管理できる
- 自動化:CI/CD パイプラインやツールと組み合わせて構築を自動化できる
この中でも AI エージェントとの相性がいいのは「可視化」ですね。生成 AI のコミュニケーション媒体は文字列が主なので、コードとして設定が全て記述されている IaC は生成 AI にとって扱いやすい形式です。
また、IaC 自体が運用面で大きなメリットを持っているため、その点も含めて導入時の説得材料にできます。仮に開発やサポートが終了したとしても、先方が生成 AI を通じて一定レベルの QA を行えるという点は、生成 AI の今後の成長を見据えた投資としても、十分に訴求力のあるポイントになるのではないかと思います。
Terraform Import
すでに手動で作成されたリソースをコード管理に取り込む際に利用するのが Terraform の import 機能です。
Terraform (v1.5 以上) では、以下のように import block を書くことでインポート対象を HCL 内に明示的に記述できます。
# 例として EC2 のインスタンスの設定情報を記載
resource "aws_instance" "example" {
...
}
import {
to = aws_instance.example
id = "i-xxxxxxxxxxxxxxxxx"
}
この二つのブロックを Claude Code に記述させるのが今回のデモのタスクです。
今回の現場ではすでに terraform が導入されている状況だったので新規性という面では大きくはないです。
ただ「既存リソースを IaC に取り込む」というタスクは、どのような現場においても着手しやすい、実務に直結した内容だと思います。
Snowflake
今回は Snowflake の各リソースを import するタスクを与えます。
Snowflake はクラウドネイティブなデータウェアハウスの SaaS であり、権限設定とコンピュート・ストレージ分離が特徴的な次世代のデータベースです。以下のような特徴があります。
- SQL ベースの操作性
- 従来の DWH と同様に標準 SQL で操作可能。加えて snowflake 独自の拡張で undrop 等の機能を利用可能。
- コンピュートとストレージの分離
- 必要に応じて計算リソースを水平・垂直拡張することができ、計算効率を最適化できる。
- 柔軟な権限設定
- ロールを設計することで、ユーザごとに可能な権限を細かく設定できる。あるユーザからは読み取り専用にしたり存在を秘匿するなど必要最小限のアクセス権限を付与できる。
Snowflake への SQL 発行は Snow CLI を通してコマンドラインで行います。Claude Code にはこの Snow CLI を通じてどのようなリソースがあるのか探索してもらいます。
デモ概要
今回は Claude Code に以下のようなお願いをしてみました。
- 事前に手動で snowflake に SQL を発行して多様なリソースを作成しておく。この情報は Claude Code には秘匿する。
- Claude Code は snow CLI を探索ツールとして利用して、
showやdescコマンドからアカウント内のオブジェクトの情報を知る。- Claude Code が試行錯誤する様子を共有しながら解説を行う。
- Claude Code は resource block と import block を含んだファイルの作成を行い、terraform plan で問題なく動くことを確認する。
ディレクトリ構造
今回のデモプロジェクトのレポジトリの構造はこんな感じです。
- .claude
- settings.json
- terraform-import
- DO_NOT_READ_FILE_HERE_OR_YOU_WILL_BE_FIRED/
- create_resources.sql
- infra/
- live/
- dev/
- database/
- terragrunt.hcl
- schemas/
- schema_objects/
- governance/
- modules/
- database/
- database.tf
- variables.tf
- output.tf
- schemas/
- schema_objects/
- governance/
- CLAUDE.md # デモ特有の内容を記した方法
- CLAUDE.md # 普遍的な開発方針
Terragrunt では、上述したリソースの tf ファイルを modules 内に、開発環境や商用環境によって変化するパラメータを live 内に記載することが推奨されているので、それに従って構成しました。
Snowsight で作成した各種リソースの DDL は create_resources.sql にバックアップしており、こちらの内容と比較してどのリソースが IaC 配下に導入されたかを確認します。
ちなみに、この SQL を含む DO_NOT_... ディレクトリに関しては claude/settings.json において Claude Code が読めないように設計しています。
CLAUDE.md は二つ用意しており、片方はプロジェクトレベル、もう片方は一般的な開発方針として記述しています。
CLAUDE.md の実装(プロジェクト方針)
では具体的にどのように Claude Code の挙動を設計したのか、CLAUDE.md の内容を紹介します。
ここでは重要なポイントに絞り、デモを実施した時の内容より簡略化しています。
# CLAUDE.md
本サブプロジェクトでは、Claude Code を利用して snowflake のリソースを独自でインポートし、terragrunt 管理下に置かせるデモを行う。
## Goal
Claude Code は環境変数 `$SNOWFLAKE_DATABASE` に示される DB 配下のリソースを網羅的に探索し、`/workspace/terraform-import/infra` 配下の tf ファイル群で管理できるよう resource 定義と import block の記載を行う。
最終的に全項目で plan を実施して、エラーが発生しない状態にする。
## Condition
Claude Code の挙動及び生成結果は以下を満たさなければならない。
以下の事項に違反せざるを得ない場合はユーザに許可を依頼すること。
- Claude Code は snow cli を利用して SQL 文を発行する。
- import 時に、実際のリソースを ALTER / update / replace することはあってはならない。
- 実装方針メモ等一時ファイルは他のサブプロジェクトと重ならないように、`claude_work/terraform-import` 内に記載する。
- `DO_NOT_READ_FILES_HERE_OR_YOU_WILL_BE_FIRED` ディレクトリ配下のファイル群はデモの回答になるので読み込みは禁止される。
Claude Code には Snowflake との接続手段として Snow CLI のみを与え、あくまで読み取り専用で利用することを前提としています。
また、Claude Code 自体の素の能力を評価したかったため、プロジェクト固有の情報は極力与えず、デモを成立させるために必要最小限の条件だけをコンテキストとして注入しています。
なお、terraform apply は判断を伴う作業であるため人間が行うものとし、Claude Code には terraform plan までを担当させる構成としました。
CLAUDE.md の実装(開発方針)
# CLAUDE.md
このファイルは、このリポジトリでClaude Codeが作業する際のガイダンスを提供します。
## Conversation Guidelines
- ユーザとの対話時は常に日本語で会話する
- 思考時は英語を利用して良い
- デモをお見せする ◯◯ さまに言及する際は必ず敬称をつけること
## Development Philosophy
### General Behavior
- 設定に異常があると推察される場合はユーザに編集して良いか尋ねる。設定を変更するのではなく、基本的にコードの記載方法で解決できると考える
- 設計に関しては、すぐに実装に入るのではなく綿密に検討して(ultrathink)から実装に着手する
- 外部のリファレンスを参照する際は、極力公式のドキュメントを一次情報として参照する。以下にドキュメントのリンクを掲載。
- terraform: Terraform MCP を利用すること。以下に例を記載するが、実際に利用する際は version の指定も怠らないように。
- aws: `namespace="aws", resource="instance"`
- snowflake: `namespace="snowflakedb", provider="snowflake", resource="database"`
- リソース名`snowflake_database`では検索エラーが出ることに注意
- `snowflake-labs`ではなく`snowflakedb`が公式であることに注意
- snowflake: https://docs.snowflake.com
- 利用する技術の流行り廃りが激しいので、リソースを定義したり新たなモジュールを利用するときは、必ずバージョンを確認後に一次情報を取得すること。怠ると泥沼になります。
- ファイル構成を意識し、作成しようとするファイルの類似ファイルが見つかった時は、そのファイルと依存ファイルを全て読み込むこと。
### Temporary Output Workspace
**/workspace/claude_workディレクトリがあなたの一時的な作業出力を行う場所です。実装を除いた開発計画などのマークダウンファイルはここに生成すること**
一般論である開発方針に関しては、説明を多めに入れています。
ユーザとの対話に関しては日本語を指定し、思考に関しては英語や中国語等、言語に縛られず推論するように明示しています。
一般的に英語や中国語は日本語よりデータが多く、また per トークンに対する情報量が多い言語であるため推論効率が良いという性質があります。1
Ultrathink を明示的に導入し、Claude Code の ultrathink 機能を紹介しています。
Claude Code は指示を与えると先走りで実装に取り掛かろうとする傾向があり、生成される結果の質が下がることがしばしばあります。そこでまず設計方針について十分に熟考させることで、最終的な生成物の品質が大きく向上するというベストプラクティスを合わせて紹介していました。
外部のレファレンスよりも公式のドキュメントが情報として正確であり、整備もされているという背景から、優先的に公式ドキュメントを参照させようとしています。
基本的にサードパーティのドキュメントは前提知識が少ない人間向けで、内容も古くなりがちで使えないことも(特に terraform provider に関しては)多いため、不要な試行錯誤を繰り返して時間・費用・コンテキストを消耗してしまいます。
LLM なら広い知識を事前分布に溜め込んでいるため、難解で情報量が多い文章でも重要な部分を正確に抜き出して解釈できるので、公式ドキュメントを投げて任せるのが一番効果的です。
また、外部のレファレンスよりも公式ドキュメントのほうが情報として正確かつ整備されているという前提から、参照先はできる限り公式ドキュメントを優先するようにしています。サードパーティの記事は前提知識が少ない人向けに書かれていることが多く、内容が古くなりがちです。特に Terraform provider 周りではその傾向が顕著で、結果として不要な試行錯誤を繰り返し、時間・コスト・コンテキストを消耗してしまうケースが少なくないです。
LLM は広範な知識を事前分布として持っているため、情報量が多く難解な文章であっても、重要なポイントを正確に抽出して解釈できます。そのため、公式ドキュメントをそのまま渡して任せるのが一番効果的と考えています。
Terraform に関しては鮮度が命なので HashiCorp Terraform MCP を利用して AWS や snowflake の provider の情報を取得するように命令しています。公式ドキュメントは Web 検索経由では正しく取得できないことも多いため、MCP を通じて利用方法や仕様を引き出すほうが合理的です。実際、MCP を使うかどうかで、生成結果の精度には大きな差が出ます。
MCP を導入したので、MCP の説明もできますね。自分の場合は Claude Code に MCP を意図的に叩かせ、各コマンドの入力と出力をカタログ化した説明資料を作ってもらうというネタを仕込みました。
このように AI エージェント協働開発で重要な概念をひとさらいできるため、Terraform はデモ題材として非常に相性が良いと感じています。
失敗部分を意図的に見せる
Claude Code が生成したコードが必ずしも正常に動くとは限らないことは皆さん百も承知だと思います。
成功する場所だけ見せても説得力が薄いので、むしろ「どのような状況で弱点が出るのか」を明確に示せているかどうかが重要だと考えています。
今回のケースでは、指示の曖昧さが原因となり、import 漏れが発生することが事前検証の段階で頻発していました。
テーブルやビューなどの基本的なオブジェクトに関してはクリアしていましたが、マイナーなオブジェクト、例えばタグやマスキングポリシー等への考慮は抜け落ちる傾向がありました。
単に「リソースを探してインポートしろと」いう指示だけでは目標達成が難しいことをあえて再現し、追加の指示を与えて目の前で修正させるという過程を見せることによって、開発者が日常的に生成 AI エージェントをどう扱うのか、その手触り感を伝えられたのではないかと思います。
もっとも、デモには時間的な制約があるため、コンテキストに含めるコード量など、性能低下につながる他の要因については、質疑応答の中で補足説明を行いました。
LLM は確率的な生成モデルである以上、生成 AI のデモがどこかで失敗するのは避けられません。しかし問題なのは失敗そのものではなく、「どのような条件で失敗しやすいのか」という傾向を把握できているかどうかです。そこまで共有できていれば、先方も納得感を持って導入を検討できるようになるのではないかと感じています。
おわりに
自分自身、昨年度大学院で roo-cline を利用していたため、AI エージェントそのものに強い抵抗があったわけではありません。とはいえ、業務に入ってから数ヶ月ほど触れない期間を経たあとに初めて Claude Code に触れた際には、以前のツールとは自律性の面であまりにも大きな違いがあり、驚きと同時に一抹の不安を覚えました。
一方で、生成品質の高さやタスク消化のスピードも格段に向上しており、業務に組み込むかどうかで生産性に極端な差が生まれる、という確信に至っています。
Claude Code は間違いなく生産性向上に寄与しますが、その反面、負担に感じる部分が出てくるのも事実です。
他社に勤める友人の話では、従量課金方式が現場での Sonnet 利用に対するプレッシャーを生んでいることや、Claude.md の設定が不適切なまま運用されることで、いきなり実装に入って既存コードに沿わない実装が生成されてしまうケースがあるとのことでした。さらに、変更量が増えすぎた結果、レビュー体制が飽和攻撃を受け、怪しいコードがそのまま通ってしまう場面も出てきているようです。
全体としてはポジティブな流れである一方で、こうした「どこが開発者にとって辛くなりうるのか」を明確にしていくことも、同じくらい重要だと感じましたね。