Terraform: Both Tool and Teacher

Adam Edwards
Pandera Labs
Published in
6 min readJul 11, 2018

--

I volunteered to stand up a SonarQube instance for internal use at Pandera Labs, so that I could learn more about the deployment process and how cloud infrastructure itself works.

At first, I thought using AWS’s web app would be a simple process, but I quickly learned that was not a good place to start for the faint of heart. My next stop was CloudFormation, but I learned (even sooner!) that using CF wouldn’t be as easy as I’d thought.

Eventually, I settled on Terraform after a suggestion from my colleague, Joel McCance. Here’s a description of my journey learning a new platform, as well as an entirely new (to me) aspect of application development.

The Goal: have a running instance of SonarQube deployed in a way that we have complete control over

My first attempt to create enough infrastructure to solve this task was to create an EC2 instance pointed at the Docker image for SonarQube. The AWS documentation made the process seem straight forward, so I was full of confidence going in to a code review with some of my more senior colleagues. That is, until I got the following feedback:

  • Can we have this instance accessible from an easy-to-understand URL?
  • What security is there on this instance?
  • How do we protect this in a multi-tenant system?
  • How are we maintaining state for the instance? It’s not running everything on a local H2 instance, is it?!?!
  • Can anyone access this instance? I don’t want strangers seeing my code analytics or where I keep my source code!

Their rapid fire questions that I hadn’t even considered showed me how little I had actually done, and how shallow my dive into infrastructure really was. Of course, I was prepared for constructive criticism, but I hadn’t even the slightest clue how to address the issues that were presented to me.

I started trying to read the AWS documentation to see how best to go about standing up an application. However, as anyone will undoubtedly tell you, the AWS documentation is very un-opinionated, dense, and difficult to understand. I had gotten as far as “set up an IAM role” before I got lost in the number of services and the myriad of ways to solve the same problem in AWS.

I made a number of mistakes simply trying to configure those services through the AWS console. To say that manually setting up services through AWS is error-prone is an understatement. Typically, you miss key information, opt for more computing power than you need, set up something completely unrelated to what you’re actually trying to achieve, and the list goes on and on… To make matters worse, this all costs money, and every time you make a mistake, AWS is tacking it on to your bill.

I was faced with a problem: how do I implement a cloud infrastructure stack with all of the best practices I would want to follow, and as efficiently as possible? So I tapped into my inner developer: surely someone else must have already solved this problem!

I was desperate to find hope, truth, a guiding light… So I turned to the gospel: StackOverflow.

You’re my only hope

Sure enough, Cloud Formation seemed like it would have been a great solution. But that was more of a nightmare to navigate and understand than the documentation was. Trying to understand a 900+ line long JSON file and making sure I set all of the right properties was daunting and unwieldy…

Enter Terraform

Terraform is an infrastructure-as-code tool by HashiCorp where you can write and design your cloud infrastructure in a structured and easy-to-read way.

I had first heard of Terraform through Joel McCance who had used the tool on a well-known client in the connected appliance manufacturing space. I thought I could use the goal of standing up this SonarQube instance as a learning opportunity for not only AWS infrastructure, but also Terraform.

Terraform operates in three phases:

  1. init — fetches your providers and modules (much like fetching dependencies for any other application code)
  2. plan — interprets your Terraform configuration and then provides a detailed execution plan of the changes that Terraform will perform on your infrastructure
  3. apply — deploys/implements the changes detailed in your plan

The most important phase here is the plan phase.

The plan phase is sort of like a compiler for your Terraform code. It will look at the configuration that you have written, insert variables where necessary, and pass references to dependent resources wherever they are needed. If at any point in your configuration a value is missing, a required field is not populated, or a dependency is not provided, the plan phase will tell you exactly what went wrong. plan will also tell you what you should consider doing to fix it.

This is how I learned how to stand up AWS infrastructure

I started building out my infrastructure in Terraform by first declaring an EC2 resource. The very first problem I faced was that I didn’t have an AMI for my instance. But I didn’t want to use an AMI, I wanted to use the Docker image that was already available for SonarQube. This led me to ask, “Is there another way to stand up a container in AWS?”

After a bit of research I learned that I could set up an ECS service. In Terraform, the ECS service resource requires that you provide an ECS task definition, along with a few other dependencies such as: a load balancer, a subnet and security group(s), and an ECS cluster.

With a little patience, I was able stand up the following with Terraform:

  1. VPC — Defined a VPC (Virtual Private Cloud) where all of the components can live safe from both external forces, and other tenants
  2. Subnets — Defined networks within a VPC to further segregate components so that important communication between components is hidden from public traffic, while key accessibility is available and easy to maintain
  3. Security Groups — Created permission sets to control access so that only components within the same Subnet and Security Group may communicate with each other
  4. Load Balancer — Created to manage incoming traffic to the ECS cluster, and for defining entry points to my applications for client interaction
  5. ECS — Established an ECS Cluster that managed an ECS Service which had deployed an ECS Task (or containerized application)
  6. RDS — Hosts a relational database (in this case Postgres) for maintaining the state of the SonarQube application
  7. CloudWatch — Captures logs of my ECS services

This is quite a lot, but it affords us a lot of peace-of-mind. Now that we’ve done this once in Terraform, we can do it again and again and again. For ourselves, we’ve reduced the ramp-up time for securely standing up an enterprise-grade infrastructure stack. For our clients, this means a secure, tailored environment for each and every application.

Suddenly something that would take days or weeks is now being done in minutes or hours. If you or your team are considering ways to maintain your infrastructure in a sensible way that also affords some accountability, I cannot recommend Terraform enough.

At Pandera Labs, we’re always exploring new ways to build products and iterate on our engineering processes, and we value sharing our findings with the broader community as our company and our technology evolve together. To reach out directly about the topic of this article or to discuss our offerings, visit us at panderalabs.com.

--

--