JS-Terraform: Spicing up Terraform and Terragrunt with JavaScript

Martin Wentzel
Stocard
2 min readMay 7, 2019

--

We at Stocard aim to write all of our code in JavaScript or Typescript, and we also use Terraform and Terragrunt to manage our backend infrastructure.

In order to quickly setup the needed resources for a new service (loggroups, targetgroups….) we have developed a set of TypeScript-based CLI scripts. What they basically do is ask a few questions (e.g. “which healthcheck path does our service have”) and then generate the Terraform resources your service needs. However, it was always a bit odd to change tools, from JavaScript to Terragrunt and back. Thus, I decided to write a small TypeScript wrapper for Terraform and Terragrunt. (And, actually, the combination is pretty cool and gives you a lot of possibilities)

Here is the link for the curious people amongst you: https://github.com/Stocard/terraform-js

Using is straight forward. Instead of calling terraform plan in a specific directory, you do

const terraform = new Terraform()
await terraform.plan(path)

This will give you exact same functionality. But wait, what if you already know what the plan will output and do not want any output? Simply pass { silent: true} as a second parameter.

Furthermore, the plan, apply, destroy functions return how many resources are changed (or will be changed, in the case of a plan):

const terraform = new Terraform()
const resources = await terraform.apply(path)
console.log(resources.addCount) // E.g. "2"

You can simplify the apply by using the silent mode and also passing autoApprove: true as another option=> perfect for usage in CI/CD scenarios!

Outputs

Apart from changing resources, terraform-js also knows how to handle outputs:

const value = await terraform.output(path, { simple: true })
console.log(value)
/*
{
output_1: '1'
}
*/
// you can also have the full output by setting simple: false
/*
{
output_1: {
sensitive: false,
type: 'string',
value: '1'
}
}
*/

There are also more output possiblities, simply check out the documentation!

You can also add custom loggers and stderr/stdout streams for better integration into your own tooling.

Outlook

The combination of Typescript with terra-* tools is pretty nifty, as it enables some other cool things further down the road:

  • Standardized output from terraform and terragrunt (terragrunt’s outputAll -json does not produce valid JSON)
  • Create terraform resources directly with JavaScript: terraformjs.createResource<EC2Instance>(allTheRequiredParameters, basePath)
  • get outputs for resources which are not defined as outputs
  • maybe you also have a cool idea? Create an issue!

Please feel free to check it out and use it!

--

--