
Claude Codeで「あとからIaC」— 既存AWSリソースをCloudFormationにimportする実践ガイド
はじめに
AWSを使っていると、最初はマネジメントコンソールでサクッと作ったリソースが、気づけば数十個に膨れ上がっていた、という状況はよくあります。
こうしたリソースは、CloudFormation(以降CFn)の import機能を使えばスタック管理下に取り込めます。しかし、実際にやろうとすると意外と大変です。本記事ではClaude Codeを使ってCFnにimportする方法を紹介します。
「あとからIaC」の何が大変か
1. 何があるか分からない
まず「環境にどんなリソースがあるのか」を把握する必要があります。AWS CLIで各サービスのリソースを一覧取得し、既存CFnスタックの list-stack-resources と突き合わせて「管理されていないリソース」を洗い出します。
ECS、RDS、DynamoDB、Cognito、SNS、SES、Security Group、IAM などサービスの数だけCLIコマンドを叩き、出力を解釈し、分類する作業は、人間がやると数時間かかります。
2. 既存リソースと一致するテンプレートを作るのが難しい
CFn importでは、テンプレートに書いたプロパティ値が既存リソースと一致している必要があります。ズレがあるとimportが失敗します。なお、省略したプロパティはimport時に検証されませんが、import後のドリフト検出で差分として現れるため、管理したいプロパティは正確に書く必要があります。
既存リソースの現在の設定値をAWS CLIで取得し、それをCFnテンプレートの書式に変換する作業は
リソースの数だけ繰り返す必要があり膨大です。
3. リソース間の依存関係の把握が大変
importするリソースをどのスタックにまとめるか、どの順序でimportするかを決めるには、リソース間の依存関係を把握する必要があります。VPCとサブネット、ALBとターゲットグループ、ECSサービスとセキュリティグループなど、依存の方向を正しく整理しないとimportが失敗したり、スタック間の参照が壊れたりします。
4. import特有の制約がある
CFnのimport機能には制約がいくつかあります。
- ResourceIdentifierのキー名が直感と違う: CLIでは
GroupIdと表示されるSecurity Groupが、importのResourceIdentifierではIdになる。Secrets ManagerはシークレットARN(ランダムサフィックス付き)が必要 - Import非対応のリソースタイプがある: ACM Certificate、CodeBuild Project、ECS TaskDefinition等
- Outputsを含むテンプレートでimportが失敗する: import用Change Setではimport対象の追加だけにし、Outputsは後続のChange Setで追加する
- Security Groupの循環依存: 相互参照するSecurity Groupをimportすると循環依存エラーが発生。CIDRブロックに一時置換して回避
- Change Set失敗時の残骸: 新規スタック作成でimportに失敗すると
REVIEW_IN_PROGRESS状態のスタックが残りdelete-stackが必要。既存スタックへのimport失敗ならChange Set削除で済む
これらに1つずつぶつかって対処するのは、かなり骨が折れます。
Claude Codeで「あとからIaC」をする手順
ここまで説明した大変さの多くは、「AWS CLIの出力を解釈する」「リソースの設定値をCFnテンプレートに変換する」「エラーの原因を特定して対処する」という作業です。これらはまさにClaude Codeが得意とする領域です。
実際にある環境(ECS Fargate、Aurora PostgreSQL、Lambda、S3、CodePipeline等で構成)で棚卸しからimport完了まで一通りやった手順を紹介します。
1. 棚卸し
Claude Codeに「この環境のAWSリソースを全部棚卸ししてほしい」と依頼すると、各サービスのリソースを aws CLIで網羅的に取得し、既存CFnスタックとの突き合わせまで一気にやってくれます。
今回の環境では以下の未管理リソースが見つかりました
- VPC、EC2、ECS、RDS
- DynamoDB、SNS、SES、KMS、Secrets Manager
- Route53、ECR、CodePipeline、IAM
- Security Group、CloudWatch Alarm、Kinesis Firehose、ACM証明書
棚卸し結果はMarkdownで保存しておくのがおすすめです。以降の作業でClaude Codeが参照できます。
2. スタック設計
棚卸し結果をもとに「このリソース一覧を責務別にスタックに分けて」と依頼すると、依存関係を考慮した分割案を提示してくれます。今回は以下のように分かれました:
| スタック | 含むリソース |
|---|---|
vpc-stack |
VPC, Subnet, IGW, NAT Gateway, Route Table |
rds-stack |
Aurora PostgreSQL Cluster/Instance, Secret, Security Group |
ecs-infra-stack |
ECS Cluster, ALB, Target Group, Listener, Security Group, IAM Role, Log Group |
bastion-stack |
EC2 (踏み台サーバー) |
dns-stack |
Route53 Hosted Zone |
ses-stack |
SES Domain Identity, Email Identities |
sns-stack |
SNS Topics |
security-groups-stack |
Security Groups |
misc-stack |
DynamoDB, KMS, Secrets Manager, CloudWatch Alarm |
iam-stack |
IAM Roles |
cicd-stack |
ECR, CodePipeline, Kinesis Firehose |
import順序(VPC → RDS → ECS → EC2 → IAM → DNS → SES → SNS → Security Groups → misc → CI/CD)も依存関係から提案してもらいます。
3. テンプレート作成
スタック設計が決まったら「この未管理リソースをimportするためのCFnテンプレートを作って」と依頼します。Claude Codeは以下を一気にやってくれます。
awsCLIで既存リソースの現在の設定値を取得- それをCFnテンプレートの書式に変換
DeletionPolicyをimport対象の全リソースに付与(import必須要件。値は任意だが、既存リソースを守るためRetain推奨)。UpdateReplacePolicy: Retainも付与推奨--resources-to-importに渡すリソース識別子ファイル(リソースタイプと物理IDの対応JSON)も作成
既存リソースからCFnテンプレートを生成するツールとしてはAWS公式のIaC GeneratorやFormer2などもありますが、対応していないサービスがあったり、生成したテンプレートがそのままではimportできないケースがあります。Claude Codeの場合、テンプレート生成だけでなく、importが失敗したときの原因調査・修正・再試行まで一気に行えるのが強みです。
テンプレートとパラメータの分離
AWSアカウントで環境を分けている場合は、テンプレートとパラメータを分離した構成にしておくのがおすすめです。テンプレートは全環境共通、パラメータファイルだけ環境別に用意します。
cfn-templates/
├── templates/ # 環境共通テンプレート
│ ├── vpc-stack.json
│ ├── sns-stack.json
│ └── ...
├── parameters/ # 環境別パラメータ
│ ├── dev/
│ └── prod/
└── imports/ # --resources-to-import 用(リソースタイプと物理IDの対応)
├── sns-stack.json
└── ...
この構成なら、dev環境でimportを済ませたあと、prod環境ではパラメータファイルのコピー&編集だけで同じテンプレートを適用できます。
余談ですが、この構成で災害復旧(DR)手順書も作成でき、「別リージョンにパラメータを変えてデプロイするだけ」という状態を実現できました。
4. importコマンドの生成
テンプレートができたら、あとはimportを実行するだけです。Claude Codeに「importコマンドを作って」と依頼すれば、スタック名・テンプレートパス・パラメータパスを組み合わせたコマンドを生成してくれます。
# Claude Codeが生成するコマンドの例(人間がコピペして実行する)
aws cloudformation create-change-set \
--stack-name my-sns-stack \
--template-body file://templates/sns-stack.json \
--parameters file://parameters/dev/sns-stack.json \
--change-set-name ImportChangeSet \
--change-set-type IMPORT \
--resources-to-import file://imports/sns-stack.json
aws cloudformation execute-change-set \
--stack-name my-sns-stack \
--change-set-name ImportChangeSet
import自体はリソースの作り直しを伴わないため比較的安全です。人間がコマンドを確認して実行します。import完了後はドリフト検出で答え合わせをします。
aws cloudformation detect-stack-drift --stack-name my-sns-stack
DriftedStackResourceCount: 0 ならテンプレートと実態が一致しています。ドリフトが検出された場合は、テンプレートの値がどこかズレているので修正が必要です。
なお、importはテンプレートに書いたプロパティだけを検証するため、省略したプロパティが実際のリソースと異なっていてもimport自体は成功します。ドリフト検出はその漏れを拾うための答え合わせです。
5. importエラーの解決
import作業中のエラー対処もClaude Codeの出番です。エラーメッセージを貼るだけで原因と対処法を教えてくれます。
実際にぶつかったケースと対処:
| エラー | 原因 | Claude Codeの対処 |
|---|---|---|
| ResourceIdentifier不正 | Security Groupの識別子キーが GroupId ではなく Id |
公式ドキュメントの識別子一覧を参照し修正 |
| Secrets Managerのimport失敗 | シークレット名ではなくフルARN(ランダムサフィックス付き)が必要 | describe-secret でARN取得して修正 |
| 循環依存エラー | ALB用Security GroupとService用Security Groupが相互参照 | 一時的にCIDRブロックに置換→import後にIngress/Egressリソースを追加 |
| ECR LifecyclePolicy削除 | テンプレートにLifecyclePolicyを含めていなかった | get-lifecycle-policy で取得してテンプレートに追加 |
| Import非対応エラー | ACM Certificate | テンプレートから除外、CFn管理外として運用 |
これらのエラーに1つずつ手動で対処すると、そのたびにドキュメントを調べ、テンプレートを修正し、再試行……と時間がかかります。Claude Codeがいると、エラー→原因特定→修正→再試行のサイクルが格段に速くなります。
補足: CDKで管理したい場合
今回はCFnテンプレートを作成してimportしましたが、CDKで管理したい場合は cdk import コマンドで既存リソースを直接CDKスタックに取り込めます。CDKコードを既存リソースと一致する設定値で書く必要がある点はCFnと同じですが、リソース識別子ファイルの作成は不要です。
また、CFnでimportしたスタックを cdk migrate コマンドでCDKコードに変換する方法もあります。ただし生成されるコードはL1 Construct(CfnXxx)ベースで、対応範囲にも制約があるため手直し前提です。
押さえておくべき注意点
権限の考え方: Claude Codeは読み取りだけ、実行は人間
Claude Codeが意図しない変更を加えないように、Claude Codeに与えるAWS権限は読み取り(Describe/List/Get系)だけにします。
Claude Codeが担当するのは:
- 既存リソースの設定値を
awsCLIで取得する(読み取り) - 取得した情報をもとにCFnテンプレートを生成する(ローカルファイル作成)
- importに必要なCLIコマンドを生成する(テキスト出力)
import用の create-change-set や execute-change-set などの書き込みコマンドは、Claude Codeが生成したものを人間が確認して実行します。書き込み権限をClaude Codeに渡す必要はありません。
この分担なら、Claude Codeが意図しない変更を加えてしまうリスクがなく、安心して棚卸しやテンプレート生成を任せられます。
Importに非対応のリソースがある
ACM Certificate、CodeBuild Project、ECS TaskDefinition等はimport非対応です。これらはCFn管理外として運用するか、新規作成時のみCFnを使います。
import後のスタック更新にはChange Setを使う
import自体は安全な操作ですが、import後にテンプレートを変更してスタックを更新するときは注意が必要です。aws cloudformation deploy ではなく、必ず create-change-set → describe-change-set → execute-change-set の3ステップを踏みましょう。Replacement: True(リソース再作成)や Action: Remove(リソース削除)が含まれていないか、目視で確認してから実行してください。
段階的に進め、作業ログを残す
一度に全スタックをimportしようとせず、1スタックずつ確実に進めます:
- まず小さいスタック(SNS等)で手順を確立
- 手順が安定したら、VPC、RDS、Security Groupsと順に適用
- 複雑なスタック(ECS、CI/CD等)は最後に、制約を把握してから着手
作業中に発見したハマりどころはMarkdownに記録しておきます。
今回は20項目の制約事項が記録でき、後続の作業効率を大幅に上げてくれました。
この作業ログ自体もClaude Codeに整理を任せられます。
まとめ
稼働中の環境をIaC化する作業は、新規構築より慎重さが求められます。
特に「既存リソースと一致するテンプレートを作る」部分が、リソースの数だけ繰り返す単純だが膨大な作業です。
Claude Codeを使ったところ、このあたりの手間がかなり減らせました。
| 作業 | 手動 | Claude Code(読み取り権限のみ) |
|---|---|---|
| 1. 棚卸し | 数時間 | CLI実行から分類まで自動 |
| 2. スタック設計 | 依存関係の整理が大変 | 責務別の分割案を提示 |
| 3. テンプレート作成 | リソースあたり数十分 | 設定値の取得・変換まで自動 |
| 4. importコマンド生成 | 手打ち | スタック別に自動生成 |
| 5. importエラー対処 | ドキュメント調査→修正→再試行 | エラーを貼れば原因特定・修正 |
| importコマンドの実行 | 人間が確認して実行 | — |
今回、小規模な構成ではありますが import完了まで1日で終わりました。
Claude Codeには読み取り権限だけ渡して棚卸し・テンプレート生成・コマンド生成を任せ、書き込み操作は人間が実行する。「あとからIaC」は、この役割分担で安全かつ効率的に進められます。







