At Reverb, we’re always thinking about ways to improve our workflow. Whether it’s in our application, our customer experience or our infrastructure, we know there’s always room for improvement.

One of the areas that we still have a lot of blackboxes and not-so-obvious knowledge is in the infrastructure that powers Reverb.com. When I started at Reverb in November 2014, all of our servers were built and maintained by hand. I knew that this approach was not feasible if we wanted to continue scaling our platform.

My first pass at revamping the infra included writing a chef cookbook for every service and using Chef to manage the infrastructure. This offered us a lot of benefits, such as repeatability and being able to document the actions required to configure our servers.

While we made some strides on the operating system and application level, we were still building what I like to call ‘artisanally crafted infrastructure’. Networks, subnets and load balancers were all set up by hand.

As the year went on, a lot of questions from the team arose: “Why does this server have X amount of ram? Why is X service in this subnet? Why does the load balancer listen on this port?” I knew that if I wanted to scale this platform that I had to shift the way I approached our infrastructure. I knew I had to document our infrastructure entirely in code.

Enter Terraform.

Terraform has given us the ability to create and spin up new environments in just minutes. Not only are the files self documenting the infrastructure, it’s incredibly useful to be able to tear down and spin up an entire environment by running one command: `terraform apply`.

Here’s an example of a Terraform plan that we use to set up one of our staging environments.

So far, we’ve rebuilt every one of our staging environments using a similar Terraform plan. This plan brings up our load balancer, database, elasticache instance and the instance that will run the reverb code. It even configures the DNS record pointing to the CNAME of the load balancer.

After the instance has been provisioned, Terraform even does us another solid: bootstraps the instance with the Chef server.

Terraform allows you to dynamically reference resources as they’re created. You’ll notice in the load balancer resource, I’m referencing ${aws_instance.example.*.id} which is string interpolation. Basically I’m telling the load balancer, “I don’t care how many instances there are, just use them all!”.

Another great feature of Terraform is that it allows you to generate dependency graphs so you can easily describe your infrastructure to others in a visual format:

Lastly, one of the things I’m really loving about this approach is that creating a new environment to test some crazy change is as easy as typing:

cp -r old-env/ new-env/ in Vim: %s/old-env-name/new-env-name/g and Finally: terraform apply

Next time you find yourself logging into AWS to make a handcrafted server sandwich with an applewood smoked load balancer, ask yourself “Is this something I could document and share with my team using a Terraform plan?”.

More than likely the answer will be yes. Not only are you spreading the knowledge that it took to create that piece of the Rube Goldberg machine, you’re saving yourself from hours of pain later on figuring out how you setup the damn thing months ago.

Like what we’re doing here and want to contribute to the best place to buy music gear on the web? We’re hiring for a Jr Devops Engineer and more!

Til next time,

@atom_enger