Get started with CDK4J

Get started with CDK4J

To work with the AWS CDK, you must have an AWS account, credentials, and Java 17 or later installed. You will also need Apache Maven 3.5 or later.

Configure your AWS environment

To use the CDK4J to interact with AWS, you must configure security credentials on your local machine. This lets AWS know who you are and what permissions you have.

The system’s environment variables used are:

  • AWS_ACCESS_KEY_ID - Specifies an AWS access key associated with an IAM account.
  • AWS_SECRET_ACCESS_KEY - Specifies the secret key associated with the access key. This is essentially the “password” for the access key.
  • AWS_REGION - The AWS SDK compatible environment variable that specifies the AWS Region to send the request to.

The following examples show how you can configure those environment variables for Linux, Mac and Windows:

Create project

Each AWS CDK app should be in its own directory, with its own local module dependencies. Create a new directory for your app. Starting in your home directory, or another directory if you prefer, issue the following commands.

mkdir hello-cdk 
cd hello-cdk

Now create a file named pom.xml and copy the following content into it:

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>org.datapith</groupId>
  <artifactId>cdk4j-tutorial-getting-started</artifactId>
  <version>1.0.0</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <cdk.version>@aws.cdk.version@</cdk.version>
  </properties>
  
  <dependencies>
    <dependency>
      <groupId>software.amazon.awscdk</groupId>
      <artifactId>aws-cdk-lib</artifactId>
      <version>${cdk.version}</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <!-- Skip deploying example project to Maven repository -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-deploy-plugin</artifactId>
        <configuration>
          <skip>true</skip>
        </configuration>
      </plugin>
      
      <plugin>
        <groupId>org.datapith</groupId>
        <artifactId>cdk4j-maven-plugin</artifactId>
        <version>@project.version@</version>
        <configuration>
          <!-- Full class name of the app class defining your stacks -->
          <app>org.datapith.examples.GettingStartedApp</app>
        </configuration>
        <executions>
          <execution>
            <id>deploy-cdk-app</id>
            <phase>deploy</phase>
            <goals>
              <goal>synth</goal>
              <goal>bootstrap</goal>
              <goal>deploy</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Create App and Stack

An AWS CDK stack is the smallest single unit of deployment. It represents a collection of AWS resources that you define using CDK constructs. When you deploy CDK apps, the resources within a CDK stack are deployed.

You define a stack by extending or inheriting from the Stack construct. The following example is a common pattern for defining a CDK stack in a separate class. Here, we extend the Stack class and define a constructor that accepts scope, id, and props. Then, we invoke the base Stack class constructor using super with the received scope, id, and props:

package org.datapith.cdk4j.examples;

import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.constructs.Construct;

public class GettingStartedStack extends Stack {

  public GettingStartedStack(final Construct scope, final String id, final StackProps props) {
    super(scope, id, props);

    // Define your constructs here
  }
}

To create the stack, it must be instantiated within the context of a CDK app. A common pattern is to define your CDK app and initialize your stack on a separate file. In below example, the CDK app is created and the GettingStartedStack is instantiated in the context of the app:

package org.datapith.cdk4j.examples;

import software.amazon.awscdk.App;
import software.amazon.awscdk.StackProps;

public class GettingStartedApp {

  public static void main(final String[] args) {
    App app = new App();

    new GettingStartedStack(app, "GettingStartedStack", StackProps.builder().build());

    app.synth();
  }

}

Add an Amazon S3 bucket

At this point, your app doesn’t do anything because the stack it contains doesn’t define any resources. Let’s add an Amazon S3 bucket by adding an Amazon S3 bucket in the stack using the Bucket construct.

package org.datapith.cdk4j.examples;

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

public class GettingStartedStack extends Stack {

  public GettingStartedStack(final Construct scope, final String id, final StackProps props) {
    super(scope, id, props);

    Bucket.Builder.create(this, "MyFirstBucket")
        // Remove bucket when stack destroyed
        .removalPolicy(RemovalPolicy.DESTROY)
        .versioned(true)
        .build();
  }
}

As Bucket is the first construct we’ve seen, so let’s take a closer look. Like all constructs, the Bucket class takes three parameters.

  • scope: Tells the bucket that the stack is its parent: it is defined within the scope of the stack. You can define constructs inside of constructs, creating a hierarchy (tree). Here, and in most cases, the scope is this, meaning the construct that contains the bucket: the stack.

  • Id: The logical ID of the Bucket within your AWS CDK app. This (plus a hash based on the bucket’s location within the stack) uniquely identifies the bucket across deployments so the AWS CDK can update it if you change how it’s defined in your app. Here it is "MyFirstBucket". Buckets can also have a name, which is separate from this ID (it’s the bucketName property).

  • props: A bundle of values that define properties of the bucket. Here we’ve defined only one property: versioned, which enables versioning for the files in the bucket.

Synthesize the app

Synthesize the app, as follows.

mvn cdk4j:synth  

The synth action executes your app, which causes the resources defined in it to be translated into an CloudFormation template. The CloudFormation template is also saved in the \target\cdk.out directory in JSON format.

A snippet of the cloudformation template is shown below:

{
  "Resources": {
    "MyFirstBucketB8884501": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "VersioningConfiguration": {
          "Status": "Enabled"
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete"
    }
  },

Deploying the app

To deploy the stack using CloudFormation, issue:

mvn cdk4j:deploy

The deploy action displays progress information as your stack is deployed.

[INFO] Deploying to region eu-north-1
[INFO] Deploying 'GettingStartedStack' stack
[INFO] Waiting until 'GettingStartedStack' reaches stable state
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | Timestamp            | Logical ID                       | Status                           | Status Reason                                                    |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:48:11  | GettingStartedStack              | CREATE_IN_PROGRESS               | User Initiated                                                   |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:48:13  | MyFirstBucketB8884501            | CREATE_IN_PROGRESS               |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:48:14  | MyFirstBucketB8884501            | CREATE_IN_PROGRESS               | Resource creation Initiated                                      |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:48:33  | MyFirstBucketB8884501            | CREATE_COMPLETE                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:48:33  | GettingStartedStack              | CREATE_COMPLETE                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] The stack 'GettingStartedStack' has been successfully deployed

You can go to the CloudFormation console and see that it now lists GettingStartedStack. You’ll also find MyFirstBucket in the Amazon S3 console.

Congratulations, you’ve deployed your first stack using CDK4J! But that’s not all.

Modifying the app

CDK4J can update your deployed resources after you modify your app. Let’s change our bucket so it delete the objects stored within our bucket before destroying the bucket, via the autoDeleteObjects property.

package org.datapith.cdk4j.examples;

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

public class GettingStartedStack extends Stack {

  public GettingStartedStack(final Construct scope, final String id, final StackProps props) {
    super(scope, id, props);

    Bucket.Builder.create(this, "MyFirstBucket")
        // Remove bucket when stack destroyed
        .removalPolicy(RemovalPolicy.DESTROY)
        .autoDeleteObjects(true)
        .versioned(true)
        .build();
  }
}

Here, we haven’t written any code that, in itself, changes our Amazon S3 bucket. Instead, our code defines the desired state of the bucket.

ℹ️
Declarative IaC allows a developer to describe resources and settings that make up the end state of a desired system. The IaC solution then creates this system from the infrastructure code. This makes declarative IaC simple to use, as long as the developer knows which components and settings they need to run their application.

When we now deploy the stack you will see that CDK4J updates the bucket configuration as requested:

[INFO] Deploying to region eu-north-1
[INFO] Deploying 'GettingStartedStack' stack
[INFO] Waiting until 'GettingStartedStack' reaches stable state
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | Timestamp            | Logical ID                       | Status                           | Status Reason                                                    |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:12  | GettingStartedStack              | UPDATE_IN_PROGRESS               | User Initiated                                                   |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:15  | CustomS3AutoDeleteObjectsCustomR | CREATE_IN_PROGRESS               |                                                                  |
[INFO] |                      | esourceProviderRole3B1BD092      |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:15  | MyFirstBucketB8884501            | UPDATE_IN_PROGRESS               |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:16  | CustomS3AutoDeleteObjectsCustomR | CREATE_IN_PROGRESS               | Resource creation Initiated                                      |
[INFO] |                      | esourceProviderRole3B1BD092      |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:32  | CustomS3AutoDeleteObjectsCustomR | CREATE_COMPLETE                  |                                                                  |
[INFO] |                      | esourceProviderRole3B1BD092      |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:38  | MyFirstBucketB8884501            | UPDATE_COMPLETE                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:39  | CustomS3AutoDeleteObjectsCustomR | CREATE_IN_PROGRESS               |                                                                  |
[INFO] |                      | esourceProviderHandler9D90184F   |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:39  | MyFirstBucketPolicy3243DEFD      | CREATE_IN_PROGRESS               |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:40  | MyFirstBucketPolicy3243DEFD      | CREATE_IN_PROGRESS               | Resource creation Initiated                                      |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:40  | CustomS3AutoDeleteObjectsCustomR | CREATE_IN_PROGRESS               | Resource creation Initiated                                      |
[INFO] |                      | esourceProviderHandler9D90184F   |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:41  | MyFirstBucketPolicy3243DEFD      | CREATE_COMPLETE                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:46  | CustomS3AutoDeleteObjectsCustomR | CREATE_COMPLETE                  |                                                                  |
[INFO] |                      | esourceProviderHandler9D90184F   |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:47  | MyFirstBucketAutoDeleteObjectsCu | CREATE_IN_PROGRESS               |                                                                  |
[INFO] |                      | stomResourceC52FCF6E             |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:49  | MyFirstBucketAutoDeleteObjectsCu | CREATE_IN_PROGRESS               | Resource creation Initiated                                      |
[INFO] |                      | stomResourceC52FCF6E             |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:49  | MyFirstBucketAutoDeleteObjectsCu | CREATE_COMPLETE                  |                                                                  |
[INFO] |                      | stomResourceC52FCF6E             |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:50  | GettingStartedStack              | UPDATE_COMPLETE_CLEANUP_IN_PROGR |                                                                  |
[INFO] |                      |                                  | ESS                              |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 15:59:51  | GettingStartedStack              | UPDATE_COMPLETE                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] The stack 'GettingStartedStack' has been successfully deployed

Destroying the app

Now that you’re done with the quick tour, destroy your app’s resources to avoid incurring any costs from the bucket you created, as follows.

mvn cdk4j:destroy

As requested the application will be deleted

[INFO] The stack 'GettingStartedStack' is being deleted, waiting until the operation is completed
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | Timestamp            | Logical ID                       | Status                           | Status Reason                                                    |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:09:51  | GettingStartedStack              | DELETE_IN_PROGRESS               | User Initiated                                                   |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:09:52  | MyFirstBucketAutoDeleteObjectsCu | DELETE_IN_PROGRESS               |                                                                  |
[INFO] |                      | stomResourceC52FCF6E             |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:09:56  | MyFirstBucketAutoDeleteObjectsCu | DELETE_COMPLETE                  |                                                                  |
[INFO] |                      | stomResourceC52FCF6E             |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:09:57  | MyFirstBucketPolicy3243DEFD      | DELETE_IN_PROGRESS               |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:09:57  | CustomS3AutoDeleteObjectsCustomR | DELETE_IN_PROGRESS               |                                                                  |
[INFO] |                      | esourceProviderHandler9D90184F   |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:09:58  | MyFirstBucketPolicy3243DEFD      | DELETE_COMPLETE                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:10:00  | CustomS3AutoDeleteObjectsCustomR | DELETE_COMPLETE                  |                                                                  |
[INFO] |                      | esourceProviderHandler9D90184F   |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:10:01  | CustomS3AutoDeleteObjectsCustomR | DELETE_IN_PROGRESS               |                                                                  |
[INFO] |                      | esourceProviderRole3B1BD092      |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:10:01  | MyFirstBucketB8884501            | DELETE_IN_PROGRESS               |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:10:02  | MyFirstBucketB8884501            | DELETE_COMPLETE                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:10:14  | CustomS3AutoDeleteObjectsCustomR | DELETE_COMPLETE                  |                                                                  |
[INFO] |                      | esourceProviderRole3B1BD092      |                                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] | 2026-03-18 16:10:15  | GettingStartedStack              | DELETE_COMPLETE                  |                                                                  |
[INFO] +----------------------+----------------------------------+----------------------------------+------------------------------------------------------------------+
[INFO] The stack 'GettingStartedStack' has been successfully deleted
ℹ️
If we hadn’t set the bucket’s RemovalPolicy to DESTROY, the stack deletion would complete successfully, but the bucket would become orphaned (no longer associated with the stack).