Installing Terraform CDKTF in an old repository with AWS

September 17, 2022

I ran into a problem a couple of weeks back where I wanted to install CDK for Terraform in an old project of mine to deploy it to AWS with an EC2 instance, however, on Terraform’s tutorial pages I only found a brief tutorial showing how you can deploy a completely new project.

So I decided to test it out and found a way!

Prerequisites

  • Any old project of yours that could use some IAC

Approach

First thing you need to do is install cdktf@latest and cdktf-cli@latest, which can be done using npm:

npm install cdktf@latest cdktf-cli@latest

Now we’ve passed the first step. Then we need to create a file called cdktf.json, which can be done either through terminal with touch cdktf.json or in your favorite editor. Then simply add this to cdktf.json:

{
  "language": "typescript",
  "app": "npx ts-node main.ts",
  "projectId": "YOUR_PROJECT_ID",
  "terraformProviders": ["aws@~> 3.0"],
  "terraformModules": []
}

Here we basically tell Terraform that we want to use AWS version 3, and then there’s some basic information since we could also use Python for the IAC code, however, I’m more familiar with typescript.

Now add cdktf get --language="typescript" as a script to your package.json (if you haven’t installed cdktf globally), and run it using whatever command you named it. For example, if you added:

"get": "cdktf get --language='typescript'",

to your package.json, then run npm run get. This way we’ll fetch the necessary things for the cdktf to work.

Then to actually tell Terraform what to deploy, add a file called main.ts and fill it with this:

import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import { AwsProvider, ec2 } from "./.gen/providers/aws";


interface MyStackConfig {
  environment: string;
  region?: string;
}

class MyStack extends TerraformStack {
  constructor(scope: Construct, id: string, config: MyStackConfig) {
    super(scope, id);

    const { region = "eu-west-1" } = config;

    new AwsProvider(this, "aws", {
      region,
      accessKey: process.env.AWS_ACCESS_KEY,
      secretKey: process.env.AWS_SECRET_KEY
    });

    new ec2.Instance(this, "YOUR_INSTANCE_NAME", {
      ami: "ami-09e2d756e7d78558d", // AWS Free Tier Linux ami
      instanceType: "t2.micro",
      tags: {
        environment: config.environment,
        Name: 'YOUR_PROJECT_NAME'
      },
    });
  }
}

const app = new App();
new MyStack(app, "YOUR_PROJECT_NAME-dev", {
  environment: "development",
});
app.synth();

Also, create a file named .env and add your AWS_ACCESS_KEY and AWS_SECRET_KEY to that file. If you haven’t created those, you’ll need to create them in AWS for your account.

Deploying

If you want to deploy the AWS app, add "deploy": "cdktf deploy" and "destroy": "cdktf destroy" to your package.json, and run the script with npm run deploy. This will deploy an EC2 instance to your AWS account, however, do remember to run cdktf destroy to take the instance down, otherwise you may be billed for the usage.

Wrap-up

In this blog, we have shortly gone through how it’s possible to add CDK for Terraform to an old project, if you’re interested in writing IAC code as typescript instead of using the TF template language.


Profile picture

Written by An anonymous coder who lives and works building useful things. Mostly focusing on Django, Vue and overall Python examples.