pulumi-cdk-to-pulumi について
CDK から Pulumi への移行を支援するスキルです。AWS インフラの移行を行うエージェント向けに、リソース変換、カスタムリソース、アセット、検証、PR 用レポートの手順をまとめています。
主な機能
- 01段階的な移行ワークフロー
- 02CDK リソースの一覧化と変換
- 03カスタムリソースの置き換え指針
- 04アセットとバンドリングの移行指針
- 05インポートとプレビューの検証
- 06PR 向け移行レポート
活用シーン
- 01CDK プロジェクトを Pulumi コードへ変換
- 02移行時の不足リソースやカスタムリソースの特定
- 03CDK アセットとビルド手順の扱いを計画
- 04引き渡し前にインポート済みスタックを検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pulumi/ agent-skills --skill pulumi-cdk-to-pulumiインストール後、Claude Code で/pulumi-cdk-to-pulumiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
cdk-convert.mdcdk-importer.mdcloudformation-id-lookup.mduse_cases.yamlagents/openai.yaml詳細
重要な成功要件
移行の出力は、以下のすべてを満たす必要があります。
-
すべてのリソースを網羅
- CDK によって合成されるすべての CloudFormation リソースは、次のいずれかを満たす必要があります。
- Pulumi プログラムに表現されている
- または、最終レポートで明確に理由が説明されている
- CDK によって合成されるすべての CloudFormation リソースは、次のいずれかを満たす必要があります。
-
デプロイの成功
- 生成される Pulumi プログラムは構造的に有効であり、(適切な設定がある場合に)
pulumi upを正常に実行できる必要があります。
- 生成される Pulumi プログラムは構造的に有効であり、(適切な設定がある場合に)
-
最終移行レポート
- プルリクエストに適した正式な移行レポートを必ず出力してください。
- 以下を含めてください。
- CDK → Pulumi のリソースマッピング
- プロバイダーの選択(aws-native または aws)
- 動作上の違い
- 不足している手順、または手動で必要となる手順
- 検証手順
情報が不足している場合
ユーザーが提供した CDK プロジェクトに不備がある、曖昧な点がある、または cdk.out などの成果物が不足している場合は、Pulumi コードを生成する前に、対象を絞った質問をしてください。
移行ワークフロー
このワークフローに、記載された順序どおりに正確に従ってください。
1. 情報収集
1.1 AWS 認証情報を確認する(ESC)
AWS コマンド(例:aws cloudformation list-stack-resources)および CDK コマンド(例:cdk synth)の実行には、Pulumi ESC 経由で読み込まれた認証情報が必要です。
- ユーザーがすでに ESC 環境を提供している場合は、それを使用してください。
- ESC 環境が指定されていない場合は、AWS コマンドを実行する前に、どの ESC 環境を使用するかユーザーに確認してください。
AWS リージョンを必ずユーザーに確認してください。誤った AWS リージョンで実行すると、cdk synth の結果が不正確になる場合があります。
1.2 CDK を合成する
次を実行/確認してください。
npx cdk synth --quiet
- テンプレートが標準出力に出力されないように、必ず
--quietを指定してsynthを実行してください。
失敗した場合は、cdk.json または package.json を確認し、カスタムの synth 動作がないか調べてください。
1.3 CDK スタックと環境を特定する
cdk.out/manifest.json を読み込みます。
jq '.artifacts | to_entries | map(select(.value.type == "aws:cloudformation:stack") | {displayName: .key, environment: .value.environment}) | .[]' cdk.out/manifest.json
出力例:
{
"displayName": "DataStack-dev",
"environment": "aws://616138583583/us-east-2"
}
{
"displayName": "AppStack-dev",
"environment": "aws://616138583583/us-east-2"
}
作成する Pulumi スタックでは、aws:region と aws-native:region の両方の設定変数を必ず設定してください。例:
pulumi config set aws-native:region us-east-2 --stack dev
pulumi config set aws:region us-east-2 --stack dev
1.4 リソースインベントリを作成する
スタックごとに、次を実行します。
aws cloudformation list-stack-resources \
--region <region> \
--stack-name <stack> \
--output json
1.5 CDK の構造を分析する
以下を抽出します。
- 環境固有の条件分岐
- スタックの依存関係とスタック間参照
- ランタイム設定(コンテキスト/環境変数)
- コンストラクトの種類(L1、L2、L3)
2. コード変換(CDK → PULUMI)
cdk2pulumiツールを使用して初期変換を行います。変換を実施するには、cdk-convert.md に従ってください。- 変換レポートを読み、抜けている箇所を補ってください。たとえば、変換でリソースが変換されなかった場合は、自分で手動変換する必要があります。
2.1 カスタムリソースの処理
CDK は、CloudFormation で利用できない機能に Lambda ベースのカスタムリソースを使用します。合成された CloudFormation では、次のように表示されます。
- リソースタイプ:
AWS::CloudFormation::CustomResourceまたはCustom::<name> - メタデータに、ハンドラー名を含む
aws:cdk:pathが含まれます(例:aws-s3/auto-delete-objects-handler)
デフォルトの動作:cdk2pulumi は、カスタムリソースを元の Lambda を呼び出す aws-native:cloudformation:CustomResourceEmulator に書き換えます。これは動作しますが、Lambda への依存、コールドスタート、結果整合性といったトレードオフがあります。
ハンドラータイプごとの移行戦略:
| ハンドラー | 戦略 |
|---|---|
aws-certificatemanager/dns-validated-certificate-handler | aws.acm.Certificate、aws.route53.Record、および aws.acm.CertificateValidation に置き換えます |
aws-ec2/restrict-default-security-group-handler | インバウンド/アウトバウンドルールを空にした aws.ec2.DefaultSecurityGroup リソースに置き換えます |
aws-ecr/auto-delete-images-handler | aws-native:ecr:Repository を forceDelete: true を指定した aws.ecr.Repository に置き換えます |
aws-s3/auto-delete-objects-handler | aws-native:s3:Bucket を forceDestroy: true を指定した aws.s3.Bucket に置き換えます |
aws-s3/notifications-resource-handler | aws.s3.BucketNotification に置き換えます |
aws-logs/log-retention-handler | retentionInDays を明示した aws.cloudwatch.LogGroup に置き換えます |
aws-iam/oidc-handler | aws.iam.OpenIdConnectProvider に置き換えます |
aws-route53/delete-existing-record-set-handler | allowOverwrite: true を指定した aws.route53.Record に置き換えます |
aws-dynamodb/replica-handler | aws.dynamodb.TableReplica に置き換えます |
アカウント/リージョンをまたぐハンドラー:
aws-cloudfront/edge-function→region: "us-east-1"を指定したaws.lambda.Functionを使用しますaws-route53/cross-account-zone-delegation-handler→ アカウントをまたいだロール引き受けを使用する、別の aws プロバイダーを使用します
不明なハンドラーの適切なフォールバック:
CustomResourceEmulatorを維持します(デフォルトの動作)- 移行レポートにカスタムリソースについて記載し、次の情報を含めます。
- 元のハンドラー名と用途(CDK パスから判別できる場合)
- 実行時に Lambda の呼び出しを使用する旨
- ネイティブな置き換えが可能かどうか、ユーザーによる確認を推奨する旨
2.2 プロバイダー戦略
- デフォルト:リソースタイプが利用可能な場合は、常に
aws-nativeを使用します。 - フォールバック:aws-native が同等の機能をサポートしていない場合は、
awsを使用します。
2.3 アセットとバンドル
CDK では、アセットとバンドルを使用してデプロイ成果物を処理します。これらは CloudFormation によるデプロイ前に CDK CLI で処理され、cdk.out ディレクトリに *.assets.json メタデータファイルとともに出力されます。CloudFormation テンプレートには、アセットの場所(S3 バケット/キー、または ECR リポジトリ/タグ)へのハードコードされた参照が含まれています。
# Inspect asset definitions
jq '.files, .dockerImages' cdk.out/*.assets.json
アセットの種類ごとの移行方法:
| アセットの種類 | 検出方法 | Pulumi への移行 |
|---|---|---|
| Docker イメージ | assets.json 内の dockerImages | docker-build.Image を使用してビルドおよびプッシュします。ハードコードされた ECR URI をイメージの出力値に置き換えます。 |
| ビルドコマンド付きファイル | executable フィールドを持つ files | ユーザーに通知 — ビルドコマンドを Pulumi で設定する必要があります |
| 静的ファイル | executable がなく、CDK ソースにバンドル処理もない files | pulumi.FileArchive または pulumi.FileAsset を使用します |
| バンドルされたファイル | executable はないものの、CDK ソースでバンドル処理を使用している files | ユーザーに通知 — Pulumi でバンドル処理を設定する必要があります |
CDK ソースでのバンドル処理の検出:
CDK ソースコードで、バンドル処理を行う構成要素(NodejsFunction、PythonFunction、GoFunction、または bundling オプションを使用するリソース)を確認します。バンドル処理が使用されている場合、開発を継続できるように、Pulumi でビルド手順を再現する必要があります。そうしないと、ソースに変更を加えるたびに、手動で cdk synth を再実行する必要があります。
バンドル処理が検出された場合、ユーザーに次のように伝えます:
ビルド手順が検出されました:この CDK アプリケーションでは、合成時にデプロイ可能な成果物をビルドする <BUNDLING_TYPE> を使用しています。開発を継続できるように、Pulumi でこのビルド手順を再現する必要があります。
選択肢:
- CI/CD パイプライン(推奨):ビルド手順を CI パイプラインに移し、Pulumi ではビルド済みの成果物を参照します
- Pulumi Command Provider:
command.local.Commandを使用して、pulumi upの実行中にビルドコマンドを実行します- 事前ビルドスクリプト:
pulumi upの前に実行し、既知の場所に出力するビルドスクリプトを作成します各選択肢には、キャッシュ、再現性、デプロイ速度に関するトレードオフがあります。本番環境のワークロードでは、通常は選択肢 1 が推奨されます。
2.4 aws-native の TypeScript 処理
aws-native の出力には、undefined が含まれることがよくあります。! による非 null アサーションは避けてください。常に .apply() を使用して安全に値を取り出してください:
// ❌ WRONG - Will cause TypeScript errors
functionName: lambdaFunction.functionName!,
// ✅ CORRECT - Handle undefined safely
functionName: lambdaFunction.functionName.apply(name => name || ""),
2.5 環境ロジックの維持
すべての条件付き動作を引き継いでください:
if (currentEnv.createVpc) {
// create resources
} else {
const vpcId = pulumi.output(currentEnv.vpcId);
}
3. リソースのインポート(任意)
変換後、既存のリソースを任意でインポートして、Pulumi で管理できるようにします。ユーザーから依頼がない場合は、変換後の追加手順として提案してください。
- 必ず
cdk-importerツールを使用した自動インポートから始めます。自動インポートを実行するには、cdk-importer.md に従ってください。 - 自動インポートツールでインポートに失敗したリソースは、手動でインポートしてください。
リソースを手動でインポートする必要がある場合:
-
CloudFormation のインポート識別子を調べるには、cloudformation-id-lookup.md に従ってください。
-
web-fetch ツールを使用して、Pulumi の公式ドキュメントから内容を取得してください。
-
AWS のインポート ID の確認 -> https://www.pulumi.com/docs/iac/guides/migration/aws-import-ids/
3.1 インポート後のプレビュー実行
インポート後は pulumi preview を実行し、変更がないことを確認する必要があります。変更がない状態とは、次の操作がないことを意味します:
- 更新
- 置換
- 作成
- 削除
変更がある場合は、変更がなくなるまで調査してプログラムを更新する必要があります。
ユーザーとの作業
ユーザーが CDK から Pulumi への移行の計画や実行について支援を求めている場合は、上記の情報を参考に、自動移行の方法を案内してください。
詳細なドキュメントについて
ユーザーが上記で説明した推奨パスから外れることを希望する場合は、ウェブ取得ツールを使用して公式の Pulumi ドキュメントからコンテンツを取得してください → https://www.pulumi.com/docs/iac/guides/migration/migrating-to-pulumi/migrating-from-cdk/migrating-existing-cdk-app
このドキュメントでは、次のトピックを扱っています。
- 移行戦略
- 変換と書き換え
- インポートと再構築
- ベストプラクティス
- 複数の CDK スタックの処理
- CDK ステージの処理
- コードの構成
- CDK コンストラクトの変換
- 実行戦略
- 自動移行(推奨)
- 手動移行
出力形式(必須)
移行を実施する際は、必ず次の内容を出力してください。
- 概要(大まかな説明)
- 移行計画の概要
- Pulumi コードの出力(TypeScript。ファイルごとに構成)
- リソースのマッピング表(CDK → Pulumi)
- カスタムリソースの概要(該当する場合):
- ネイティブの Pulumi リソースに移行したハンドラー
CustomResourceEmulatorのままにしたハンドラーとその理由- ユーザーによる対応が必要なハンドラー
- アセットとバンドルの概要(該当する場合):
- 移行済み:正常に変換されたアセット(例:Docker イメージ →
docker-build.Image、静的ファイル →pulumi.FileArchive) - 要対応:バンドル手順が必要なアセット、提示した選択肢、決定内容(決定済みの場合)
- 移行済み:正常に変換されたアセット(例:Docker イメージ →
- 最終移行レポート(プルリクエスト対応形式)
- 次のステップ(任意のリファクタリング)
コードの構文が正しくなるようにし、ファイルごとに明確に分けてください。