Complete AWS Elastic Beanstalk Application through CDK (TypeScript)

An entire CloudFormation stack written in TypeScript

Over the weekend I read Ross Rhodes’ fantastic article on generating Infrastructure as Code. Having previously encountered many shortcomings in the Serverless Framework with which I am most familiar, I was curious to see if CDK could be a solution to some of the more complex challenges in terms of deploying an Elastic Beanstalk application without the need for external CLI tools or using Amazon’s CodePipeline.

I was impressed — sort of.

Initially I was hugely optimistic, having found an Elastic Beanstalk example on the official Github repo. However, it should come as no surprise to anyone that the example (and documentation) provided were sorely lacking. The example provided only shows how to create a basic environment and application but running the demo code will give you the sample application (the “Hello World” of Elastic Beanstalk applications) — not very useful for production.

After many hours scouring the TypeScript source-code and AWS CloudFormation API reference, I eventually cobbled together a collection of CDK calls which were able to create a custom (i.e. not a sample application) Node.js Elastic Beanstalk environment entirely through CDK.

Getting Setup

I won’t go into full details of how to setup AWS CDK — they do a reasonable job in the official documentation so for the purposes of this example, let’s assume you are creating a brand new project in TypeScript:

$ cdk init --language typescript
$ tree -L 2
├── bin
│ └── elbtest.ts
├── cdk.json
├── jest.config.js
├── lib
│ └── elbtest-stack.ts

Notice the file? That’s your Elastic Beanstalk application — I’m not going to go into details on how you create that here — there’s plenty of documentation on AWS. However, for the example to work, you will need a ZIP file so just download a sample application if you don’t have anything on hand.

Elastic Beanstalk Application

The file which controls all the magic is elbtest-stack.ts — replace its entire contents with that of the below gist.

You’ll also need to install a couple of extra dependencies:

$ yarn add @aws-cdk/aws-elasticbeanstalk @aws-cdk/aws-s3-assets

Then to build and create the CloudFormation template:

$ yarn build && cdk synth

That’s it! You should now have a cdk.out folder containing your template which is ready to deploy!


  1. The first step is to create an S3 asset using the ready packaged ZIP file from earlier. This S3 logic fires before the CloudFormation template is acted upon. The thing I love about this syntax is how easy it is to reference the S3 Bucket and Key later on (lines 45 and 46)
  2. The next section (up to line 40) is largely copied from the demo application — it creates an app with some pre-defined options to showcase how the defaults can be overwritten.
  3. The appVersionProps is where the S3 asset from lines 10–12 is referenced
  4. Create the environment (needs to be placed after the app is created as per AWS’ example)
  5. addDependsOn: really critical line — the app version cannot be created until after the app!


With any luck, running yarn build && cdk deploy will have your application packaged and deployed to CloudFormation. You will notice you end up with two stacks — one for the main application template and one for your Elastic Beanstalk application (which itself creates a huge number of resources).

That said, running cdk destroy will remove both so there’s no additional cleanup required.


And you’re done! You can verify correct deployment by visiting the Elastic Beanstalk homepage — you should see something like this:

Elastic Beanstalk application homepage

Personally, I found this so much cleaner than any previous attempt I have made to deploy an Elastic Beanstalk application — sure there is still the packaging (ZIP) step but the overall feel of CDK is so much cleaner than trying to generate CloudFormation templates by any other means.

As alluded to in the source code — creating a custom IAM Instance Profile is also super trivial with this setup, I’ll go into more details on the specifics of this in a future article if there’s interest.

Happy CDK-ing!

Update: Here is part 2 — the IAM permissions with instance profiles



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store