How to migrate CDK v1 to CDK v2 in 10 minuets
Tags: aws, cdk, migration, infrastructure
Published: 2021-12-10 06:57:18

> The article was updated on May 17th, 2023 (Wed) for keeping update-to-date.

#Content table
* [Prologue](#prologue)
* [CDK Settings](#cdk-settings)
  * [`cdk.json`](#-raw-cdkjson-endraw-)
  * [Dependencies](#dependencies)
  * [peerDependencies](#peerDependencies)
  * [devDependnecies](#devDependnecies)
* [Modify Import](#modify-import)
  * [Stable](#stable)
  * [Experimental modules](#experimental-modules)
* [Bootstrapping](#bootstrapping)
* [Conclusion](#conclusion)

#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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84q0bc40il4fbpfllwfb.png) _My First Migration CDK Application from V1 to V2_

#CDK settings
##`cdk.json`
**Before**
```json
{
  "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**
```json
{
  "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](https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html#migrating-v2-v1-upgrade-cdk-json) via `cdk diff`. For further detail, you could also go to the [Github documentation](https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/cx-api/FEATURE_FLAGS.md) 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**
```json
"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**
```json
"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](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-lambda-python-alpha-readme.html), 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](https://www.npmjs.com/package/@aws-cdk/aws-lambda-python-alpha), 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](https://www.npmjs.com/).
##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.
```json
"peerDependencies": {
  "aws-cdk-lib": "^2.0.0",
  "constructs": "^10.0.0"
},
```
##devDependnecies
**Before**
```json
"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**
```json
"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
1. `import * as cdk from '@aws-cdk/core'` => `import {App, Fn, Tags} from 'aws-cdk-lib'`.
2. `import targets = require('@aws-cdk/aws-events-targets')` => `import targets = require('aws-cdk-lib/aws-events-targets')`
3. `import * as iam from '@aws-cdk/aws-iam';` => `import { aws_iam as iam } from 'aws-cdk-lib';`
4. `import { Construct } from 'constructs';`

There are three parts I gotta modify as you could see the list above. And about point 3, before [#issue17860](https://github.com/aws/aws-cdk/issues/17860) 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
1. `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](https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html), 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.

```bash
# 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](https://docs.aws.amazon.com/cdk/api/latest/docs/pipelines-readme.html) 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.


![CDK V2 API Reference](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5eydulklaajje0b05q8z.png) _A Screenshot of CDK V2 API Reference_