Terraform CDK — Deploying a serverless API Gateway to AWS
In this article we will setup an AWS Lambda backed API Gateway, go through the decision making process of our infrastructure as code tool, as well as share some best practices when it comes to IaC.
What is Terraform CDK and why should I care?
Nowadays Infrastructure as Code (IaC) is a well known pattern that, luckily, most companies embrace. Most commonly used tools are Terraform, or proprietary solutions, such as AWS CloudFormation. While these tools definitely have their purpose, they share a common pain point — they require developers to learn a proprietary language or configuration format that is not used anywhere except for IaC.
This is a hurdle that each and every developer needs to overcome when having to adjust the infrastructure of a project. Admittedly not a huge deal for most, it can be scary for others. This in turn reduces the number of people comfortable with taking on and working onsuch a task, which then could act as a blocking factor for innovation and productivity.
To overcome this, we have chosen Terraform CDK for some of our application stacks. It allows us to write our IaC using the same language in which the developers author the application itself. As of today Terraform CDK supports the following languages:
- C#
- Go
- Python
- Java
- TypeScript
Since the IaC is written in a proper programming language, you also inherit some of the baseline features, for example …
- Code completion in all IDEs
- A type system that warns you about invalid types / missing arguments or options
- The ability to write tests for your IaC
- Use existing APIs / packages of the language (e.g. the file-system, http calls (not recommended IMO but possible)) and so on.
- Create IaC abstractions that can be published to a package registry and shared across projects
Getting started with Terraform CDK
Starting off with Terraform CDK is easy as pie, and there are loads of getting started guides out there already, so I will not repeat this. Instead I would recommend to just watch the guide from the Terraform CDK team itself.
Usual structure of a Terraform CDK module
Let’s walk through the usual structure that we use for all of our CDK modules, which is a built-in way of grouping related cloud resources. In “standard” terraform this was done using the “module” construct.
As you see, to declare a module we simply need to declare a class that will extend the Construct
base class and from there on it is your job to declare and configure the cloud resources, easy right?
Creating the AWS Lambda CDK module
Now let’s jump to the first piece of the puzzle — The lambda module.
You see that the configuration of this module is quite simple, since our use case in this application is to create lots of lambda functions that will not significantly differ in terms of configuration. However, if you need to individually provide some configuration for Lambda A but not B, simply add some options to the interface on the top — voilà!
Creating the AWS APIGateway CDK module
Next up is the APIGateway V2 which will be used to expose all Lambda functions via one hostname. Again, this is the most basic example and you might need to tweak the configuration to match it to your own needs.
Creating the AWS CloudFront CDN CDK module
And finally, to increase the performance and, also important, to reduce costs of AWS Lambda, let’s setup a CDN in front of the AWS APIGateway V2.
Combining all modules
Now that we have all of our modules setup, the only thing left is to integrate them. This is where you can really feel the benefits of using Terraform CDK.
In our codebase, we make use of the filesystem to automatically pick up and deploy lambdas once code get’s pushed into the repository. An example structure could look as follows:
├── infrastructure
│ ├── index.ts
│ └── ...
├── lambda
│ ├── get-products-v1
│ │ ├── ... source files of the lambda
│ │ └── lambda.zip
│ ├── get-cart-v1
│ │ ├── ... source files of the lambda
│ │ └── lambda.zip
└── README.md
Note that we also follow convention over configuration in this example. You might notice that we follow a naming schema for the folders of the lambda, e.g. {method}-{endpointPath}-{version}
.
Since we use Terraform CDK, we can now scan the lambda
directory and create one AWS lambda deployment for each folder. An example could look as follows:
Summary
While the code we’ve used here is quite rudimentary, it shows how easy it is to setup an applications deployment to the cloud using IaC with Terraform CDK.
All in all we had a great experience with Terraform CDK so far. Onboarding new developers into the infrastructure is much easier and we can see how the capabilities of the CDK will benefit us even more in the longer run!
A huge thanks to everyone involved the architecture, developing and contributing to Terraform CDK! ❤️