Writing Terraform configuration in TypeScript



Posted on

August 30, 2020

Terraform is a great tool for building Infrastructure as Code. Many teams like to use it for their deployments because of its cloud-agnostic approach and ability to treat infrastructure as cattle. However, learning how to write HCL can be a blocker for many.

Recently HashiCorp announced the community preview of Cloud Development Kit (CDK) for Terraform, which will enable developers to define their infrastructure with the familiarity of TypeScript and Python.

Pulumi have been on to this for a while, but the broad and mature provider support you get with Terraform sure is welcomed!

About CDK for Terraform

So how does this work? How can you use TypeScript with Terraform all of a sudden?

CDK for Terraform came to life thanks to the Terrastack project and AWS CDK. The idea is to generate provider definitions you can use with your programming language of choice, and then convert the result to JSON for Terraform.

First, declare your infrastructure in TypeScript or Python. You do this with the help of the package cdktf, and your favorite provider definitions.

Then, you convert your code declaration to configuration files Terraform can understand. This is done with the help of package cdktf-cli, a CLI tool designed to let you initialize, synthesize and deploy CDK projects.

CDK is still experimental, but it doesn't stop us from trying it out.

Using CDK with Azure

Set up a new project

Before proceeding, make sure you have Node.js ~12.16 and Terraform ~0.13 installed.

Then, install the CLI tool and create a new project folder:

Answer the questions in the guide in order to set up your CDK project. After the setup, you should have something like this in your project folder:

List of files within the CDK example project

The project template assumes we want to use AWS for our infrastructure, which we don't. To fix this, open cdktf.json and set the provider to azurerm:

After editing the file, run cdktf get in order to generate provider definitions for TypeScript.

It is also possible to import pre-built definitions for the major providers.

Declaring Azure resources in TypeScript

The TypeScript template project contains main.ts, which will be used as our starting point.

Azure resources are declared within the constructor of MyStack. First, import the AzurermProvider from ./.gen/providers/azurerm in order to configure the azurerm provider. Keep the configuration simple and use a partial provider configuration.

It can be hard to know which properties to use, since the Terraform documentation only covers HCL. The provider definition files helps cope with this (thanks, TypeScript!), and if you're using an editor with auto-completion (like VS Code) it will show you suggestions as you type. Otherwise, a pointer would be to use camelCase instead of snake_case for the property names.

Screenshot of VS Code auto-completion

To declare a resource group, import the ResourceGroup interface and set the values you want:

You can store resources in a variable and re-use properties for other resources:

Sometimes you need to resolve TypeScript types to Terraform types manually. To do this, import Token and use the resolve method for the appropriate Terraform type.

Synthesizing Terraform configuration

When you are happy with your resource declaration, you need to convert it into something Terraform understands. This lets you use your declaration in a Terraform workflow. To do this, use the command cdktf synth.

After doing this, you can proceed with deploying your resources with Terraform using standard procedure.

Wrapping up

CDK for Terraform is still in its early stages, so it doesn't come without limitations and quirks. It lacks a lot of features you'd come to expect from native HCL. And since it is preview software it isn't something you'd want to rely on for your production environments.

I hope this project will make Infrastructure as Code more accessible for developers. Not having to learn another language is something I think would help many on their way. If you want to follow the progress of the project, you can find it on GitHub.

Follow us on LinkedIn if you liked this post for more content like this. And if you have any questions regarding Terraform, we're happy to help you out! Just send us a message.

Written by

Lars Åkerlund