mcpField
P
pulumi-cdk-to-pulumi

pulumi-cdk-to-pulumi

github.com/pulumi云与 DevOps78901 次安装3 周前更新
代码仓库

关于 pulumi-cdk-to-pulumi

用于指导 CDK 到 Pulumi 迁移的技能,涵盖资源转换、自定义资源、资产处理、验证和 PR 报告,面向处理 AWS 基础设施迁移的 Agent。

主要功能

  1. 01分步迁移工作流
  2. 02CDK 资源盘点与转换
  3. 03自定义资源替换指导
  4. 04资产与打包迁移指导
  5. 05导入与预览验证
  6. 06面向 PR 的迁移报告

适用场景

  1. 01将 CDK 项目转换为 Pulumi 代码
  2. 02识别迁移中的遗漏资源或自定义资源
  3. 03规划 CDK 资产及构建步骤的处理方式
  4. 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.md
cdk-importer.md
cloudformation-id-lookup.md
use_cases.yaml
agents/
openai.yaml

详细介绍

关键成功要求

迁移输出必须满足以下所有要求:

  1. 完整覆盖资源

    • CDK 合成的每个 CloudFormation 资源都必须:
      • 在 Pulumi 程序中表示,或
      • 在最终报告中明确说明原因。
  2. 成功部署

    • 生成的 Pulumi 程序在结构上必须有效,并能够成功执行 pulumi up(假设配置正确)。
  3. 最终迁移报告

    • 始终输出适用于 Pull Request 的正式迁移报告。
    • 内容包括:
      • CDK → Pulumi 资源映射
      • Provider 决策(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 环境,请先询问用户要使用哪个 ESC 环境,再运行 AWS 命令。

你必须向用户确认 AWS 区域。如果使用了错误的 AWS 区域,cdk synth 的结果可能不正确。

1.2 合成 CDK

运行或检查:

npx cdk synth --quiet
  • 始终使用 --quiet 运行 synth,以防止模板输出到 stdout。

如果失败,请检查 cdk.json 或 package.json 中是否配置了自定义合成行为。

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 使用 Lambda 支持的自定义资源来实现 CloudFormation 不支持的功能。在合成的 CloudFormation 中,这些资源会显示为:

  • 资源类型:AWS::CloudFormation::CustomResource 或 Custom::<name>
  • 元数据包含 aws:cdk:path,其中记录了处理程序名称(例如,aws-s3/auto-delete-objects-handler)

默认行为:cdk2pulumi 会将自定义资源重写为 aws-native:cloudformation:CustomResourceEmulator,由其调用原始 Lambda。此方式可用,但也有一些取舍(依赖 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 替换为 aws.ecr.Repository,并设置 forceDelete: true
aws-s3/auto-delete-objects-handler将 aws-native:s3:Bucket 替换为 aws.s3.Bucket,并设置 forceDestroy: true
aws-s3/notifications-resource-handler替换为 aws.s3.BucketNotification
aws-logs/log-retention-handler替换为 aws.cloudwatch.LogGroup,并显式设置 retentionInDays
aws-iam/oidc-handler替换为 aws.iam.OpenIdConnectProvider
aws-route53/delete-existing-record-set-handler替换为 aws.route53.Record,并设置 allowOverwrite: true
aws-dynamodb/replica-handler替换为 aws.dynamodb.TableReplica

跨账号/区域处理程序:

  • aws-cloudfront/edge-function → 使用 aws.lambda.Function,并设置 region: "us-east-1"
  • aws-route53/cross-account-zone-delegation-handler → 使用单独的 aws 提供程序,并通过跨账号角色进行身份代入

未知处理程序的优雅降级:

  1. 保留 CustomResourceEmulator(默认行为)
  2. 在迁移报告中记录该自定义资源,包括:
    • 原始处理程序名称和用途(如果可以从 CDK 路径中判断)
    • 说明其会在运行时调用 Lambda
    • 建议用户评估是否可以替换为原生资源
2.2 提供程序策略
  • 默认:只要资源类型可用,就使用 aws-native。
  • 回退:当 aws-native 不支持等效功能时,使用 aws。
2.3 资源与打包

CDK 使用资源和打包来处理部署产物。CDK CLI 会在 CloudFormation 部署前处理这些产物,并将其放在 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 替换为镜像输出。
带构建命令的文件files 中带有 executable 字段向用户标记——需要在 Pulumi 中设置构建命令
静态文件files 中没有 executable,且 CDK 源码中没有打包使用 pulumi.FileArchive 或 pulumi.FileAsset
已打包的文件files 中没有 executable,但 CDK 源码使用了打包向用户标记——需要在 Pulumi 中设置打包

检测 CDK 源码中的打包:

检查 CDK 源码,查看是否使用了打包结构(NodejsFunction、PythonFunction、GoFunction,或使用 bundling 选项的资源)。如果使用了打包,则需要在 Pulumi 中复现构建步骤,以便持续开发;否则,源代码变更后需要手动重新运行 cdk synth。

检测到打包时,告知用户:

检测到构建步骤:此 CDK 应用使用 <BUNDLING_TYPE>,会在合成期间构建可部署的产物。持续开发需要在 Pulumi 中复现此构建步骤。

选项:

  1. CI/CD 流水线(推荐):将构建步骤移至 CI 流水线,并在 Pulumi 中引用预构建的产物
  2. Pulumi Command Provider:使用 command.local.Command 在 pulumi up 期间运行构建命令
  3. 预构建脚本:创建一个在 pulumi up 之前运行并将产物输出到已知位置的构建脚本

每种选项在缓存、可复现性和部署速度方面各有取舍。对于生产工作负载,通常优先选择选项 1。

2.4 aws-native 的 TypeScript 处理

aws-native 的输出通常包含 undefined。避免使用 ! 非空断言。始终使用 .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 执行自动导入。
  • 对于自动工具导入失败的资源,请手动导入。

如果需要手动导入资源:

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 构造
  • 执行策略
    • 自动化迁移(推荐)
    • 手动迁移

输出格式(必需)

执行迁移时,始终提供:

  1. 概述(高层级描述)
  2. 迁移计划摘要
  3. Pulumi 代码输出(TypeScript;按文件组织)
  4. 资源映射表(CDK → Pulumi)
  5. 自定义资源摘要(如有):
    • 已迁移为原生 Pulumi 资源的处理程序
    • 保留为 CustomResourceEmulator 的处理程序及其理由
    • 任何需要用户注意的处理程序
  6. 资产和打包摘要(如有):
    • 已迁移:成功转换的资产(例如,Docker 镜像 → docker-build.Image,静态文件 → pulumi.FileArchive)
    • 需要注意:包含打包步骤的资产、提供的选项,以及(如已做出)决策
  7. 最终迁移报告(可用于 PR)
  8. 后续步骤(可选重构)

确保代码语法有效,并按文件清晰分隔。

评论

支持 Markdown