The cdk synth command doesn’t just show you the CloudFormation template; it’s the final, crucial step where your CDK code is translated into the declarative language CloudFormation understands.

Let’s see it in action. Imagine you have a simple CDK app that synthesizes a single S3 bucket.

# app.py
from aws_cdk import App, Stack
from constructs import Construct
from aws_cdk import aws_s3 as s3

class MyBucketStack(Stack):
    def __init__(self, scope: Construct, construct_id: str):
        super().__init__(scope, construct_id)

        s3.Bucket(self, "MySimpleBucket",
                  versioned=True,
                  removal_policy=s3.RemovalPolicy.DESTROY)

app = App()
MyBucketStack(app, "MyBucketStack")

When you run cdk synth MyBucketStack, the output is a JSON document representing the CloudFormation template. Here’s a snippet of what you’d see:

{
  "Resources": {
    "MySimpleBucketF4818B31": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "VersioningConfiguration": {
          "Status": "Enabled"
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete"
    },
    "CDKMetadata": {
      "Type": "AWS::CDK::Metadata",
      "Properties": {
        "Analytics": "allow",
        "Tool": "aws-cdk-lib.cxapi.CloudFormationStackSynthesizer, version:1.x.x, ignore:true"
      }
    }
  },
  "Parameters": {
    "BootstrapVersion": {
      "Type": "AWS::SSM::Parameter::Value<String>",
      "Default": "/cdk-bootstrap/hnb659ef3.1.0:bootstrap-version",
      "Description": "Version of the CDK Bootstrap resources in this account and region."
    }
  },
  "Rules": {
    "CheckBootstrapVersion": {
      "Assertions": [
        {
          "Assert": {
            "Fn::Equal": [
              {
                "Ref": "BootstrapVersion"
              },
              "1"
            ]
          },
          "Description": "The AWS CDK Bootstrap version in this account is not compatible with the constructed template. Please upgrade the CDK bootstrap stack."
        }
      ]
    }
  },
  "Outputs": {
    "MyBucketStackMySimpleBucketArn12345678": {
      "Value": {
        "Fn::GetAtt": [
          "MySimpleBucketF4818B31",
          "Arn"
        ]
      },
      "Export": {
        "Name": "MyBucketStackMySimpleBucketArnExportName12345678"
      }
    },
    "MyBucketStackMySimpleBucketName12345678": {
      "Value": {
        "Ref": "MySimpleBucketF4818B31"
      },
      "Export": {
        "Name": "MyBucketStackMySimpleBucketNameExportName12345678"
      }
    }
  }
}

This template is the blueprint CloudFormation uses to create, update, or delete your AWS resources. The cdk synth command is the bridge between your imperative, object-oriented CDK code and CloudFormation’s declarative, resource-based model. It resolves all the dependencies, applies the correct AWS resource types and properties based on your CDK constructs, and generates a valid CloudFormation template.

The cdk synth command is the operational heart of the CDK. It takes your high-level constructs—like s3.Bucket—and translates them into the specific AWS CloudFormation resource definitions (AWS::S3::Bucket) with all the correct properties (VersioningConfiguration, BucketName, etc.) and their corresponding values. You can think of it as the compiler for your CDK application. It doesn’t deploy anything; it just produces the artifact that CloudFormation will consume. This allows you to inspect exactly what AWS resources will be provisioned and how, before any changes are made to your AWS environment.

The Resources section contains the actual AWS resources to be created. Notice how MySimpleBucket from your CDK code is transformed into MySimpleBucketF4818B31, a CloudFormation logical ID. The Type is AWS::S3::Bucket, and the Properties mirror the versioned=True and removal_policy=DESTROY you set. UpdateReplacePolicy and DeletionPolicy are automatically set to Delete because you specified RemovalPolicy.DESTROY – a direct translation.

The Parameters section often includes things like BootstrapVersion. This is crucial for ensuring compatibility with the AWS CDK bootstrap environment, which sets up necessary resources in your AWS account for the CDK to function correctly. The Rules section, particularly CheckBootstrapVersion, uses assertions to verify this compatibility.

The Outputs section defines values that can be exported from the stack, useful for referencing resources in other stacks. Here, we see exports for the bucket’s ARN and name, generated from Fn::GetAtt and Ref respectively.

When you define a RemovalPolicy in your CDK code, like s3.Bucket(self, "MyBucket", removal_policy=s3.RemovalPolicy.DESTROY), cdk synth translates this into both DeletionPolicy: "Delete" and UpdateReplacePolicy: "Delete" in the generated CloudFormation template. This is a critical detail: DeletionPolicy controls what happens to the resource when the stack is deleted, while UpdateReplacePolicy dictates what happens if the resource needs to be replaced during an update (e.g., if you change a property that forces replacement). Both being set to Delete ensures that the bucket is removed when the stack is deleted and if it needs to be replaced during an update, preventing orphaned resources.

The CDKMetadata resource is automatically injected by the CDK. It’s a small piece of metadata that CloudFormation uses to track which CDK version synthesized the template and to enable certain features or checks. You’ll often see Analytics: "allow" here, which is a mechanism for AWS to collect anonymized usage data about the CDK (you can disable this if desired).

Understanding the output of cdk synth is paramount for debugging and for gaining confidence in your infrastructure-as-code. It allows you to see the raw CloudFormation that will be applied, helping you to catch potential issues or unexpected resource configurations before they are deployed.

The next step after synthesizing a template is typically deploying it using cdk deploy, which then passes this generated CloudFormation template to the AWS CloudFormation service.

Want structured learning?

Take the full Cdk course →