Since AWS CDK launched version 2, version 1 is now due to enter maintenance (June 1, 2022) or end-of-life (June 1, 2023). As such, there is an urgent need to upgrade all existing AWS CDK stacks to their latest version in the near future.

In this tutorial, we will discuss how to move to version 2 from version 1. You could follow the official documentation (https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html), but I thought it would be simpler for you by breaking some of the steps down for learning.

Update your global CDK version on your local machine

Before you run this step, realize that after you update your AWS CDK version globally on your local machine, all your AWS CDK version 1 stacks would not be deployable from the update.

You would have to ensure that all stacks within your code are updated once you run this command:
npm install -g aws-cdk

Remove all references to AWS CDK version 1 in your npm packages list

Let me show you my sample changes within package.json that you might need to make. This may be different from my setup because you might have more dependencies depending on your stack, but the goal is to remove all references of AWS CDK version 1 within your setup.

{
  "name": "gefyra-cdk-demo",
  "version": "0.1.0",
  "bin": {
    "gefyra-cdk-demo": "bin/gefyra-cdk-demo.js"
  },
  "scripts": {
    "build": "tsc",
    "watch": "tsc -w",
    "test": "jest",
    "cdk": "cdk"
  },
  "devDependencies": {
    "@aws-cdk/assert": "^1.90.1", // to be removed
    "@types/jest": "^26.0.20",
    "@types/node": "^10.17.54",
    "aws-cdk": "^1.90.1", // to be removed
    "jest": "^26.4.2",
    "ts-jest": "^26.5.1",
    "ts-node": "^8.1.0",
    "typescript": "^3.9.9"
  },
  "dependencies": {
    "@aws-cdk/aws-lambda": "^1.130.0", // to be removed
    "@aws-cdk/aws-s3": "^1.90.1", // to be removed
    "@aws-cdk/aws-s3-notifications": "^1.130.0", // to be removed
    "@aws-cdk/core": "^1.90.1", // to be removed
    "source-map-support": "^0.5.16"
  }
}

Also, delete package-lock.json and remove the ./node_modules folder in your repo. We will reinstall the base packages without the above libraries.

Re-install the npm libraries for your stack

  • Run npm install.
    • It will install all the libraries within your new package.json file.
  • Run npm install aws-cdk-lib constructs
    • All CDK references within your code will primarily be sourced from the aws-cdk-lib and constructs libraries.

From here on out, all your Typescript code within the AWS CDK stack would be broken. It is time to switch to the new code.

Change your AWS CDK version 1 code to version 2 conventions

Some important pointers:

  • aws-cdk-lib has replaced all aws-cdk libraries.
  • There isn’t a need to install individual dependencies to deploy any AWS resources in version 2 (i.e. @aws-cdk/aws-s3 or @aws-cdk/aws-lambda). Updating your global aws-cdk-lib and construct modules would solve all dependency issues.
    • Libraries are referenced within the aws-cdk-lib module instead. (Example, import * as codebuild from 'aws-cdk-lib/aws-codebuild';)

Changing your libraries to fit AWS CDK version 2’s convention

Below is AWS CDK version 1’s module references. This may be different from your setup.

import * as cdk from '@aws-cdk/core';
import * as s3 from "@aws-cdk/aws-s3";
import * as s3n from '@aws-cdk/aws-s3-notifications';
import * as lambda from '@aws-cdk/aws-lambda';

This is the updated code for AWS CDK version 2:

import * as cdk from 'aws-cdk-lib';
import * as s3 from "aws-cdk-lib/aws-s3";
import * as s3n from 'aws-cdk-lib/aws-s3-notifications';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import { Construct } from 'constructs'; // newly-added module

In a nutshell:

  • Change the @aws-cdk/core into aws-cdk-lib.
  • Replace all references of @aws-cdk to aws-cdk-lib.

Within your constructor, replace the cdk.Construct into Construct from the newly-added module:

// CDK doesn't contain 'Construct' anymore.
constructor(scope: cdk.Construct, id: string, props: S3Props) // From this

// We will use the newly-added module for our construct
constructor(scope: Construct, id: string, props: S3Props) // To this

Repeat this exercise for all your Typescript files within the lib and bin folders.

In general, there wouldn’t be any additional code changes unless certain methods within the AWS resource modules have been deprecated. Check the official AWS CDK docs to see which methods you might need to change for your setup.

Changing All AWS CDK Typescript Test Cases To Version 2

If you have written any test cases within the ./test folder for your Typescript infrastructure:

  • Rewrite the @aws-cdk/assert to aws-cdk-lib/assertions.
  • Many of the methods have changed:
    • aws-cdk-lib/assertions‘ doesn’t have expect, matchTemplate, and MatchStyle anymore.

For example, this is version 1 for AWS CDK testing:

import { expect as expectCDK, matchTemplate, MatchStyle } from '@aws-cdk/assert';
import * as cdk from '@aws-cdk/core';

test('Empty Stack', () => {
    const app = new cdk.App();
    // WHEN
    const stack = new GefyraCdkDemo.GefyraCdkDemoStack(app, 'MyTestStack');
    // THEN
    expectCDK(stack).to(matchTemplate({
      "Resources": {}
    }, MatchStyle.EXACT))
});

This is version 2:

import { Template } from 'aws-cdk-lib/assertions';
import * as cdk from 'aws-cdk-lib';
import * as GefyraCdkDemo from '../lib/gefyra-cdk-demo-stack';
test('Empty Stack', () => {
    const app = new cdk.App();
    // WHEN
    const stack = new GefyraCdkDemo.GefyraCdkDemoStack(app, 'MyTestStack');
    // THEN
    const template = Template.fromStack(stack);

    // Testing AWS individual resources within the stack
//   template.hasResourceProperties('AWS::SQS::Queue', {
//     VisibilityTimeout: 300
//   });
});

Change your test cases accordingly to the new format.

Remove all deprecated feature flags within cdk.json

When you run npm run build && cdk synth, the compiler will flag all the unsupported feature flags within the cdk.json:

Error: Unsupported feature flag '@aws-cdk/core:enableStackNameDuplicates'. This flag existed on CDKv1 but has been removed in CDKv2. CDK will now behave as the same as when the flag is enabled.

Remove all the unsupported feature flags within the cdk.json, and your build would run normally. If you need additional flags that are specific to your deployment, check with the official AWS CDK docs: https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html

Re-run AWS CDK bootstrap

At this point, ensure that npm run build && cdk synth runs smoothly.
AWS CDK version 2 requires us to use a new bootstrap from version 1. This means it would reference an S3 bucket to store metadata for your AWS CDK stack deployments.
Hence, run: 

  • cdk bootstrap
  • cdk bootstrap --profile {Your AWS profile/credential} for specific AWS environment deployments

At this point, your migration to version 2 should work.

Re-deploy your dev stack to ensure that your AWS account is accepting your migration changes within your repo.  Once you’re confident that your dev environment works, you should be confident to deploy to prod.

Repo for your reference: https://github.com/jonathan-moo/gefyra-cdk-demo/tree/CDK-T5