AWS CDK Construct Levels: How do L1, L2, and L3 Construct Types Differ?

AWS CDK Construct Levels

If you tried learning AWS CDK, you might have realized that three levels of CDK construct types exist when defining an AWS resource: L1, L2, and L3 (also called ‘CDK patterns’). So, deciding which CDK construct level to choose may become confusing. Sometimes, a resource’s different construct classes are even named similarly. Then, are there any advantages you get by choosing one over another?

You aren’t alone if you feel the same. This was also what I felt while learning AWS CDK. So, in this post, I will discuss AWS CDK construct levels to help you understand their differences.

I thoroughly cover them with hands-on examples in my AWS CDK with Python Step by Step course. Still, this post will be a nice addition as a summary of these crucial AWS CDK concepts.

How does AWS CDK work?

Before discussing AWS CDK constructs, let’s first understand how AWS CDK works.

AWS Cloud Development Kit (CDK) is an infrastructure code tool of AWS like AWS CloudFormation. However, instead of JSON or YAML templates of CloudFormation, you write AWS CDK code with supported common programming languages like Python, Java, JavaScript, etc. So, you can benefit from their object-oriented features.

However, AWS CDK still depends on AWS CloudFormation during the deployment. AWS CDK synthesizes CloudFormation templates from your CDK code and deploys them as CloudFormation stacks. So, everything is converted to its CloudFormation counterpart.

AWS CDK has three primary components:

  • CDK apps, the top-level component of your CDK project containing all stacks.
  • CDK stacks that correspond to CloudFormation stacks.
  • CDK constructs, representing your resources in CDK stacks.

The last one is the topic of this blog post. So, let’s start discussing CDK constructs.

What are AWS CDK Constructs?

Constructs are the basic building blocks of AWS CDK. Technically, CDK apps and stacks are also special types of CDK constructs. However, we primarily use the term ‘constructs’ to refer to AWS resources or solutions in your CDK stacks.

CDK constructs are classes in the object-oriented language supported by CDK for which you created your project. For example, if you use Python, they are Python classes. Their contents depend on the level of their construct type. They may correspond to a single AWS resource, a few AWS resources around a central AWS resource, or a complete solution with multiple resources.

These levels are named L1, L2, and L3, according to their levels in the CDK construct hierarchy. So, let’s also discuss each construct type from the lowest to the highest level.

L1 Constructs: Using AWS CDK like AWS CloudFormation

L1 Constructs are the lowest-level constructs in the CDK construct hierarchy. In the CDK Construct Library, they start with Cfn, the short form for CloudFormation. It’s because each L1 construct corresponds to an AWS CloudFormation resource type. So, CDK uses L1 constructs while converting the AWS resource definitions in your programming language to the CloudFormation syntax in JSON.

When a new AWS resource is supported by AWS CloudFormation, its L1 construct is automatically created on CDK from the CloudFormation specification. Hence, you can find an L1 construct for most resources even if no higher-level constructs are provided.

As CDK’s L1 constructs correspond to CloudFormation resource types, you can easily convert your existing AWS CloudFormation templates using only L1 constructs. However, you have to define each resource separately, as in CloudFormation. So, you don’t fully benefit from the AWS CDK if you only use L1 constructs.

L2 Constructs: First-class citizen AWS CDK constructs

L2 Constructs are the next-level construct classes that create AWS resources with their auxiliary resources with defaults according to the best practices. Unlike L1 constructs, they don’t start with the Cfn prefix in the CDK Construct Library.

For instance, let’s say you want to create a VPC. If you only use L1 constructs to create it, you must define all its sub-resources, subnets, route tables, etc., separately in your CDK stack. Otherwise, your VPC will be useless.

However, by only defining the L2-level Vpc construct, you can configure a complete VPC with public, private, or isolated subnets with all necessary sub-resources configured automatically. So, L2 constructs increase your efficiency by providing sensible defaults according to the best practices. You don’t have to know your resource type in detail to start.

With L2 constructs, you can configure additional resources related to your primary resource with method calls. For example, you can add a function URL to a Lambda function by calling its add_function_url() method. Similarly, you can grant a Lambda function read-level access to a DynamoDB table with a grant_read() method call on the DynamoDB table’s L2 construct.

L2 constructs provide many built-in features for configuring network connections, uploading assets to S3, etc. So, with L2 constructs, everything becomes more easily configurable and understandable with object-oriented patterns than with L1 constructs. But L2 constructs also utilize L1 constructs behind the scenes and are considered higher level as a result. Your L2 constructs become L1 constructs before being converted to the CloudFormation syntax.

L2 constructs can create multiple resources but are centered around a single resource, such as a VPC in our example or an AWS Lambda function. However, if you want to create a complete solution with L2 constructs, you will need multiple of them. For instance, you need L2-level Function and Table constructs as separate objects to create a complete AWS Lambda backend accessing a DynamoDB table. Instead, wouldn’t it be cool to have a single construct class for a complete solution for the same example? Then, it is time to discuss L3 constructs, or in other words, CDK patterns.

CDK Patterns (L3 Constructs): Compound CDK constructs shared as a package

L3 constructs are also called CDK patterns. They encapsulate multiple constructs to create a complete solution, like a Lambda backend accessing a DynamoDB table or an API Gateway API with a Lambda backend. CDK patterns are regarded as the highest-level CDK constructs because they configure L2 and L1 constructs behind the scenes.

CDK patterns are not included in the CDK Construct Library. You import CDK patterns to your CDK apps as separate libraries from the repository of the programming language you use. You can also share your custom CDK patterns by exporting them as libraries to the same repository.

Where can you find new CDK patterns to use in your CDK apps? Construct Hub is the central repository where you can search for CDK patterns from AWS teams and third-party providers. AWS Solutions teams also provide their patterns in their reference documentation. However, they are also included in the Construct Hub. So, Construct Hub is the usual place to look for a CDK pattern.

Which CDK construct level should you use?

AWS CDK’s primary advantage is the encapsulation it provides for your AWS resources with sensible defaults according to the best practices. So, the more you use construct classes to handle the mundane configuration tasks for you, the more you become efficient in writing infrastructure code with CDK. Still, let me provide a simple algorithm while choosing a CDK construct.

1) First, look at the Construct Hub to see if someone provided a CDK pattern similar to the AWS solution you aim to deploy. With a few tweaks, you may customize it for your needs and save a great deal of time.

2) If no CDK pattern fits your use case, use L2 constructs to benefit from their object-oriented features. They also do most of the heavy lifting for you by configuring sub-resources of your primary resource.

3) If you need a resource type without any L2 constructs, it probably has an L1 construct corresponding to its CloudFormation resource type. You will still be more efficient than CloudFormation because you can efficiently utilize control flow tools provided by your programming language, such as if-else statements, for and while loops, etc.

Would you like to learn AWS CDK with Python?

Words are good but are not as effective as demonstrating a concept with hands-on examples. So, if you want to learn AWS CDK and would love to use Python as the programming language, I will be happy to see you in my online course on Udemy: AWS CDK with Python Step by Step.

In this course, you will learn AWS CDK from the basics and understand the CDK constructs in detail. More importantly, you will learn to use the CDK Construct Library reference or Construct Hub to find a construct type needed for your project. We will also cover advanced CDK concepts like aspects and testing.

You can use the links in this post to join AWS CDK with Python Step by Step with special discounts.

You can also find our other courses on the Online Courses page.


AWS CDK constructs increase your efficiency with their object-oriented features while writing infrastructure code with your favorite programming language on AWS. However, different AWS CDK construct levels may be confusing at the beginning. So, in this post, I aimed to help you by briefly explaining the CDK construct levels and sharing my recommendations while using them.

Thanks for reading. I hope to see you in AWS CDK with Python Step by Step!


AWS CDK Construct Levels
Emre Yilmaz

AWS Consultant • Instructor • Founder @ Shikisoft