[Virtual Event] IaCConf Spotlight: Designing IaC Interfaces | July 14

Register Now ➡️

AWS

AWS Cloud Development Kit (CDK) vs. Terraform

aws cdk vs terraform

In this post we will compare two very different tools for infrastructure as code (IaC): AWS Cloud Development Kit and HashiCorp Terraform.

How do Terraform and CDK differ? AWS CDK is an open-source framework that defines AWS infrastructure imperatively in a general-purpose programming language, then synthesizes it to CloudFormation. Terraform manages infrastructure declaratively in HCL across AWS, Azure, Google Cloud, and 4,000+ other providers. 

Choose CDK when you build entirely on AWS and want to write infrastructure in the language your team already uses. Choose Terraform when your infrastructure spans more than one platform and you want a single workflow for all of it.

What we will cover:

  1. What is Infrastructure as Code?
  2. What is AWS CDK?
  3. What is Terraform?
  4. AWS CDK vs. Terraform table comparison
  5. Differences between CDK and Terraform
  6. Which is better, CDK or Terraform?

How we compared these platforms

We aim to make our recommendations practical and vendor-neutral. We based this comparison on each vendor’s public documentation and pricing pages, hands-on experience using both tools, and the dimensions that matter most in practice.

What is infrastructure as code?

Infrastructure as code (IaC) is the practice of defining your infrastructure (your virtual networks, Kubernetes clusters, DNS records, and more) in a configuration language, a Bash script, or even using a proper programming language.

You configure your cloud infrastructure in code, you apply it, and then your infrastructure comes to life. This contrasts starkly with a manual approach of clicking your way through a graphical user interface to create the resources your applications depend on.

diagram showing how infrastructure as code works

In the world of IaC, there are two distinct types: declarative and imperative.

Declarative IaC is all about the destination. The code you write describes the desired end state. The order of the code blocks does not matter. What matters is how infrastructure resources are related to one another and how those relationships are expressed. 

From the expression of these relationships, the IaC tool can form a DAG (Directed Acyclic Graph) which determines the order in which resources are created. Failing to properly specify an existing relationship between two resources generally leads to an error. In this blog post, we will look at Terraform, an early player in the world of declarative IaC.

Imperative IaC takes the journey to the destination into account. The code you write follows steps in a certain order. Shifting blocks of code around would generally mean these steps are performed in the wrong order, which would break the code. In this blog post, we will look at AWS CDK, an example of imperative IaC.

These benefits are common to all types of IaC:

  • Write code once, apply it many times. You can create repeatable modules of infrastructure that work the same way each time you apply it.
  • Keeping your IaC under source control gives you an audit trail of all changes made throughout your infrastructure’s lifecycle.
  • Changes to your infrastructure follow the same workflow as application code. You can build and test your code and use the same peer-review process as for the rest of your application code.
  • Your infrastructure code documents the infrastructure underlying your applications. This documentation is always up to date, unlike a diagram in a wiki.

Read more: Business Benefits of Infrastructure as Code

What is AWS CDK?

AWS CDK is an evolution of AWS CloudFormation, the original tool for IaC on AWS. You can use a few different languages for AWS CDK:

  • JavaScript
  • TypeScript
  • Python
  • Java
  • C#
  • Go

There is no functional difference between the different languages, so your choice of language does not limit your features. Under the hood, AWS CDK uses a tool named jsii. It allows for class libraries written in JavaScript/TypeScript to be used from other languages, enabling the AWS CDK team to provide many languages with the same functionality.

AWS CDK uses the imperative approach to IaC. However, the purpose of the AWS CDK code is to generate AWS CloudFormation templates. 

AWS CDK features

  • Programmatic code: AWS CDK uses familiar programming languages to define cloud infrastructure.
  • Constructs: The CDK introduces constructs, which are pre-configured cloud components that can be composed to build higher-level abstractions, improving code reuse and modularity.
  • Imperative control: Unlike declarative IaC tools, CDK allows conditional logic, loops, and complex control flows to be used in code, giving developers flexibility and power in infrastructure definitions.
  • CloudFormation compatibility: CDK translates high-level constructs into CloudFormation templates, providing the power and reliability of CloudFormation with the flexibility of programming languages.
  • Built-in validation: CDK provides automatic checks and validations during synthesis, helping catch configuration errors early, ensuring smoother deployments, and minimizing runtime failures.

How does AWS CDK work?

To get started with AWS CDK you need a few prerequisites. The exact requirements depend on what language you plan on using for AWS CDK. See the AWS documentation for all the relevant details for the language you choose. For the following demonstration, Go will be the language of choice.

You can create a new AWS CDK project using the app project template through the following CDK CLI command:

$ cdk init app --language go
Applying project template app for go
(details omitted)Initializing a new git repository...
✅ All done!

Infrastructure in AWS CDK comes in the form of stacks, the same concept as an AWS CloudFormation stack. This is how the state of your infrastructure is maintained. An AWS CDK application can consist of one or many stacks. The app template we initialized consists of a single stack.

The stack is initialized in the main function:

func main() {
    // details left out for brevity ...

    NewNetworkStack(app, "NetworkStack", &NetworkStackProps{
        awscdk.StackProps{
            Env: env(),
	   },
    })

    // details left out for brevity ...
}

Part of the stack initialization takes a definition of an environment. An environment comprises the appropriate AWS account and AWS region. You can target different AWS environments in the same CDK application.

The stack content is defined in the NewNetworkStack function. The boilerplate code for this function is:

func NewNetworkStack(...) awscdk.Stack {
    var sprops awscdk.StackProps
    if props != nil {
        sprops = props.StackProps
    }
    stack := awscdk.NewStack(scope, &id, &sprops)

    // your infrastructure goes here

    return stack
}

The NewNetworkStack function is where you define the infrastructure that goes into your stack. Our goal is to create a VPC with related resources, so we must import the EC2 package because this is where the VPC resources live:

import (
  // other packages omitted for brevity ...
  ec2 "github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
)

You should run the following command to download all the required packages your application is referencing:

$ go mod tidy

With the EC2 package imported, we can configure the VPC resource:

// in the NewNetworkStack function
ec2.NewVpc(stack, jsii.String("vpc"), &ec2.VpcProps{})

By default, the NewVpc function will create a VPC with a public and private subnet in each of the selected AWS region’s availability zones, along with an internet gateway, NAT gateways, route tables, routes, and more. That single line of code does a lot of work!

The code you write with AWS CDK is synthesized into AWS CloudFormation templates. The resulting CloudFormation templates are then finally deployed to your AWS environment using CloudFormation as the deployment engine. 

Does that mean that AWS CDK is bound by all the limitations of the underlying CloudFormation framework? Not exactly. 

AWS CDK has some limitations, but it can go beyond AWS CloudFormation in some ways. This is usually done by using custom AWS Lambda functions that perform required tasks during deployment.

We can synthesize the AWS CDK code to a CloudFormation template in our terminal if we wish to see what the end result will be:

$ cdk synth
Resources:
  vpcA2121C38:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      # the rest of the template is omitted for brevity

If you examine the resulting CloudFormation template, you see that the single line of CDK code created a lot of CloudFormation code.

To deploy the resources with AWS CDK, run the deploy command:

$ cdk deploy

You must approve any IAM permissions, network port openings, and similar sensitive changes by answering y (yes) in a prompt. After accepting the coming changes, AWS CDK sends the synthesized CloudFormation templates up to AWS and streams the stack creation status to your terminal.

The deployment finishes eventually:

NetworkStack: deploying... [1/1]
NetworkStack: creating CloudFormation changeset...

 ✅  NetworkStack

✨  Deployment time: 152.43s

Stack ARN:
arn:aws:cloudformation:eu-west-1:<account id>:stack/NetworkStack/<stack id>

✨  Total time: 154.79s

You can delete the stack using the destroy command and replying y (yes) at the prompt:

$ cdk destroy
Are you sure you want to delete: NetworkStack (y/n)? y

Resources in AWS CDK are called constructs. Different types of construct have different abstraction levels:

  • The lowest level of construct is a direct mapping from the underlying CloudFormation resources.
  • An example of the highest level of construct is ApplicationLoadBalancedFargateService, this construct represents a large collection of underlying resources that are configured to create an ECS Fargate cluster with an Application Load Balancer (ALB).
  • Most constructs are somewhere in between. An example is the Vpc resource.

Most constructs have sensible default values, which means that you often do not have to configure many settings to get a working resource. We saw this above for the VPC resource.

If you like these types of abstractions, then the CDK is a good choice.

What is Terraform?

Terraform is an infrastructure provisioning tool that allows users to manage infrastructure across multiple cloud platforms (like AWS, Microsoft Azure, Google Cloud Platform, and other cloud providers) using a declarative configuration language called HCL to define the infrastructure.

It emerged from the idea of creating a “CloudFormation for everything” during the very early days of HashiCorp, the organization behind Terraform. The idea of using a single tool to create infrastructure spanning multiple target platforms (cloud providers, on-premise infrastructure, SaaS products, and more) is mesmerizing.

Terraform features

  • Provider ecosystem: To get started with Terraform, you have to download a single binary for your system architecture. However, before you can do anything, you also need providers. The Terraform binary is the core. It does many things (like parsing the language and orchestrating the work of the providers). 

The providers are the plugins that allow Terraform to work with a target system (e.g., AWS). The AWS provider for Terraform is arguably the most successful provider for Terraform ever, with over 6.5 billion downloads at the time of writing.

  • Declarative code: Terraform code is written in the HashiCorp Configuration Language (HCL). This domain-specific language is used in many tools in the HashiCorp suite. It is relatively easy to learn and has many features that make it easy to work with compared to traditional JSON or YAML configuration languages.

However, you can also write Terraform configurations using JSON. JSON is a good choice for code intended to be read programmatically, but it is less suited for human interaction. For that, HCL is a better choice.

  • State management: Terraform maintains a state file that represents the current state of the infrastructure. This state allows Terraform to track resource changes, identify what needs to be updated, and perform diffs during deployment.
  • Modular infrastructure: Terraform supports the creation of reusable modules, which allow users to package and share sets of resources, improving code reusability and enabling consistent deployment patterns across projects.

How does Terraform work?

In the previous section, we saw how we can create a fully configured AWS VPC with a single line of Go code using AWS CDK. In the following paragraphs, we will create the corresponding infrastructure in Terraform, and we will see that we need a lot more than a single line to do it.

We begin by specifying the Terraform provider our configuration needs (AWS), as well as configuring the provider. 

This is a similar step to importing packages into an AWS CDK application. If we want to target multiple AWS environments (either accounts or regions), we must configure the AWS provider multiple times.

terraform {
  required_providers { 
    aws = {
      source = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

variable "aws_region" {
  type    = string
  default = "eu-west-1"
}

provider "aws" {
  region = var.aws_region
}

Next, we create the VPC resource and an internet gateway attached to this VPC:

resource "aws_vpc" "this" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "spacelift-${var.aws_region}"
  }
}

resource "aws_internet_gateway" "this" {
  vpc_id = aws_vpc.this.id
  tags = {
    Name = "spacelift-${var.aws_region}"
  }
}

The internet gateway resource is used to route traffic to and from the internet.

We want to create one public and one private subnet for each availability zone in the selected region. So we must have a way to find the availability zones for our selected region. This can be done using the availability zones data source:

data "aws_availability_zones" "all" {}

Now we can create the subnets, both public and private:

resource "aws_subnet" "public" {
  count      = length(data.aws_availability_zones.all.names)
  vpc_id     = aws_vpc.this.id
  cidr_block = cidrsubnet(aws_vpc.this.cidr_block, 8, count.index)

  availability_zone = data.aws_availability_zones.all.names[count.index]

  tags = {
    Name = "spacelift-${var.aws_region}-public-${count.index}"
  }
}

resource "aws_subnet" "private" {
  count      = length(data.aws_availability_zones.all.names)
  vpc_id     = aws_vpc.this.id
  cidr_block = cidrsubnet(aws_vpc.this.cidr_block, 8, 128 + count.index)

  availability_zone = data.aws_availability_zones.all.names[count.index]

  tags = {
    Name = "spacelift-${var.aws_region}-private-${count.index}"
  }
}

The difference between a public and a private subnet is whether there is a direct route to the internet. These details are configured in route tables attached to the subnets.

Resources in the private subnets must still be able to reach the internet, but the routing goes via Network Address Translation (NAT) gateways. We can create the NAT gateways with corresponding elastic IP addresses:

resource "aws_eip" "natgw" {
  count = length(data.aws_availability_zones.all.names)
  tags = {
    Name = "spacelift-${var.aws_region}-${count.index}"
  }
}

resource "aws_nat_gateway" "all" {
  count         = length(data.aws_availability_zones.all.names)
  subnet_id     = aws_subnet.public[count.index].id
  allocation_id = aws_eip.natgw[count.index].id
  tags = {
    Name = "spacelift-${var.aws_region}-${count.index}"
  }
}

We need route tables for both public and private subnets and must attach them to each of the subnets. We start with the public route table, which can be reused for each public subnet. The public route table has a single route, sending all traffic to the internet via the internet gateway.

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.this.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.this.id
  }

  tags = {
    Name = "spacelift-${var.aws_region}-public"
  }
}

resource "aws_route_table_association" "public" {
  count          = length(data.aws_availability_zones.all.names)
  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}

The association between a route table and a subnet is created as a separate resource.

For the private subnets, we want to route all traffic via NAT Gateways. Routing traffic in the same availability zone means that each private subnet must have its own route table that uses the NAT gateway in the same availability zone as the subnet.

resource "aws_route_table" "private" {
  count  = length(data.aws_availability_zones.all.names)
  vpc_id = aws_vpc.this.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.all[count.index].id
  }

  tags = {
    Name = "spacelift-${var.aws_region}-private-${count.index}"
  }
}

resource "aws_route_table_association" "private" {
  count          = length(data.aws_availability_zones.all.names)
  subnet_id      = aws_subnet.private[count.index].id
  route_table_id = aws_route_table.private[count.index].id
}

That was it. If you have never worked with Terraform or AWS before, you now know you need deep knowledge of how the underlying VPC resources in AWS work to succeed in setting this up. 

You do not always have to build the full infrastructure from scratch. There is a large library of available modules you can use.

We could have replaced all the infrastructure defined above with the AWS VPC module. However, we still need to configure the module with a few inputs, such as the names of the availability zones we want to use and CIDR ranges for all public and private subnets.

locals {
  vpc_cidr = "10.0.0.0/16"
  azs      = length(data.aws_availability_zones.all.names)
  public_cidrs = [
    for i in range(local.azs) : cidrsubnet(local.vpc_cidr, 8, i)
  ]
  private_cidrs = [
    for i in range(local.azs) : cidrsubnet(local.vpc_cidr, 8, 128 + i)
  ]
}

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.21.1"

  cidr            = local.vpc_cidr
  azs             = data.aws_availability_zones.all.names
  private_subnets = local.private_cidrs
  public_subnets  = local.public_cidrs

  enable_nat_gateway = true

  tags = {
    Name = "spacelift"
  }
}

To create the resources (either using the explicit resources we created above or using the VPC module) with Terraform, you must first initialize the configuration:

$ terraform init

The initialization command downloads the required provider binaries. This is similar to downloading the required packages for an AWS CDK application. Next, you can run a plan operation to have Terraform tell you what will happen if you apply the configuration:

$ terraform plan

Finally, you apply the configuration:

$ terraform apply

The operation takes one to two minutes to complete.

Once you are satisfied with your testing, you can destroy the resources using the destroy command:

$ terraform destroy

Although this is a small, simple infrastructure, we have learned a little about what makes up a Terraform configuration and how the Terraform workflow works.

We defined many relationships between different resources in the configuration. If we fail to express these relationships correctly, we might end up in a situation where Terraform tries to create a resource that depends on a different resource that has not been created yet.

Errors like these are not always apparent before you try to apply the configuration. Although AWS CDK is not immune to these types of problems, they are usually more easily avoided when you write the code in a certain order and build the infrastructure successively.

AWS CDK vs. Terraform table comparison

The following table provides a high-level overview of the technical differences between AWS CDK and Terraform.

AWS CDK Terraform
Type of infrastructure as code Imperative Declarative
Languages TypeScript, JavaScript, Python, Java, C#, Go HCL, JSON
Target provider(s) AWS AWS, Azure, GCP, and 1000+ other providers
License AWS CDK and related ecosystem is open-source Terraform moved to the Business Source License (BSL) starting with version 1.6, which makes it source-available rather than open source. The 1.5.x line and earlier remain open source under MPL 2.0.
Executable CDK CLI (runs on Node.js), synthesizes code to CloudFormation templates Terraform CLI binary together with any provider binaries (e.g., AWS)
Execution mode CDK to CloudFormation generation is local, but CloudFormation execution is remote in AWS Terraform runs where you use the Terraform binary, most likely your local system, a remote CI/CD platform, or SaaS (e.g., Spacelift)
State management AWS CloudFormation stacks JSON formatted state file stored in a state backend (e.g., an AWS S3 bucket)

Differences between AWS CDK and Terraform

Apart from the technical differences, there are a few other important areas to consider. The following subsections cover these.

1. Existing technical expertise

Your organization probably already has one or more areas of technical expertise. AWS CDK offers a smoother learning curve for developers familiar with its supported programming languages. If most of your applications are written using the .NET/C# ecosystem, or another language available in AWS CDK, then you will have an advantage when using the CDK in that same language.

Learning a new framework and language can be a challenge. This depends on your preexisting skills, the size of your organization, and the available budget for training. It is also a question of priority and balancing learning with daily work.

2. Infrastructure footprint

Your existing infrastructure footprint should also influence your decision.

Unless your organization is at a very early stage of the cloud journey, you probably have considerable existing infrastructure. Perhaps you have already used either AWS CDK or Terraform for much of your infrastructure.

This is a good position to be in because you will likely have had good or bad experiences with either framework. When starting a new project, you have the chance to reevaluate your previous choice and either try something new or expand your use of your chosen framework.

3. Developer experience

Since the DevOps movement has merged traditional developer tasks with traditional operations tasks, developers are no longer expected to only write application code. Developers coming from an application background will probably prefer the imperative approach using AWS CDK in their favorite language.

Modern IDEs generally provide far better support for traditional programming languages than for configuration languages such as HCL or JSON. This is especially true for statically typed languages such as Go. However, this can vary from IDE to IDE.

The surrounding ecosystem for traditional programming languages is usually far more evolved. If you need to do a lot of string manipulations, filesystem I/O operations, or any other complex data processing as part of your IaC, you will likely have better support and an easier time using the ecosystem for one of the languages in the AWS CDK.

4. Use case

When it comes to use cases, there is one clear difference between the two tools:

  • AWS CDK targets the AWS ecosystem.
  • Terraform can target any system with an existing Terraform provider. You can also extend it to target custom systems by building your own providers.

This means that if your infrastructure spans multiple clouds, on-premise infrastructure, or third-party SaaS platforms, you will be more successful using Terraform. In this case, Terraform allows you to have a single workflow for all of your infrastructure, no matter what it is.

Even if your organization is using AWS as its sole cloud provider, chances are you are using other external systems that Terraform could work with. For example, you may be using a different DNS provider to Amazon Route53 or a different CDN solution to Amazon CloudFront.

However, if all or most of your infrastructure is on AWS, CDK could be a better choice. Even if this means you need a different tool to automate the remaining infrastructure.

Which is better, CDK or Terraform?

Both tools provision real infrastructure reliably, so “better” depends on your environment rather than the tool itself. AWS CDK is the stronger choice for AWS-focused, developer-driven teams that want code reuse and flexibility within a single cloud. Terraform is the stronger choice for teams managing multicloud infrastructure, thanks to its mature ecosystem, broad cloud compatibility, and state management.

Choose AWS CDK when your infrastructure is entirely on AWS, your team is comfortable in a supported programming language, and you want loops, conditionals, and code reuse in your infrastructure definitions.

Choose Terraform when your infrastructure spans multiple clouds, on-premises systems, or third-party SaaS, when you want one declarative workflow across all of it, and when you want the largest provider ecosystem and a mature state model.

In the end, to make an informed decision, you need to consider all your application requirements, workforce skill sets, current cloud environment, technical requirements, license concerns, and more.

Note: Terraform 1.6 and later are released under the BSL. The 1.5.x line and everything before it remain open source under MPL 2.0. OpenTofu is the open-source fork created from that final 1.5.x release. It is now a CNCF project under the Linux Foundation, with v1.12 as the current stable release, and it stays compatible with the Terraform provider ecosystem. Following IBM’s acquisition of HashiCorp, Terraform is now an IBM product.

Manage CDK and Terraform in one place with Spacelift

Spacelift is an infrastructure orchestration platform that increases your deployment speed without giving up control. It runs Terraform, OpenTofu, Terragrunt, Pulumi, CloudFormation, Ansible, and Kubernetes through one or more automated workflows, so the tool you pick in this comparison is never a dead end.

You don’t need to define all the prerequisite steps for installing and configuring the infrastructure tool you are using, nor the deployment and security steps, as they are all available in the default workflow.

With Spacelift, you get:

  • Policy as code (based on Open Policy Agent) to control approvals, which resources teams can create, and what happens when a pull request opens or merges.
  • Multi-IaC workflows that combine Terraform with Kubernetes, Ansible, Pulumi, CloudFormation, and others, with dependencies and shared outputs between them.
  • Self-service infrastructure through Templates and Blueprints, so developers provision approved infrastructure from a form without writing IaC.
  • Integrations with any third-party tools – You can integrate with your favorite third-party tools and even build policies for them. For example, see how to Integrate security tools in your workflows using Custom Inputs.
  • Creature comforts such as contexts (reusable containers for your environment variables, files, and hooks), and the ability to run arbitrary code.
  • Drift detection with optional remediation, so production stays the way you defined it.

With Spacelift Intent, developers describe what they need in plain language and Spacelift provisions it through cloud provider APIs, with the same policies, credentials, and audit trail as the IaC path.

If you want to learn more about what you can do with Spacelift, check out this article or book a demo with our engineering team to discuss your options in more detail. 

Key points

In short, AWS CDK lets you define AWS infrastructure with code in general-purpose languages, while Terraform uses HCL for declarative, cloud-agnostic provisioning, ideal for multi-cloud setups.

aws cdk vs terraform table comparison

This post has explored the differences between AWS CDK and Terraform. Here are some key points:

  • IaC comes in two distinct types: imperative and declarative.
  • Declarative IaC defines the desired end state, focusing on how different pieces of infrastructure relate to one another. The IaC tool makes the desired state a reality.
  • Imperative IaC defines the steps needed to get to the desired state.
  • AWS CDK is an example of an imperative IaC tool. You can write code in several languages (TypeScript, JavaScript, Python, Java, C#, Go). You can use the full ecosystem of packages and tools for your chosen language. CDK code is synthesized to CloudFormation templates that are then deployed on AWS.
  • Terraform is an example of a declarative IaC tool that works with multiple cloud providers. Terraform code is written in HCL or JSON. Its strength lies in its multicloud support, not just AWS integration.
  • Technical differences between AWS CDK and Terraform include the language you use and how the state information is stored. You should also consider other differences that could be important in your context, including your current engineering skill set, your current infrastructure footprint, license, and, most of all, what use case you are applying the framework for.

Terraform management made easy

Orchestrate Terraform workflows with policy as code, programmatic configuration, context sharing, drift detection, resource visualization, and more.

Learn more

Frequently asked questions

  • What is the Terraform plan equivalent in CDK?

    The Terraform plan command is roughly equivalent to cdk diff in the AWS Cloud Development Kit (CDK). terraform plan compares your configuration to state, while cdk diff compares the synthesized template to the currently deployed CloudFormation stack to show proposed changes without applying them.

  • When to use CDK and when Terraform?

    Choose CDK for AWS-native, developer-first environments. Choose Terraform for multi-cloud, team-scale operations requiring consistent infrastructure management.

  • What is the difference between Terraform, Pulumi, and AWS CDK?

    The key difference lies in their approach: Terraform is declarative and cloud-neutral, Pulumi uses general purpose languages but remains declarative and cloud-neutral, and AWS CDK is AWS-specific with strong integration into the AWS platform.

  • Does AWS CDK replace CloudFormation?

    No. CDK sits on top of CloudFormation. Your CDK code is synthesized into CloudFormation templates, and CloudFormation remains the deployment engine.

The Practitioner’s Guide to Scaling Infrastructure as Code

Transform your IaC management to scale

securely, efficiently, and productively

into the future.

ebook global banner
Share your data and download the guide