From 497bf24bc99b7c454e0ffca00863da6b49c88455 Mon Sep 17 00:00:00 2001 From: corymhall <43035978+corymhall@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:26:29 -0500 Subject: [PATCH 1/7] Add docs on migrating AWS CDK applications This PR adds migration docs detailing how users can migrate their AWS CDK applications to use Pulumi CDK. It also includes docs on the new experimental tool for importing the state of the AWS resources. re https://github.com/pulumi/pulumi-cdk/issues/250 --- .../migrating-to-pulumi/from-cdk.md | 328 ++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md diff --git a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md new file mode 100644 index 000000000000..e90eb37f2ae3 --- /dev/null +++ b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md @@ -0,0 +1,328 @@ +--- +title_tag: "Migrating from AWS CDK" +meta_desc: Migrate your existing AWS CDK TypeScript application +title: AWS CDK +h1: "Migrating from AWS CDK to Pulumi" +meta_image: /images/docs/meta-images/docs-meta.png +menu: + iac: + name: AWS CDK + parent: iac-adopting-migrate + weight: 2 + usingpulumi: + identifier: from-aws-cdk + parent: migrating + weight: 3 +--- + +If your team has already provisioned infrastructure using AWS CDK, and you'd like to adopt Pulumi, you have two primary strategies you can take: + +* [**Coexist**](#referencing-stack-outputs) with resources provisioned by CDK by referencing stack outputs. +* [**Convert**](#converting-cdk-applications) your CDK application to use [Pulumi CDK](https://github.com/pulumi/pulumi-cdk) + +## Referencing Stack Outputs + +It is possible to reference existing AWS CDK stacks from your program. It doesn't matter how these stacks were created. This lets you read properties of that CloudFormation stack for use within your Pulumi program. This includes output values computed from resources provisioned that stack. + +For instance, let's say your infrastructure team has provisioned your network infrastructure using CDK and you need to use the Subnet ID to provision something new from your Pulumi program. One approach is to hardcode that ID but this is brittle and, if it ever changes, you'd need to go and manually update the hardcoded value. + +Instead, you can look up that stack by name and use one of its output values. The following example reads an AWS CDK stack named `my-network-stack` and then uses the exported `SubnetId` value to provision a brand new EC2 instance that runs in that subnet: + +```ts +import * as aws from "@pulumi/aws"; + +const network = aws.cloudformation.getStackOutput({ + name: "my-network-stack", +}); + +const subnetId = network.outputs["SubnetId"]; + +const web = new aws.ec2.Instance("web", { + ami: "ami-0adc0e3ef2558cb1f", // us-west-2 AMI + instanceType: "t3.micro", + subnetId: subnetId, +}); +``` + +All we need to do is run `pulumi up` and the Pulumi runtime will know how to query the CDK stack and retrieve its output values. In this case, the CDK stack is treated entirely as read-only, and Pulumi will never attempt to modify it or any resources managed by it. + +> Although we've hard-coded the AWS CDK stack name here — `"my-network-stack"` — it's common to dynamically compute a name using unique per-stack information, like the stack name, AWS region, or other configuration variables. + +## Converting CDK Applications + +Let's say you want to migrate from AWS CDK to Pulumi and that simply co-existing side-by-side as shown above isn't sufficient. In this case you can convert your AWS CDK application to a Pulumi CDK application using the [Pulumi CDK Adapter](https://github.com/pulumi/pulumi-cdk). + +Using the below example as a starting point, we will convert this CDK +application to use Pulumi CDK. + +```ts +import * as cdk from 'aws-cdk-lib/core'; +import { Construct } from 'constructs'; +import * as s3 from 'aws-cdk-lib/aws-s3'; + +class TestStack extends cdk.Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + new s3.Bucket(this, 'Bucket'); + + } +} + +const app = new cdk.App(); +new TestStack(app, 'import-test'); +``` + +### Install Pulumi Dependencies + +The Pulumi CDK Adapter requires the installation of the following npm packages: + +* [@pulumi/aws](https://www.npmjs.com/package/@pulumi/aws) +* [@pulumi/aws-native](https://www.npmjs.com/package/@pulumi/aws-native) +* [@pulumi/docker-build](https://www.npmjs.com/package/@pulumi/docker-build) +* [@pulumi/pulumi](https://www.npmjs.com/package/@pulumi/pulumi) + +```console +npm install @pulumi/aws @pulumi/aws-native @pulumi/docker-build @pulumi/pulumi +``` + +### Convert the CDK Stack and App + +Replace the CDK `Stack` and `App` classes with Pulumi CDK `Stack` and `App` +classes. + +```ts +import * as pulumicdk from '@pulumi/cdk'; +import * as s3 from 'aws-cdk-lib/aws-s3'; + +class TestStack extends pulumicdk.Stack { + constructor(scope: pulumicdk.App, id: string) { + super(scope, id); + + new s3.Bucket(this, 'Bucket'); + + } +} + +const app = new pulumicdk.App('app', (scope: pulumicdk.App) => { + new TestStack(scope, 'import-test'); +}); +``` + +### Deploy the Pulumi Stack + +Now that you have converted your AWS CDK application to a Pulumi CDK application +you can use the Pulumi CLI to create a Pulumi Stack and deploy. + +```console +$ pulumi up +``` + +## Converting Multi-Stack CDK Applications + +If your CDK application contains multiple CDK Stacks they may fall into a couple +of scenarios. + +1. You have multiple CDK Stacks that all deploy to the same environment (AWS account/region). +2. You have multiple CDK Stacks that deploy to multiple environments + +### Converting Same Environment Stacks + +If all of your CDK Stacks deploy to the same environment you can combine them +all into a single Pulumi CDK Stack. Pulumi CDK Stacks do not have the same +resource limits that CloudFormation Stacks have. You can also control +termination protection at the resource level in Pulumi instead of at the +CloudFormation Stack level in CDK. + +Consider a common scenario of creating your stateful resources (e.g. an RDS +database) in one stack and your non-stateful resources (e.g. a Lambda Function) +in a separate Stack. + +```ts +import * as cdk from 'aws-cdk-lib/core'; +import { Construct } from 'constructs'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import * as rds from 'aws-cdk-lib/aws-rds'; + +class StatefulStack extends cdk.Stack { + public readonly cluster: rds.IDatabaseCluster; + constructor(scope: Construct, id: string) { + super(scope, id, { + terminationProtection: true, + }); + + this.cluster = new rds.DatabaseCluster(this, 'cluster', { ... }); + } +} + +interface AppStackProps extends cdk.StackProps { + cluster: rds.IDatabaseCluster +} + +class AppStack extends cdk.Stack { + constructor(scope: Construct, id: string, props: AppStackProps) { + super(scope, id, props); + + new AppConstruct(this, 'app-construct', { + cluster: props.cluster, + }) + + } +} + +const app = new cdk.App(); +const stateful = new StatefulStack(app, 'stateful-stack'); +new AppStack(app, 'app-stack', { + cluster: stateful.cluster, +}); +``` + +To convert this to a Pulumi CDK, you would combine the two stacks into a single +stack and then use `transforms` to set `protect: true` on the `DbCluster`. + +```ts +import * as pulumi from '@pulumi/pulumi'; +import * as pulumicdk from '@pulumi/cdk'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import * as rds from 'aws-cdk-lib/aws-rds'; + +interface AppStackProps extends pulumicdk.StackProps { } + +class AppStack extends pulumicdk.Stack { + constructor(scope: pulumicdk.App, id: string, props: AppStackProps) { + super(scope, id, props); + + const cluster = new rds.DatabaseCluster(this, 'cluster', { ... }); + new AppConstruct(this, 'app-construct', { + cluster: cluster, + }) + + } +} + +const app = new pulumicdk.App('app', (scope: pulumicdk.App) => { + new AppStack(app, 'app-stack'); +}, { + transforms: [ + (args: pulumi.ResourceTransformArgs): pulumi.ResourceTransformResult => { + if (args.type === 'aws-native:rds:DbCluster') { + return { + props: args.props, + opts: pulumi.mergeOptions(args.opts, { protect: true }), + }; + } + return undefined; + }, + ] +}); +``` + +### Converting Stacks with Different Environments + +If your application has stacks in different environments you can convert it to +Pulumi CDK as long as there are no dependencies between the stacks. You would +convert each individual CDK Stack to a Pulumi CDK Stack. + +For example, this: + +```ts +import * as cdk from 'aws-cdk-lib/core'; +import { Construct } from 'constructs'; +import * as s3 from 'aws-cdk-lib/aws-s3'; + +class StackEast1 extends cdk.Stack { + constructor(scope: Construct, id: string) { + super(scope, id, { + env: { region: 'us-east-1' }, + }); + + new s3.Bucket(this, 'bucket1') + } +} + +class AppStack extends cdk.Stack { + constructor(scope: Construct, id: string) { + super(scope, id, { + env: { region: 'us-east-2' }, + }); + + new s3.Bucket(this, 'bucket1') + } +} + +const app = new cdk.App(); +new StackEast1(app, 'east1-stack'); +new StackEast2(app, 'east2-stack'); +``` + +Would be converted to this: + +```ts +import * as ccapi from '@pulumi/aws-native'; +import * as aws from '@pulumi/aws'; +import * as pulumicdk from '@pulumi/cdk'; +import * as s3 from 'aws-cdk-lib/aws-s3'; + +class StackEast1 extends pulumicdk.Stack { + constructor(scope: pulumicdk.App, id: string) { + super(scope, id, { + props: { + env: { region: 'us-east-1' }, + }, + // pass explicit providers for the 'us-east-1' region + providers: [ + new ccapi.Provider('ccapi', { + region: 'us-east-1', + }), + new aws.Provider('aws', { + region: 'us-east-1', + }), + ] + }); + + new s3.Bucket(this, 'bucket1') + } +} + +class AppStack extends pulumicdk.Stack { + constructor(scope: pulumicdk.App, id: string) { + super(scope, id, { + env: { region: 'us-east-2' }, + }); + + new s3.Bucket(this, 'bucket1') + } +} + +const app = new pulumicdk.App('app', (scope: pulumicdk.App) => { + new StackEast1(scope, 'east1-stack'); + new StackEast2(scope, 'east2-stack'); +}); +``` + +## Importing CDK Resources + +All the prior examples in this guide discuss standing up a new Pulumi CDK Stack +and creating new AWS resources. If you want to instead have Pulumi import the +state of your existing resources you can try the experimental [Pulumi CDK Import +Tool](https://github.com/pulumi/pulumi-tool-cdk-importer). This tool allows you +to specify a CDK stack to import and then the resources in that stack will be +imported into your Pulumi Stack so that Pulumi can take over management of those +resources. + +**1. Install the tool** + +```console +$ pulumi plugin install tool cdk-importer +``` + +**2. Run the tool, passing in the name of the CDK Stack you want to import** + +```console +$ pulumi plugin run cdk-importer -- -stack $StackName +``` + +**3. Run `pulumi preview` to ensure there are no diffs** + +If there are any issues with importing, the tool can be run again to try the +import again without it affecting previously imported resources. From ead72ff9692bd4b23bf0da64e5781bb71959dc75 Mon Sep 17 00:00:00 2001 From: Cory Hall <43035978+corymhall@users.noreply.github.com> Date: Mon, 23 Dec 2024 08:41:54 -0500 Subject: [PATCH 2/7] Apply suggestions from code review --- .../iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md index e90eb37f2ae3..19828d330b17 100644 --- a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md +++ b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md @@ -177,7 +177,7 @@ new AppStack(app, 'app-stack', { }); ``` -To convert this to a Pulumi CDK, you would combine the two stacks into a single +To convert this to a Pulumi CDK app, you would combine the two stacks into a single stack and then use `transforms` to set `protect: true` on the `DbCluster`. ```ts @@ -240,7 +240,7 @@ class StackEast1 extends cdk.Stack { } } -class AppStack extends cdk.Stack { +class StackEast2 extends cdk.Stack { constructor(scope: Construct, id: string) { super(scope, id, { env: { region: 'us-east-2' }, @@ -284,7 +284,7 @@ class StackEast1 extends pulumicdk.Stack { } } -class AppStack extends pulumicdk.Stack { +class StackEast2 extends pulumicdk.Stack { constructor(scope: pulumicdk.App, id: string) { super(scope, id, { env: { region: 'us-east-2' }, From e38d0bdb3f06c8881f74fa1816950439ec55a2dc Mon Sep 17 00:00:00 2001 From: corymhall <43035978+corymhall@users.noreply.github.com> Date: Mon, 23 Dec 2024 08:52:09 -0500 Subject: [PATCH 3/7] adding links --- .../iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md | 6 ++++++ content/docs/iac/clouds/aws/guides/cdk.md | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md index 19828d330b17..5d3abbb494cf 100644 --- a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md +++ b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md @@ -326,3 +326,9 @@ $ pulumi plugin run cdk-importer -- -stack $StackName If there are any issues with importing, the tool can be run again to try the import again without it affecting previously imported resources. + +## More Info + +For more info on using Pulumi CDK check out the [Pulumi CDK +Guide](https://www.pulumi.com/docs/iac/clouds/aws/guides/cdk/) or the [Pulumi +CDK GitHub Repository](https://github.com/pulumi/pulumi-cdk) for more info. diff --git a/content/docs/iac/clouds/aws/guides/cdk.md b/content/docs/iac/clouds/aws/guides/cdk.md index 5c31b3c27f68..c1211abe1d20 100644 --- a/content/docs/iac/clouds/aws/guides/cdk.md +++ b/content/docs/iac/clouds/aws/guides/cdk.md @@ -793,3 +793,8 @@ create the following staging resources. 1a. `imageTagMutability`: `IMMUTABLE` 2. [aws.ecr.LifecyclePolicy](https://www.pulumi.com/registry/packages/aws/api-docs/ecr/lifecyclepolicy/) 2a. Expire old images when the number of images > 3 + +## Migrating from AWS CDK + +For a detailed guide on migrating from AWS CDK applications to Pulumi check out +the [Migration Guide](https://www.pulumi.com/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk/). From 5ef85e18f9af7ccda10e6d94bd1465afaae29700 Mon Sep 17 00:00:00 2001 From: corymhall <43035978+corymhall@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:04:00 -0500 Subject: [PATCH 4/7] add docs on converting stages --- .../migrating-to-pulumi/from-cdk.md | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md index 5d3abbb494cf..3a748419c2f5 100644 --- a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md +++ b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md @@ -300,6 +300,163 @@ const app = new pulumicdk.App('app', (scope: pulumicdk.App) => { }); ``` +## Converting CDK Stages + +An AWS CDK [Stage](https://docs.aws.amazon.com/cdk/v2/guide/stages.html) represents a group of one or more AWS CDK Stacks that are configured +to deploy together to a particular environment. For example, taking the example +from above where we deploy a `StatefulStack` and an `AppStack`, we would use +stages to deploy these to different environments. + +```ts +import * as cdk from 'aws-cdk-lib/core'; +import { Construct } from 'constructs'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import * as rds from 'aws-cdk-lib/aws-rds'; + + +interface StatefulStackProps extends cdk.StackProps { + instanceType: ec2.InstanceType; +} + +class StatefulStack extends cdk.Stack { + public readonly cluster: rds.IDatabaseCluster; + constructor(scope: Construct, id: string, props: StatefulStackProps) { + super(scope, id, { + ...props, + terminationProtection: true, + }); + + this.cluster = new rds.DatabaseCluster(this, 'cluster', { + writer: rds.ClusterInstance.provisioned('writer', { + instanceType: props.instanceType, + }), + ... + }); + } +} + +interface AppStackProps extends cdk.StackProps { + cluster: rds.IDatabaseCluster +} + +class AppStack extends cdk.Stack { + constructor(scope: Construct, id: string, props: AppStackProps) { + super(scope, id, props); + + new AppConstruct(this, 'app-construct', { + cluster: props.cluster, + }) + + } +} + +interface MyStageProps extends cdk.StageProps { + instanceType: ec2.InstanceType; +} + +class MyStage extends cdk.Stage { + constructor(scope: Construct, id: string, props: MyStageProps) { + super(scope, id, props); + const stateful = new StatefulStack(app, 'stateful-stack', { + instanceSize: props.instanceSize, + }); + new AppStack(app, 'app-stack', { + cluster: stateful.cluster, + }); + } +} + +const app = new cdk.App(); +new MyStage(app, 'dev', { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.R6G, ec2.InstanceSize.MEDIUM), +}); + +new MyStage(app, 'prod', { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.R6G, ec2.InstanceSize.XLARGE), +}); +``` + +The AWS CDK Stages can be converted to [Pulumi Stacks](https://www.pulumi.com/docs/iac/concepts/stacks/). Similar to CDK +Stages, Pulumi Stacks can be used to deploy groups of resources to different environments. + +In AWS CDK applications differences in configuration between environments are +typically configured through input parameters on the Stage. In the above +example, the `DatabaseCluster` uses a different `InstanceType` between the `dev` and `prod` environments. +When we convert this application to Pulumi, we will move this configuration from +the Stage input properties to [Stack Configuration](https://www.pulumi.com/docs/iac/concepts/config/) + +When we convert the AWS CDK application we will: + +* Combining the Stacks like we did in the [Multi Stack example](#converting-same-environment-stacks) +* Remove the use of CDK Stages +* Read the instance type from the [Pulumi Configuration](https://www.pulumi.com/docs/iac/concepts/config/). + +```ts +import * as pulumi from '@pulumi/pulumi'; +import * as pulumicdk from '@pulumi/cdk'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import * as rds from 'aws-cdk-lib/aws-rds'; + +const config = new pulumi.Config(); +const instanceType = config.require('instanceType'); + +interface AppStackProps extends pulumicdk.StackProps { + instanceType: ec2.InstanceType; +} + +class AppStack extends pulumicdk.Stack { + constructor(scope: pulumicdk.App, id: string, props: AppStackProps) { + super(scope, id, props); + + const cluster = new rds.DatabaseCluster(this, 'cluster', { + writer: rds.ClusterInstance.provisioned('writer', { + instanceType: props.instanceType, + }), + ... + }); + new AppConstruct(this, 'app-construct', { + cluster: cluster, + }) + + } +} + +const app = new pulumicdk.App('app', (scope: pulumicdk.App) => { + new AppStack(app, 'app-stack', { + instanceType: new ec2.InstanceType(instanceType), + }); +}, { + transforms: [ + (args: pulumi.ResourceTransformArgs): pulumi.ResourceTransformResult => { + if (args.type === 'aws-native:rds:DbCluster') { + return { + props: args.props, + opts: pulumi.mergeOptions(args.opts, { protect: true }), + }; + } + return undefined; + }, + ] +}); +``` + +Once we have converted the code, we create the `dev` Pulumi Stack and set the +`instanceType` config property. + +```console +$ pulumi stack init dev +$ pulumi config set instanceType r6g.medium +``` + +Then we create the `prod` Pulumi Stack and set the `instanceType` config +property. + +```console +$ pulumi stack init prod +$ pulumi config set instanceType r6g.xlarge +``` + ## Importing CDK Resources All the prior examples in this guide discuss standing up a new Pulumi CDK Stack From 25fd230813594db5e26c911fcf6010b932e20e65 Mon Sep 17 00:00:00 2001 From: corymhall <43035978+corymhall@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:12:28 -0500 Subject: [PATCH 5/7] fixing code block --- .../docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md index 3a748419c2f5..5cf02a5ca6d8 100644 --- a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md +++ b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md @@ -359,7 +359,7 @@ class MyStage extends cdk.Stage { constructor(scope: Construct, id: string, props: MyStageProps) { super(scope, id, props); const stateful = new StatefulStack(app, 'stateful-stack', { - instanceSize: props.instanceSize, + instanceType: props.instanceSize, }); new AppStack(app, 'app-stack', { cluster: stateful.cluster, From 8b506a0fc7093484e72823a252d8ebdc590c3418 Mon Sep 17 00:00:00 2001 From: corymhall <43035978+corymhall@users.noreply.github.com> Date: Mon, 23 Dec 2024 10:33:16 -0500 Subject: [PATCH 6/7] switching from reflow to semantic line breaks --- .../migrating-to-pulumi/from-cdk.md | 76 +++++++------------ content/docs/iac/clouds/aws/guides/cdk.md | 3 +- 2 files changed, 28 insertions(+), 51 deletions(-) diff --git a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md index 5cf02a5ca6d8..a7c239f3dde3 100644 --- a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md +++ b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md @@ -52,8 +52,7 @@ All we need to do is run `pulumi up` and the Pulumi runtime will know how to que Let's say you want to migrate from AWS CDK to Pulumi and that simply co-existing side-by-side as shown above isn't sufficient. In this case you can convert your AWS CDK application to a Pulumi CDK application using the [Pulumi CDK Adapter](https://github.com/pulumi/pulumi-cdk). -Using the below example as a starting point, we will convert this CDK -application to use Pulumi CDK. +Using the below example as a starting point, we will convert this CDK application to use Pulumi CDK. ```ts import * as cdk from 'aws-cdk-lib/core'; @@ -88,8 +87,7 @@ npm install @pulumi/aws @pulumi/aws-native @pulumi/docker-build @pulumi/pulumi ### Convert the CDK Stack and App -Replace the CDK `Stack` and `App` classes with Pulumi CDK `Stack` and `App` -classes. +Replace the CDK `Stack` and `App` classes with Pulumi CDK `Stack` and `App` classes. ```ts import * as pulumicdk from '@pulumi/cdk'; @@ -111,8 +109,7 @@ const app = new pulumicdk.App('app', (scope: pulumicdk.App) => { ### Deploy the Pulumi Stack -Now that you have converted your AWS CDK application to a Pulumi CDK application -you can use the Pulumi CLI to create a Pulumi Stack and deploy. +Now that you have converted your AWS CDK application to a Pulumi CDK application you can use the Pulumi CLI to create a Pulumi Stack and deploy. ```console $ pulumi up @@ -120,23 +117,18 @@ $ pulumi up ## Converting Multi-Stack CDK Applications -If your CDK application contains multiple CDK Stacks they may fall into a couple -of scenarios. +If your CDK application contains multiple CDK Stacks they may fall into a couple of scenarios. 1. You have multiple CDK Stacks that all deploy to the same environment (AWS account/region). 2. You have multiple CDK Stacks that deploy to multiple environments ### Converting Same Environment Stacks -If all of your CDK Stacks deploy to the same environment you can combine them -all into a single Pulumi CDK Stack. Pulumi CDK Stacks do not have the same -resource limits that CloudFormation Stacks have. You can also control -termination protection at the resource level in Pulumi instead of at the -CloudFormation Stack level in CDK. +If all of your CDK Stacks deploy to the same environment you can combine them all into a single Pulumi CDK Stack. +Pulumi CDK Stacks do not have the same resource limits that CloudFormation Stacks have. +You can also control termination protection at the resource level in Pulumi instead of at the CloudFormation Stack level in CDK. -Consider a common scenario of creating your stateful resources (e.g. an RDS -database) in one stack and your non-stateful resources (e.g. a Lambda Function) -in a separate Stack. +Consider a common scenario of creating your stateful resources (e.g. an RDS database) in one stack and your non-stateful resources (e.g. a Lambda Function) in a separate Stack. ```ts import * as cdk from 'aws-cdk-lib/core'; @@ -177,8 +169,7 @@ new AppStack(app, 'app-stack', { }); ``` -To convert this to a Pulumi CDK app, you would combine the two stacks into a single -stack and then use `transforms` to set `protect: true` on the `DbCluster`. +To convert this to a Pulumi CDK app, you would combine the two stacks into a single stack and then use `transforms` to set `protect: true` on the `DbCluster`. ```ts import * as pulumi from '@pulumi/pulumi'; @@ -219,9 +210,8 @@ const app = new pulumicdk.App('app', (scope: pulumicdk.App) => { ### Converting Stacks with Different Environments -If your application has stacks in different environments you can convert it to -Pulumi CDK as long as there are no dependencies between the stacks. You would -convert each individual CDK Stack to a Pulumi CDK Stack. +If your application has stacks in different environments you can convert it to Pulumi CDK as long as there are no dependencies between the stacks. +You would convert each individual CDK Stack to a Pulumi CDK Stack. For example, this: @@ -302,10 +292,9 @@ const app = new pulumicdk.App('app', (scope: pulumicdk.App) => { ## Converting CDK Stages -An AWS CDK [Stage](https://docs.aws.amazon.com/cdk/v2/guide/stages.html) represents a group of one or more AWS CDK Stacks that are configured -to deploy together to a particular environment. For example, taking the example -from above where we deploy a `StatefulStack` and an `AppStack`, we would use -stages to deploy these to different environments. +An AWS CDK [Stage](https://docs.aws.amazon.com/cdk/v2/guide/stages.html) represents a group of one or more AWS CDK Stacks that are configured to deploy together to a particular environment. +For example, taking the example from above where we deploy a `StatefulStack` and an `AppStack`, +we would use stages to deploy these to different environments. ```ts import * as cdk from 'aws-cdk-lib/core'; @@ -359,7 +348,7 @@ class MyStage extends cdk.Stage { constructor(scope: Construct, id: string, props: MyStageProps) { super(scope, id, props); const stateful = new StatefulStack(app, 'stateful-stack', { - instanceType: props.instanceSize, + instanceType: props.instanceType, }); new AppStack(app, 'app-stack', { cluster: stateful.cluster, @@ -377,14 +366,12 @@ new MyStage(app, 'prod', { }); ``` -The AWS CDK Stages can be converted to [Pulumi Stacks](https://www.pulumi.com/docs/iac/concepts/stacks/). Similar to CDK -Stages, Pulumi Stacks can be used to deploy groups of resources to different environments. +The AWS CDK Stages can be converted to [Pulumi Stacks](https://www.pulumi.com/docs/iac/concepts/stacks/). +Similar to CDK Stages, Pulumi Stacks can be used to deploy groups of resources to different environments. -In AWS CDK applications differences in configuration between environments are -typically configured through input parameters on the Stage. In the above -example, the `DatabaseCluster` uses a different `InstanceType` between the `dev` and `prod` environments. -When we convert this application to Pulumi, we will move this configuration from -the Stage input properties to [Stack Configuration](https://www.pulumi.com/docs/iac/concepts/config/) +In AWS CDK applications differences in configuration between environments are typically configured through input parameters on the Stage. +In the above example, the `DatabaseCluster` uses a different `InstanceType` between the `dev` and `prod` environments. +When we convert this application to Pulumi, we will move this configuration from the Stage input properties to [Stack Configuration](https://www.pulumi.com/docs/iac/concepts/config/) When we convert the AWS CDK application we will: @@ -441,16 +428,14 @@ const app = new pulumicdk.App('app', (scope: pulumicdk.App) => { }); ``` -Once we have converted the code, we create the `dev` Pulumi Stack and set the -`instanceType` config property. +Once we have converted the code, we create the `dev` Pulumi Stack and set the `instanceType` config property. ```console $ pulumi stack init dev $ pulumi config set instanceType r6g.medium ``` -Then we create the `prod` Pulumi Stack and set the `instanceType` config -property. +Then we create the `prod` Pulumi Stack and set the `instanceType` config property. ```console $ pulumi stack init prod @@ -459,13 +444,9 @@ $ pulumi config set instanceType r6g.xlarge ## Importing CDK Resources -All the prior examples in this guide discuss standing up a new Pulumi CDK Stack -and creating new AWS resources. If you want to instead have Pulumi import the -state of your existing resources you can try the experimental [Pulumi CDK Import -Tool](https://github.com/pulumi/pulumi-tool-cdk-importer). This tool allows you -to specify a CDK stack to import and then the resources in that stack will be -imported into your Pulumi Stack so that Pulumi can take over management of those -resources. +All the prior examples in this guide discuss standing up a new Pulumi CDK Stack and creating new AWS resources. +If you want to instead have Pulumi import the state of your existing resources you can try the experimental [Pulumi CDK Import Tool](https://github.com/pulumi/pulumi-tool-cdk-importer). +This tool allows you to specify a CDK stack to import and then the resources in that stack will be imported into your Pulumi Stack so that Pulumi can take over management of those resources. **1. Install the tool** @@ -481,11 +462,8 @@ $ pulumi plugin run cdk-importer -- -stack $StackName **3. Run `pulumi preview` to ensure there are no diffs** -If there are any issues with importing, the tool can be run again to try the -import again without it affecting previously imported resources. +If there are any issues with importing, the tool can be run again to try the import again without it affecting previously imported resources. ## More Info -For more info on using Pulumi CDK check out the [Pulumi CDK -Guide](https://www.pulumi.com/docs/iac/clouds/aws/guides/cdk/) or the [Pulumi -CDK GitHub Repository](https://github.com/pulumi/pulumi-cdk) for more info. +For more info on using Pulumi CDK check out the [Pulumi CDK Guide](https://www.pulumi.com/docs/iac/clouds/aws/guides/cdk/) or the [Pulumi CDK GitHub Repository](https://github.com/pulumi/pulumi-cdk) for more info. diff --git a/content/docs/iac/clouds/aws/guides/cdk.md b/content/docs/iac/clouds/aws/guides/cdk.md index c1211abe1d20..057355c4493b 100644 --- a/content/docs/iac/clouds/aws/guides/cdk.md +++ b/content/docs/iac/clouds/aws/guides/cdk.md @@ -796,5 +796,4 @@ create the following staging resources. ## Migrating from AWS CDK -For a detailed guide on migrating from AWS CDK applications to Pulumi check out -the [Migration Guide](https://www.pulumi.com/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk/). +For a detailed guide on migrating from AWS CDK applications to Pulumi check out the [Migration Guide](https://www.pulumi.com/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk/). From 621aa456a4a7a2d66ff84e5298d2c8a33478428e Mon Sep 17 00:00:00 2001 From: Cory Hall <43035978+corymhall@users.noreply.github.com> Date: Thu, 2 Jan 2025 11:28:29 -0500 Subject: [PATCH 7/7] Update content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md Co-authored-by: Florian Stadler --- .../docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md index a7c239f3dde3..bf779e6bd14a 100644 --- a/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md +++ b/content/docs/iac/adopting-pulumi/migrating-to-pulumi/from-cdk.md @@ -22,7 +22,7 @@ If your team has already provisioned infrastructure using AWS CDK, and you'd lik ## Referencing Stack Outputs -It is possible to reference existing AWS CDK stacks from your program. It doesn't matter how these stacks were created. This lets you read properties of that CloudFormation stack for use within your Pulumi program. This includes output values computed from resources provisioned that stack. +It is possible to reference existing AWS CDK stacks from your program. It doesn't matter how these stacks were created. This lets you read properties of that CloudFormation stack for use within your Pulumi program. This includes output values computed from resources provisioned by that stack. For instance, let's say your infrastructure team has provisioned your network infrastructure using CDK and you need to use the Subnet ID to provision something new from your Pulumi program. One approach is to hardcode that ID but this is brittle and, if it ever changes, you'd need to go and manually update the hardcoded value.