Claude Codeで「あとからIaC」— 既存AWSリソースをCloudFormationにimportする実践ガイド

Claude Codeで「あとからIaC」— 既存AWSリソースをCloudFormationにimportする実践ガイド

既存AWSリソースをCloudFormationにimportする「あとからIaC」に関する記事です。棚卸しからテンプレート作成、エラー対処までClaude Codeで効率化する実践手順を紹介します。
2026.03.10

はじめに

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は以下を一気にやってくれます。

  1. aws CLIで既存リソースの現在の設定値を取得
  2. それをCFnテンプレートの書式に変換
  3. DeletionPolicy をimport対象の全リソースに付与(import必須要件。値は任意だが、既存リソースを守るため Retain 推奨)。UpdateReplacePolicy: Retain も付与推奨
  4. --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が担当するのは:

  • 既存リソースの設定値を aws CLIで取得する(読み取り)
  • 取得した情報をもとにCFnテンプレートを生成する(ローカルファイル作成)
  • importに必要なCLIコマンドを生成する(テキスト出力)

import用の create-change-setexecute-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-setdescribe-change-setexecute-change-set の3ステップを踏みましょう。Replacement: True(リソース再作成)や Action: Remove(リソース削除)が含まれていないか、目視で確認してから実行してください。

段階的に進め、作業ログを残す

一度に全スタックをimportしようとせず、1スタックずつ確実に進めます:

  1. まず小さいスタック(SNS等)で手順を確立
  2. 手順が安定したら、VPC、RDS、Security Groupsと順に適用
  3. 複雑なスタック(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」は、この役割分担で安全かつ効率的に進められます。

この記事をシェアする

FacebookHatena blogX

関連記事