AWS Developer Tools Blog

Announcing AWS Cloud Development Kit v2 Developer Preview

The AWS Cloud Development Kit (AWS CDK) v2 is now available for Developer Preview in TypeScript, Python, Java, C#, and Go. The AWS CDK is an open-source software development framework to model and provision your cloud application resources using familiar programming languages. With the AWS CDK, you can define your infrastructure as code and provision it through AWS CloudFormation. AWS CDK provides high-level components that preconfigure cloud resources with proven defaults, so you can build cloud applications without needing to be an expert. It also enables you to compose and share your own custom components that incorporate your organization’s requirements, which helps teams start new projects faster.

In July of 2019, we announced the general availability of AWS CDK v1 for Typescript and Python. Since that time, we have released support for additional languages in Java and C#, and we released language bindings for Go in Developer Preview. We’re now announcing a preview release of v2, which introduces a couple of changes that make it easier for you to consume the AWS CDK and stay up to date with new versions as we evolve it going forwards.

Migrating from the latest minor version of an AWS CDK v1 application to v2 is relatively painless. You need to start by re-bootstrapping your AWS accounts, which is a one-time action. Then for most projects, all you need to do is update your import statements, synthesize, and deploy. You may notice some minor changes to resources, but nothing that requires a resource replacement.

This post walks you through the changes between AWS CDK v1 and v2.

The AWS Construct Library now comes in a single package

In AWS CDK v1, we were very careful to partition the AWS Construct Library into many small packages, one per service, so that you only needed to download the packages for those services you wanted to use.

The downside of this approach was that every time you wanted to add a new AWS service to your application, you had to go back to your terminal to npm install or pip install another package. Additionally, if you were using NPM, it was very important that all these packages were the exact same version, otherwise NPM might install multiple copies of some of the libraries, which then wouldn’t interoperate properly. We have heard feedback from customers telling us how hard it was to manage the dependency on AWS CDK correctly.

Starting in v2, we have consolidated all of the AWS Construct Library into a single package, called aws-cdk-lib. You get access to all the AWS CDK constructs by installing this package, and third-party construct libraries only need to take a dependency on this package as well.

We also extracted the constructs programming model into a separate library, called constructs. This is the basis for a bigger ecosystem of interoperable construct libraries, and is already being used by sister projects like cdk8s and terraform-cdk.

For more information about the design choices for v2, see the RFC in our GitHub repo.

Removal of the construct compatibility layer

As part of our effort to broaden the applicability of the AWS CDK programming model to other domains such as Kubernetes, we extracted the base Construct class (and a few related types) from the AWS CDK to an independent library called constructs.

If you’re defining your own construct or using any of the related APIs, you now have to make code changes to use the constructs library.

After you declare this library as a new dependency, in most cases you just need to adjust your import statements to use the new classes. Most of the class and method names have been retained, and should make this easy to migrate.

If you’re using advanced AWS CDK features such as hooking into the AWS CDK app lifecycle, more changes are required to achieve this. All of the details are available in the relevant release notes.

New lifecycle for experimental APIs

We’re also introducing changes to how we handle experimental classes, methods, and properties starting in v2.

In v1, we followed semantic versioning for all non-experimental code, but where APIs were marked as experimental, we reserved the right to make breaking changes when we felt that the APIs could be improved significantly. Although this gave us the benefit of easily adapting the APIs, customers were sometimes caught off guard by the changes when they didn’t notice the experimental banner on a package, or they simply chose to deploy production stacks with the experiments due to their perceived stability and general level of usefulness.

In AWS CDK v2, we no longer make intentional breaking changes to any APIs in minor version releases. Instead, we’re introducing a new lifecycle in which new, experimental construct libraries go through an incubation period as a library completely independent from the main aws-cdk-lib library. The packages are distributed with a name clearly indicating their experimental status, like @aws-cdk-experiments/aws-xxx, and are versioned with a version number 0.x to clearly indicate their pre-release status. Only after the new package has matured and has been put through its paces in several real-world scenarios will we include it into aws-cdk-lib as a stable module.

This means that every method, class, and property in aws-cdk-lib is guaranteed to exist until the next major version update, and you can update to new minor versions at any time without having to touch your code.

You can read about our thinking on some of the options we considered to make this transition in the GitHub repo.

For the Developer Preview release, the higher-level constructs (L2s) for experimental packages are removed from aws-cdk-lib, but they aren’t available separately yet. The AWS CloudFormation (L1) classes are included as usual. We know that a lot of work has been put into building and maintaining the experimental L2s, by both the community and the core team, and we’re working hard to get them released separately soon.

Deprecated APIs are removed

Since releasing CDK v1, we have fixed a number of bugs and defects in our code. As part of this effort, we have deprecated a number of symbols—classes, properties, and methods—and have provided better replacements for them.

As part of our cleanup efforts for CDK v2, these deprecated symbols are removed entirely. If you’re still using any of the deprecated APIs, you have to update your AWS CDK applications and libraries to switch to the replacement versions.

AWS CDK already used standard language facilities for reporting deprecated APIs, so you may have already noticed APIs getting deprecated as you were working with the code: identifiers have a strike-through decoration, or the deprecations have shown up in your IDE’s list of warnings. If so, great! You don’t need to do anything about this when migrating to v2.

If you haven’t touched your code in a while or are using Python (which doesn’t have deprecation reporting in the IDE), we will soon release an update to the AWS CDK CLI that warns you about the usage of deprecated APIs during the cdk synth operation, so you can confirm that you’re not using any deprecated APIs before upgrading.

Feature flags: New behavior becomes the default

In AWS CDK v1, we introduced the concept of feature flags. This allowed us to ship bug fixes and improvements to the AWS CDK without changing the behavior of your AWS CDK application in incompatible ways. This allowed new AWS CDK apps to get our updated behavior, while existing AWS CDK apps can opt in to the feature flags as needed. The complete list of feature flags is documented on GitHub.

In AWS CDK v2, new and existing apps that are migrated to v2 have all the feature flags enabled. In most cases, it’s not possible to revert any of the features to their old behavior, but in cases where it’s impossible to upgrade to v2 without causing interruption or downtime to your AWS application, we have made it possible to revert to the old behavior. If you’re migrating your AWS CDK application from v1 to v2, we recommend that you run the cdk diff command and see how this may impact your application.

New bootstrapping resources become the default

In the course of building support for continuous deployments of AWS CDK applications to multiple AWS accounts, we changed the bootstrap resources that AWS CDK creates for you.

In v1, creating the new bootstrap resources and using them was optional and enabled via a feature flag in cdk.json (namely @aws-cdk/core:newStyleStackSynthesis).

In v2, the new bootstrapping resources have become the default, and your stack templates will change slightly to take advantage of those new resources. The biggest changes are:

  • Assets no longer take up parameters in your CloudFormation template, so you can use as many assets as you want without being limited by the 50 parameter limit of CloudFormation templates.
  • Cross-account deployments are supported out of the box, so you can use credentials from one AWS account to assume a role and deploy an AWS CDK app into another account (assuming the right trust relationship has been set up between the accounts).
  • The bootstrap resources now also contain an Amazon Elastic Container Registry (Amazon ECR) repository in which all asset images are pushed. This is opposed to them being pushed to a separate Amazon ECR repository per asset.

Because all AWS CDK applications written with AWS CDK v2 expect the new bootstrap resources to be available, if you haven’t already manually opted into the new bootstrap resources via the feature flag we mentioned, you have to re-bootstrap all your AWS accounts and Regions once by running cdk bootstrap with the v2 AWS CDK CLI.

Migration from v1 to v2

If you have an existing AWS CDK application that you want to upgrade to v2, the migration process for your code is as follows:

  1. Update your package dependencies to depend on the new aws-cdk-lib and constructs libraries.
  2. Run your package manager to download the new dependencies.
  3. Change your import statements (the core AWS CDK classes have moved to the root AWS CDK namespace in all languages, and Construct has moved to a different namespace).
  4. Remove all feature flags from the context object in cdk.json.
  5. After you update your application code, install version 2 of the AWS CDK CLI by running npm install -g aws-cdk@2.0.0-rc.1.
  6. Re-bootstrap your application environments by running cdk bootstrap.

Apart from the core classes, we have kept the AWS Construct Library names the same in most cases, so you shouldn’t expect this to cause disruptive resource replacements in your stacks. The following sections contain a description of what the changes look like for every language.

Typescript

For AWS CDK applications written in TypeScript, update your package.json file to look like the following code (don’t forget to move @aws-cdk/assert to the new version as well):

{
    "dependencies": {
        "aws-cdk-lib": "^2.0.0-rc.1",
        "@aws-cdk/assert": "^2.0.0-rc.1",
        "constructs": "^10.0.0"
     }
}

For construct libraries written in TypeScript, the package.json should look slightly different. You need to establish the lowest version of aws-cdk-lib you require for your application (let’s say that is 2.0.0-rc.1) and then update your package.json to look like the following code:

{
    "peerDependencies": {
    "aws-cdk-lib": "^2.0.0-rc.1",
    "constructs": "^10.0.0"
  },
   "devDependencies": {
    "aws-cdk-lib": "2.0.0-rc.1",  // <-- note: no ^ to make sure we test against the minimum version
    "@aws-cdk/assert": ^2.0.0-rc1.1",
    "constructs": "^10.0.0",
    "typescript": "~3.9.0"
  }  
}

Install the new dependencies by running the following:

npm install
# or
yarn install

Change your imports to look like the following:

import { Construct }  from 'constructs';
import { App, Stack, aws_s3 as s3 } from 'aws-cdk-lib';

Python

For AWS CDK applications written in Python, update your setup.py to look like the following:

install_requires=[
     "aws-cdk-lib>=2.0.0-rc1.1",
     "constructs>=10.0.0",
    # ...
]

Install the new dependencies:

pip install -r requirements.txt

Remember to uninstall any other versions of AWS CDK via pip uninstall.

Change your imports to look like the following:

import constructs
import aws_cdk as cdk
from aws_cdk import aws_s3 as s3

Reference the classes as follows:

class MyConstruct(constructs.Construct):
      # ...

class MyStack(cdk.Stack):
      # ...

s3.Bucket(...)

Java

In the pom.xml file, remove all software.amazon.awscdk dependencies and replace them with the following:

<dependency>
        <groupId>software.amazon.awscdk</groupId>
        <artifactId>aws-cdk-lib</artifactId>
        <version>2.0.0-rc.1</version>
</dependency>
<dependency>
       <groupId>software.constructs</groupId>
       <artifactId>constructs</artifactId>
       <version>10.0.0</version>
</dependency>

Install the new dependencies:

mvn package

Change your imports to look like the following:

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.App;
import software.amazon.awscdk.services.s3.Bucket;

.NET

In the .csproj file, remove all Amazon.CDK.* references and replace them with the following:

<PackageReference Include="Amazon.CDK.Lib" Version="2.0.0-rc.1" />
<PackageReference Include="Constructs" Version="10.0.0" />

Install the new dependencies:

dotnet restore

Change your imports to look like the following:

using Constructs;
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

Changes to cdk.json

These changes apply to all languages.

Remove all feature flags from cdk.json, because all feature flags created for v1 are now enabled by default. Only three of those feature flags can be disabled to revert back to the v1 behavior:

  • If your application uses multiple Amazon API Gateway API keys and associates them to usage plans (only for the module @aws-cdk/aws-apigateway), use @aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId.
  • If your application uses an Amazon Relational Database Service (Amazon RDS) DB instance or DB clusters, and explicitly specifies the identifier for these, use @aws-cdk/aws-rds:lowercaseDbIdentifier.
  • If your application uses multiple stacks and if they refer to resources from one stack to the other, use the AWS CloudFormation export functionality: @aws-cdk/core:stackRelativeExports.

You can disable these feature flags in your cdk.json with the following code:

{
   "context": {
     "@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
     "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
     "@aws-cdk/core:stackRelativeExports": false,
   }
}

Use the cdk diff command to inspect changes to your templates to see if any of these flags need to be disabled.

Unexpected changes to synthesized infrastructure

When you run the cdk diff command to inspect changes that CDK will make, you may notice unexpected changes to your templates. These changes are the result of deprecated behavior being replaced by functionality that was previously hidden by feature flags.

These changes are probably not due to upgrading to v2, but due to upgrading from an older version of CDK. You will also see them when upgrading to the latest minor version in v1. If you are on an older 1.x version, try upgrading to a recent 1.x version first, synthesize and deploy your application, and then proceed with the v2 upgrade.

If you run into a situation where you cannot deploy your stacks because of the difference between your v1 and v2-synthesized infrastructure, and it is not covered by one of the feature flags discussed in the previous section, please let us know on GitHub.

Summary

Although AWS CDK v2 isn’t a major change in design, it makes managing package versions easier and allows you to update to newer versions of the AWS CDK on a regular cadence. For more information, refer to the v2 developer guide and the v2 API reference. As always, we welcome bug reports, feature requests, and pull requests on the aws-cdk GitHub repository.

<3 the AWS CDK team