Published on

CDK or CloudFormation

Authors

Having used CloudFormation extensively to write infrastructure code hosted on AWS, I had a brief experience of using CDK on a small project at my previous employer. It seemed like a nifty tool AWS had developed on top of CloudFormation. The fact you could write your infrastructure code in a supported programming language and not in YAML or JSON is not only attractive, but it also seems intuitive. But having used it more on my own project, I have a different opinion of it.

Before diving into the pain points I experienced whilst using it, let’s see some of the benefits of CDK over CloudFormation.

THE GOOD

  • Bootstrapping: CDK enables you to easily prep your cloud environment before deploying your artifacts; for example, an S3 bucket needed to store your assets (generation CloudFormation files). Basically, things you would normally do with AWS CLI and bash to set up your cloud environment properly before provisioning your resources get done for you by a simple CDK command: `cdk bootstrap`
  • Default managed IAM roles and policies get created as part of your new construct, especially for commonly used AWS services. For example, the basic role your Lambda needs for sending logs to Cloudwatch logs gets created and attached by default unless you decide to create a custom one to override it.
  • Easy lookup of Construct (CDK representation of an AWS resource) properties with IntelliSense in your IDE or text editor which reduces the constant need to keep navigating to the AWS documentation sites to look up CloudFormation specs for your infrastructure code.
  • Easy management of dependent resources that can be referenced by importing them by ARN or attribute into your infrastructure code. It’s easier to look up services that your Constructs have permissions to access from right inside your CDK code especially if they already exist, for example, a VPC, RDS instance, or Kinesis stream. Here’s an example of a Kinesis stream import by ARN in TypeScript:
Example of import Kinesis stream in TypeScript
  • Writing infrastructure code in a familiar and supported programming language means you can take full advantage of your chosen language package management and create reusable modules. This can be particularly useful for resources that are commonly used across an organisation’s teams and you want to enforce some form of consistency across infrastructure that they each manage. It can also save time as it’ll be much easier to just run the package or a command-line tool to quickly provision required resources that teams can then build on top of.
  • Quicker feedback right in your terminal without having to navigate to the AWS management console to inspect deployment status on the CloudFormation dashboard.

Now let’s talk about what I have found really restrictive and not so desirable when using CDK.

THE BAD

  • Business logic and infrastructure code all look the same especially when you host versioned infrastructure code in the same repo as the application code.
  • More mental overload maintaining both infrastructure code and application logic written in the same language.
  • CDK construct or module version compatibility issues. CDK packages have to be the same version for related stacks. For example, you cannot use a different CDK version for your Lambda and then a different one for API Gateway within the same stack. You’re very likely to have issues. So you’d have to pin down versions. You update one, you update all.

THE UGLY

  • Assets in S3 don’t get reused and you can quickly start accumulating bills. So you’ll need to keep an eye on the assets that get built up over time in S3 and do some clean up from time to time. But there’s a caveat to this.
  • When you delete the assets in S3, you may also need to delete CDK toolkit that gets set up in CloudFormation when you first run the bootstrapping. The CDK toolkit syncs with the assets in S3 and if it doesn’t find them when you try to update your stack, you’d likely experience errors.
  • Some resources are not yet supported. So you may be half-way through a project that uses CDK and find yourself stuck. However AWS provides an escape hatch which is the low-level CDK modules called CFN Resources, they’re often prefixed with Cfn. The downside to this is, you may still have to reference CloudFormation documentation to really understand how to use them. I found myself doing that a lot when using API Gateway WebSockets. It was painful and time-consuming and I might as well have just used CloudFormaiton to create my APIs.

CloudFormation is native to AWS and it seems much easier to use for managing your infrastructure than having to deal with an extra layer of abstraction that is CDK, as well as all the problems that come with maintaining programming language packages and dependencies.