If the CDK was a band, I’d be a groupie. If it was a football team I’d buy a season pass. If the CDK was a movie star I’d wait in line for an autograph. I really, really like the CDK. In this post I’ll tell you why.

I’ve been fascinated by computers for as long as I can remember. My mother is a writer so we had a computer around the house earlier than most of my friends did. I remember her typing commands in DOS to ‘park’ her hard drive. I remember green-on-black monochrome monitors. I remember when Windows came out. And I remember always wanting to learn more about how it all worked.

It only made sense I went to study technical computer sciences at the University of Applied Sciences in Utrecht. In The Netherlands, technical computer sciences is the study that has classes on programming in Assembly, on programming real-time systems, on the foundations of networking protocols, and - the class that has always fascinated me most - on object oriented programming.

If my passion for software was a spark before, learning object oriented programming turned it into a blaze. Defining real-world objects, modeling relationships, reusable interfaces, inheritance, it just resonated with me.

Leaping onto AWS

My distant second love in computer sciences is hosting and networking. I’ll save you the history, but I’ve been hooking up servers and routers for quite a while. In 2017 I joined Sentia as an AWS cloud engineer. In many ways this was a logical extrapolation of my two passions: I’ve always seen public cloud, and AWS specifically, as the crossroads between infrastructure and software. This is literally true in Infrastructure-as-Code.

But in some ways IaC felt like a step backwards. CloudFormation, with all its capabilities, is very unwieldy - there is so much repetition, and it is so easy to make a mistake. And sometimes it takes an hour for a deployment to fail and for you to actually find out you made a mistake. AWS SAM and the Serverless Framework alleviate some of these issues, but only for a specific subset of resources. Terraform follows a different approach which makes IaC a bit easier, but it has never felt quite like a natural IaC implementation to me. And all of these solutions miss some sort of flow. With their complex syntax and unfamiliar languages they just don’t feel like a natural extension of either software development or public cloud. And then, suddenly, there was the CDK.

Meet developers where they are

Meet developers where they are
If you haven’t seen it, check out Werner Vogels on the AWS Cloud Development Kit on YouTube. In 15 minutes Amazon’s CTO will take you through the origin story and idea behind the CDK. He will tell you how developers at AWS felt that CloudFormation’s declarative language did not meet their requirements, and how they developed the CDK to overcome their issues. Then they found out that AWS’ customers had the same needs. Raise your hand if you feel seen 🙋.

Let’s take a look at the problems they solved with CDK.

1. A full blown programming language for your infrastructure

A declarative language will always have limited functionality compared to a multi-purpose language like Java, Python, C#, Rust or Go. Although CloudFormation has added Modules, Macros and many other nifty features to solve some of its limitations, it can never compare to a language with features like if, for, while, import, os.environ, curl or datetime.now().isoformat(). Using a multi-purpose language to define infrastructure allows for boundless flexibility and innovation. Examples include custom configuration repositories, conditional loops, dynamic lookups and much, much more.

2. A language that you already know

The CDK has a concept called JavaScript Interop Interface, or JSII, which allows them to write CDK constructs (L1, L2 or L3) once in TypeScript and convert them to any other programming language, including Python, .NET and Java. This means any component they add will immediately be available in your language of choice. Gone are the days where you need to learn or use a language that wouldn’t be your first choice. Additionally, this allows you to write your application code and infrastructure code in the same language, with the same linters, same code checks and same version control systems. In fact, doing so is listed as one of the best practices in AWS’ blog post “Best practices for developing cloud applications with AWS CDK”.

3. Unit testing and Test Driven Development (TDD)

In software development unit testing has been a standard quality check for years, if not decennia. In the process of writing code, you define the expected outcomes for specific inputs. By running these tests any time you make a change you are assured that your change doesn’t affect anything you wrote in the past. If you write the unit tests before you write your implementation, you’re practicing Test Driven Development.

With CDK and the use of multi-purpose languages, unit testing has become a standard component for infrastructure as well. This is supported by default for TypeScript, and can be implemented with a bit of work for any other language too.

4. Do not repeat yourself (DRY)

I’ve saved my favorite feature for last. As you might have surmised from my introduction, I love clean code. I love writing reusable, efficient, natural code. This means that if a code block is repeated a few times, it should go in its own function or class (as long as the code remains readable and understandable, but that’s another discussion). Bare CloudFormation is terrible at this. I wouldn’t be surprised if more than 70% of any medium-sized CloudFormation project would be code that’s already used elsewhere in the project.

The CDK, on the other hand, is built around the concept of reusability. A Level 2 construct consists of Level 1 constructs with sensible defaults, so by using a Level 2 construct you’re avoiding coding those defaults time and again. A Level 3 construct consists of a pattern of Level 2 constructs, for example an S3 bucket plus a CloudFront distribution, and whatever is needed to make those work together. By using this L3 construct you’re writing only a few lines of code, instead of every configuration detail of its internal components.

But the best part is when you’re writing your own infrastructure project and realize you can combine a few parts into a building block - for example a CloudWatch Log Group, A Metric Filter and an Alarm, or an AppSync Resolver and a Lambda Function. You look at your code and realize these combinations occur a few times. You group them into a Construct with sensible defaults, use parameters to provide their configurable parts, and suddenly you’ve saved yourself 50 lines of code and got a better readable result for it too.

Conclusion

The CDK is one of those products that make so much sense you don’t understand it wasn’t there before. But it’s the things that seem logical and simple that are the hardest to envision. As the classic example goes: everyone says “I could have thought of that!”, but nobody did - until they did. The decision to build JSII and support any programming language has also been visionary. Without it, the CDK would never have seen the uptake it has.

With the CDK, we have reached the point where application and infrastructure development seamlessly flow into and over each other. You add a database or a bucket, and in the same breath you write the application code that uses it. You run a code linter on your project, and your application and infrastructure are validated in a single keystroke. You run your unit tests, and you can be guaranteed that there are no regressions in either your application or your infrastructure. It is natural.

I share posts like these and smaller news articles on Twitter, follow me there for regular updates! If you have questions or remarks, or would just like to get in touch, you can also find me on LinkedIn.

Luc van Donkersgoed
Luc van Donkersgoed