DEV Community

Cover image for How to write terraform, but with typescript
Julian Krispel-Samsel
Julian Krispel-Samsel

Posted on

How to write terraform, but with typescript

Ever wished you could just use typescript to write your infrastructure? You may or may not have heard about the release of the terraform cdk (short for cloud development kit). It's HashiCorps answer to the aws cdk. In the words of the projects readme:

CDK (Cloud Development Kit) for Terraform allows developers to use familiar programming languages to define cloud infrastructure and provision it through HashiCorp Terraform.

Let's try this out shall we?

To get the full developer experience, make sure you have typescript support installed for your IDE

autocomplete-terraform

Generating the boilerplate

Let's open our terminal and install install cdktf-cli:

npm install -g cdktf-cli
Enter fullscreen mode Exit fullscreen mode

Next we'll initialize the project

mkdir hello-cdktf
cd hello-cdktf
cdktf init --template="typescript" --local
Enter fullscreen mode Exit fullscreen mode

Answer the two configuration questions and the project boilerplate will be generated.

Now we should see a main.ts file with the following contents in our folder:

import { Construct } from 'constructs';
import { App, TerraformStack } from 'cdktf';

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    super(scope, name);

    // define resources here

  }
}

const app = new App();
new MyStack(app, 'hello-cdktf2');
app.synth();
Enter fullscreen mode Exit fullscreen mode

Adding a provider package and importing modules from it

After generation finishes you'll see a message in the console listing instructions of what to do next. To add the prebuilt aws provider (which also gives us all the modules and types that we might want).

npm install -a @cdktf/provider-aws
Enter fullscreen mode Exit fullscreen mode

Now you can import modules from @cdktf/provider-aws such as AwsProvider and others. We'll go for the AwsProvider, LambdaFunction and IamRole. Add this at the top of your file:

import { AwsProvider, LambdaFunction, IamRole } from '@cdktf/provider-aws';
Enter fullscreen mode Exit fullscreen mode

and then create an AwsProvider in your stack:

new AwsProvider(this, 'aws', {
  region: 'eu-west-2'
})
Enter fullscreen mode Exit fullscreen mode

Adding a lambda function to our stack

To create a lambda we need to define an IAM role at first. Boring, but made easier by autocomplete of cours. Anyway here's the default policy:

const roleForLambda = new IamRole(this, 'iam-role-for-lambda', {
  name: 'iam-role-for-lambda',
  assumeRolePolicy: JSON.stringify({
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Principal": {
          "Service": "lambda.amazonaws.com"
        },
        "Effect": "Allow"
      }
    ]
  })
})
Enter fullscreen mode Exit fullscreen mode

Now we can add a lambda function to the stack like this:

new LambdaFunction(this, 'hello-world', {
  filename: process.cwd() + 'hello-world.zip'
  functionName: 'hello-world',
  handler: 'index.handler',
  runtime: 'nodejs12.x',
  role: roleForLambda.arn,
})
Enter fullscreen mode Exit fullscreen mode

You will need to zip your lambda function - which is usually a separate step before running terraform. For example sake, let's say you have a file in your project named hello-world.js:

export const handler = async function () {
  return { hello: world }
}
Enter fullscreen mode Exit fullscreen mode

Then zip your lambda zip -r lambda.zip hello-world.js

Deploying your stack

Before you deploy don't forget need to have your aws credentials in your path.

Now that you have everything ready you can deploy your stack with cdktf deploy. This command will display an execution plan and ask you if you want to deploy. Press the Y and Enter key to deploy.

Any errors at this stage should be farely self-explanatory. If they don't make sense, google the error message - other people have likely run into the same problem.


If you're a terraform user and you've used the lambda_function module before, you'll notice that the configuration is exactly the same.

Ultimately, when you run cdktf synth cdktf compiles your javascript/typescript modules into terraforms alternative JSON configuration syntax.

This is an extremely powerful feature of terraform's design since it can be a compile target not just for javascript and typescript, but any kind of language. The open source community could add it's own language compilers.

Why not write one in rust? 😅

PS: The original version of this post was published on my website, if you liked this post, please consider having a look around.

Top comments (1)

Collapse
 
hungluong profile image
Hung Luong

Seems quite unnecessary having to stringify a IAM policy document