→ Use separate aws provider with cross-account role assumption
Graceful degradation for unknown handlers:
Keep the
CustomResourceEmulator
(default behavior)
Document the custom resource in the migration report with:
Original handler name and purpose (if discernible from CDK path)
Note that it uses Lambda invocation at runtime
Recommend user review for potential native replacement
2.2 Provider Strategy
Default
Use
aws-native
whenever the resource type is available.
Fallback
Use
aws
when aws-native does not support equivalent features.
2.3 Assets & Bundling
CDK uses Assets and Bundling to handle deployment artifacts. These are processed by the CDK CLI before CloudFormation deployment and appear in the
cdk.out
directory alongside
*.assets.json
metadata files. CloudFormation templates contain hard-coded references to asset locations (S3 bucket/key or ECR repo/tag).
Inspect asset definitions
jq
'.files, .dockerImages'
cdk.out/*.assets.json
Migration strategies by asset type:
Asset Type
Detection
Pulumi Migration
Docker Image
dockerImages
in assets.json
Use
docker-build.Image
to build and push. Replace hard-coded ECR URI with image output.
File with build command
files
with
executable
field
Flag to user
- build command needs setup in Pulumi
Static file
files
without
executable
, no bundling in CDK source
Use
pulumi.FileArchive
or
pulumi.FileAsset
Bundled file
files
without
executable
, but CDK source uses bundling
Flag to user
- bundling needs setup in Pulumi
Detecting Bundling in CDK Source:
Check the CDK source code for bundling constructs (
NodejsFunction
,
PythonFunction
,
GoFunction
, or resources using the
bundling
option). If bundling is used, the build step needs to be replicated in Pulumi for ongoing development - otherwise source changes would require manually re-running
cdk synth
.
When bundling is detected, inform the user:
Build Step Detected
This CDK application uses which builds deployable artifacts during synthesis. This build step needs to be replicated in Pulumi for ongoing development.
Options:
CI/CD Pipeline
(Recommended): Move the build step to your CI pipeline and reference the pre-built artifact in Pulumi
Pulumi Command Provider
Use
command.local.Command
to run the build command during
pulumi up
Pre-build Script
Create a build script that runs before
pulumi up
and outputs to a known location
Each option has tradeoffs around caching, reproducibility, and deployment speed. For production workloads, option 1 is typically preferred.
2.4 TypeScript Handling for aws-native
aws-native outputs often include undefined. Avoid
!
non-null assertions. Always safely unwrap with
.apply()
:
// ❌ WRONG - Will cause TypeScript errors
functionName
:
lambdaFunction
.
functionName
!
,
// ✅ CORRECT - Handle undefined safely
functionName
:
lambdaFunction
.
functionName
.
apply
(
name
=>
name
||
""
)
,
2.5 Environment Logic Preservation
Carry forward all conditional behaviors:
if
(
currentEnv
.
createVpc
)
{
// create resources
}
else
{
const
vpcId
=
pulumi
.
output
(
currentEnv
.
vpcId
)
;
}
3. Resource Import (optional)
After conversion you can optionally import the existing resources to now be managed by Pulumi. If the user does not request this you should suggest this as a follow up step to conversion.
Always start with automated import using the
cdk-importer
tool. Follow
cdk-importer.md
to perform the automated import.
For any resources that fail to import with the automated tool, import them manually.
If you need to manually import resources:
Follow
cloudformation-id-lookup.md
to look up CloudFormation import identifiers.
Use the web-fetch tool to get content from the official Pulumi documentation.
If there are changes you must investigate and update the program until there are no changes.
Working with the User
If the user asks for help planning or performing a CDK to Pulumi migration use the information above to guide the user towards the automated migration approach.
For Detailed Documentation
When the user wants to deviate from the recommended path detailed above, use the web-fetch tool to get content from the official Pulumi documentation ->
Assets with bundling steps, options presented, and decision if made
Final Migration Report
(PR-ready)
Next Steps
(optional refactors)
Keep code syntactically valid and clearly separated by files.