Home
Published on

AWS CDK Glossary - Part 2

Author
    Roman Naumenko
    Name
    Roman Naumenko

In part one of "AWS CDK Glossary," we went through the base CD terminology: constructs, construct libraries, the App, and the Stack. In this post, I'd like to explore constructs' programmatic properties and relations between constructs.

Do you know how does CDK distribute code and libraries? The same way as any other programming language distributes libraries and packages. For example, aws-cdk-lib it is an NPM module. It supplies all L2 Constructs, App, Stack, and all other extra classes of CDK. From a packaging and distribution point of view, the CDK version 2 delivers almost everything required for development with a single aws-cdk-lib npm package. Very convenient!

CDK has a CLI - just like any other respectful programming framework. But unlike other frameworks, the parents gave it an enterprise-y name: the "CDK Toolkit" rather than a simple "CDK CLI." I've never heard anybody saying anything like, "let me quickly run the diff with CDK Toolkit."

Ok, what about the constructs implementation? My goal here is to look into the CDK source code and see how they named things. But first, let's talk about distinct ways AWS advertises and writes about CDK. They created various web portals (for example, "Constructs Hub") to provide users with valuable sets of abstractions or "construct libraries." Wait, we just talked about NPM modules? Why not distribute packages via a standard supported channel for a programming language?

I think all kinds of CDK "web portals" with libraries are a necessary evil. The first reason is that CDK itself supports (distributed for) multiple languages. The CDK itself is TypeScript; but libraries can be published in JavaScript, Python, Java, C#, and Go. AWS uses jsii compiler to bundle classes in TypeScript for other languages. Is it the same experience with CDK constructs across all languages? No, it is very different. The documentation for extra languages is minimal. For example, aws-cdk-lib for Python package links to the "source code," which points to the AWS CDK GitHub repository.

Keep jsii compilation and distribution model in mind when you pick up the language for the CDK application: The CDK itself has the source code, TypeScript. For all other languages - it is a compiled "runtime" from the TypeScript source code.

What is inside the CDK application? Here is a minimalistic example of a CDK application in TypeScript.

main.js
import { App, Stack, StackProps } from "aws-cdk-lib";
import { Bucket } from  "aws-cdk-lib/aws-s3";
import { Construct } from "constructs";

export class MyStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps = {}) {
    super(scope, id, props);

    new Bucket (this, "myBucket", {})
  }
}

const cdkApp = new App();

new MyStack(cdkApp, "InfraStack");

This is a simple yet fully functional CDK application that creates an S3 bucket.

The application uses classes such as: App, Stack, Construct, Bucket. What are those classes for? And why are there so many if it only creates a bucket? I peeked at the definitions in IDE and copied them right from the source code and comments.

⁠Construct: "Represents the building block of the construct graph.

⁠All constructs besides the root construct must be created within the scope of another construct"

App: A construct which represents an entire CDK app. This construct is normally the root of the construct tree.

⁠You would normally define an App instance in your program's entrypoint, then define constructs where the app is used as the parent scope.

Stack: A root construct that represents a single CloudFormation stack.

StackProps: an interface.

Constructor: ⁠Creates a new stack.

* @param scope Parent of this stack, usually an `App` or a `Stage`, but could be any construct.
* @param id The construct ID of this stack.
* @param props Stack properties.

⁠Bucket: An S3 bucket with associated policy objects.

⁠This bucket does not yet have all features exposed by the underlying BucketResource.

synth(): Synthesize this stage into a cloud assembly.

⁠Once an assembly has been synthesized, it cannot be modified. Subsequent calls will return the same assembly.

We already saw "Construct", however "construct graph", "root construct", "scope of construct" are specific programming CDK concepts.

The App is a top-level construct, and they probably used "construct tree" interchangeably with "construct graph."

"Parent scope" is related to the "scope of the construct."

Constructor is a method of a class.

The Bucket is an AWS resource; however, the phrase "associated policy objects" needs clarification.

And finally, the "cloud assembly" and "synthesize" are related to the CDK framework rather than the application code.

This is the glossary of all the above terms.

TERM

WHAT IT MEANS

Construct graph, construct tree

All CDK apps consist of constructs arranged in a hierarchy. CDK developers decided to expose this hierarchical structure. This is the respective design proposal.

If you run cdk synth, the tree will be generated in cdk.out/tree.json file. The tree defined the order and dependencies between resources.

This is also a convenient way for low-level debugging when something goes wrong with constructs that create many resources.

Root construct

If there is a Construct tree, what would be the root of that tree? CDK application itself. In the code above, it is declared as const cdkApp = new App()

Scope of the construct, Parent scope

The Constructs are organized into Construct tree. But how do Constructs know about the scope: who's the parent, who's children in the tree?

The scope must be defined in the class constructors. Which means that each construct will have a parent construct.

The resources in MyStack construct will have the parent scope MyStack and the Bucket has a child Construct aws-cdk-lib.aws_s3.CfnBucket

Associated policy objects

It is probably something peculiar to Bucket Construct. There is a "policy" property in the class code: "The resource policy associated with this bucket."

Cloud assembly

"Cloud assembly" is a set of deployment artifacts. When application calls cdkApp.synth() - it will make each Construct class generate artifacts with synthesis method implementation.

The artifacts are not only Cloudformation template(s). There are AWS Lambda application bundles, file and Docker image assets, and other deployment artifacts. There is an official specification for Cloud assembly.

cdk.out/manifest.json file contains all information about cloud assembly.

Synthesize

Run your CDK application assuming it has app.synth() method. Developers can run applications directly with the programming language interpreter or compiler. It will synthesize cloud assembly.

CDK CLI can do the same with cdk synth

I created an entity relation diagram I created with Mermaid.js that highlights the tree hierarchy of constructs.

That is a lot to digest! The good news is that the CDK as a software project is well-organized and logical. Here are distilled core programming concepts from classes such as Stack, Construct, App:

  • Everything is a construct
  • CDK applications made of constructs
  • CDK application is a root construct
  • Constructs organized in a hierarchical tree
  • Construct classes require a scope, so it knows the parent construct

And finally, the framework can produce a somewhat surprising number of deployment artifacts called "Cloud assembly." The method of creating artifacts is synth(), and constructs can implement their own synthesized methods.

Next Post

← Back to the blog

Services

Overview
AWS CDK CourseNew

Catenary Cloud

© 2021 Catenary Cloud LLC. Made with ❤️ in Philadelphia