The article was updated on May 17th, 2023 (Wed) for keeping update-to-date.
Content table
Prologue
The AWS Cloud Development Kit (AWS CDK) v2 is GA on Dec. 2nd, 2021 (Thur). You might have been using CDK v1, either Typescript, Javascript, Python, Java, or .NET, to create and manage your infrastructure for quite a while. Some crucial parts in CDK v2 are that every stable module is now integrated into a module called aws-cdk-lib
and the Construct
class is extracted into another library instead of cdk.Construct
by import * as cdk from '@aws-cdk/core';
in CDK v1. In the mean time, those packages which are still in experimental mode (status) will still be like individual modules that you used to import in CDK v1.
In this post, I'll note the parts that I changed from an existing CDK application based on v1 to CDK v2, including the application part and its test. This application is composed of 30 resources and was deployed via CDK v1 in the past. Now, it is deployed with CDK v2 into production and no issue found so far.
My First Migration CDK Application from V1 to V2
CDK settings
cdk.json
Before
{
"app": "npx ts-node --prefer-ts-exts bin/aws-helper.ts",
"context": {
"@aws-cdk/core:newStyleStackSynthesis": false,
"@aws-cdk/core:stackRelativeExports": false,
"@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
"@aws-cdk/aws-lambda:recognizeVersionProps": false,
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false
}
}
After
{
"app": "npx ts-node --prefer-ts-exts bin/aws-helper.ts",
"context": {
"@aws-cdk/core:newStyleStackSynthesis": false,
"@aws-cdk/core:stackRelativeExports": false,
"@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
"@aws-cdk/aws-lambda:recognizeVersionProps": false,
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false
}
}
Theoretically, you just need to remove all the feature flags put on cdk.json
in v1, and can check whether you need the new features listed on the official documentation via cdk diff
. For further detail, you could also go to the Github documentation to take a look. As you could see, in my v1 cdk.json
of the application, none of the features is related to those new suggested in the v2 cdk.json
. Yet I love the concept of YOU DON'T TURN YOUR BACK ON FAMILY from Vin Diesel, I just put all of them onto the v2 cdk.json
.
Dependencies
Before
"dependencies": {
"@aws-cdk/aws-events": "^1.96.0",
"@aws-cdk/aws-events-targets": "^1.96.0",
"@aws-cdk/aws-iam": "^1.96.0",
"@aws-cdk/aws-lambda": "^1.96.0",
"@aws-cdk/aws-lambda-python": "^1.96.0",
"@aws-cdk/aws-stepfunctions": "^1.105.0",
"@aws-cdk/aws-stepfunctions-tasks": "^1.105.0",
"@aws-cdk/core": "^1.96.0",
"esbuild": "^0.11.2",
"source-map-support": "^0.5.16"
}
After
"dependencies": {
"@aws-cdk/aws-lambda-python-alpha": "^2.0.0-alpha.11",
"aws-cdk-lib": "^2.0.0",
"constructs": "^10.0.0"
}
Yes, that's it. In cdk v2, in general scenario, you only need aws-cdk-lib
and constructs
. Yet in my first migration application, I use @aws-cdk/aws-lambda-python
to build up my Python-based Lambda functions based on ARM. And this module is still in experimental mode as you could notice on the v2 API references, therefore, you need to add it into the dependencies part of package.json
. AND you don't see it wrong, all experimental modules will be suffixed with alpha
, that's one of the conventions you need to adapt yourself to it. About what version you need to specify regarding experimental modules, go check it on npm, my child, that's the quickest way I could sense so far. After you're highly familiar with how experimental versions are progressed, you farewell with looking up on npm.
peerDependencies
I don't have any item in the peerDependencies
part of package.json
. And I added the following items into package.json
with cdk v2.
"peerDependencies": {
"aws-cdk-lib": "^2.0.0",
"constructs": "^10.0.0"
},
devDependnecies
Before
"devDependencies": {
"@aws-cdk/assert": "^1.96.0",
"@types/jest": "^26.0.10",
"@types/node": "^10.17.27",
"aws-cdk": "^1.96.0",
"jest": "^26.4.2",
"ts-jest": "^26.2.0",
"ts-node": "^9.0.0",
"typescript": "~3.9.7"
}
After
"devDependencies": {
"@aws-cdk/assert": "^2.1.0",
"@types/jest": "^26.0.10",
"@types/node": "^10.17.27",
"aws-cdk-lib": "^2.0.0",
"constructs": "^10.0.0",
"jest": "^26.4.2",
"ts-jest": "^26.2.0",
"ts-node": "^9.0.0",
"typescript": "~3.9.7"
}
Since in the CDK application, I have some tests about the application. The only part you need to mind is you upgrade the version of @aws-cdk/assert
and add aws-cdk-lib
and constructs
. You think there is another name for testing? No, no, no, you upgrade the version. By doing so, you don't need to change the testing where you've put quite hard effort and enter into the v2 world.
Modify Import
Stable
-
import * as cdk from '@aws-cdk/core'
=>import {App, Fn, Tags} from 'aws-cdk-lib'
. -
import targets = require('@aws-cdk/aws-events-targets')
=>import targets = require('aws-cdk-lib/aws-events-targets')
-
import * as iam from '@aws-cdk/aws-iam';
=>import { aws_iam as iam } from 'aws-cdk-lib';
import { Construct } from 'constructs';
There are three parts I gotta modify as you could see the list above. And about point 3, before #issue17860 is resolved, you just follow what I've done, otherwise, you may fail even executing yarn build
. In my CDK application, there are four .ts
files under the lib
directory, do you modify one by one? You might ask. My child, that is feasible yet you may start doubting why you have an infrastructure role and why you are here at the moment you're migrating. I usually count on VS Code for programming, both services and infrastructure. And you got take advantage of the Replace All
function in VS Cod., That will save your life, trust me.
Experimental modules
-
import {PythonFunction} from '@aws-cdk/aws-lambda-python'
=>import {PythonFunction} from '@aws-cdk/aws-lambda-python-alpha
That's it, just that easy.
Bootstrapping
Conversion from CDK v1 to CDK v2 seems not too cumbersome as a heavy user of CDK v1. On the documentation, it is suggested that you should not install CDK Toolkit v2 globally if you'll create both v1 and v2 projects. For new projects, I'm probably going to initialize them with CDK v2 yet for retaining risk to the lowest, I'll make v1 and v2 as different aliases.
# alias cdk1="npx aws-cdk@1.x"
alias cdk="npx aws-cdk@2.x"
PROFILE_NAME="ker_ker"
ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --profile ${PROFILE_NAME} | tr -d '\"')
AWS_REGION="YOUR_REGION_BABY"
export CDK_NEW_BOOTSTRAP=1 && cdk bootstrap \
--profile ${PROFILE_NAME} \
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \
aws://${ACCOUNT_ID}/${AWS_REGION}
In other projects, I use the CDK pipelines module, therefore, I bootstrapped the environment for CDK v2 as the above. If you don't use the CDK pipelines module to execute automatic deployment for your infrastructure, your re-bootstrapping command will be simpler than mine.
Conclusion
After done with re-bootstrapping, from testing, upgrading packages to deployment, all the CDK commands remain the same. And there's still one issue, i.e., we might only need 10 minutes to migrate a v1 application to v2, what if there are decades of complicated applications? How I wish I could migrate my whole v1 applications to v2 just with one click. That a utopian world I'll enter in my dream now. Other than that, have good time on your migration journey from CDK v1 to CDK v2.
Top comments (2)
What do you mean when you say
In other projects, I use the CDK pipelines module, therefore, I bootstrapped the environment for CDK v2 as the above.
. We use the CDK Pipelines module, why is the bootstrap process any different(as in your case you bootstrapped v2 with an alias)?Is the Pipelines module not supported in v2?
As mentioned in the documentation. If you are not building a CDK Construct with your project, then you don't need to add anything into
peerDependencies
. This is only necessary, if your CDK Construct will be integrated into another CDK App.documentation -> Updating dependencies and imports:
See difference between Applications and Construct libraries