How we manage infrastructure with Terraform
When people think about software as a service, they tend to think of the application that they interact with in their web browser. Every bit as important as the application, though, are the servers, virtual networks, load balancers, cloud storage, and other resources that the application depends on.
Like software applications, infrastructure evolves over time. Servers must be scaled and new types of resources added as a company grows. When you have only a few servers to manage, you can sometimes get away with spinning up new resources by hand. This quickly becomes infeasible though, and automation is needed to make scaling possible.
Terraform is a tool that allows you to specify your infrastructure as code and automates the process of creating and manipulating infrastructure. You specify resources using a declarative syntax and Terraform takes care of creating your infrastructure by talking to your cloud provider’s API. Terraform offers many advantages over managing infrastructure manually, as we’ll see in the rest of this blog post. At Appsembler, we use Terraform to manage infrastructure for deployments of both Open edX and Virtual Labs.
The greatest advantage of using Terraform is automating the provisioning of new servers and other resources. This both saves time and reduces the possibility of human error. For each new customer deployment, we override a handful of variables in our Terraform configuration and run Terraform. First, the `terraform plan` command is used to construct a deployment plan. In the plan, Terraform tells us exactly which resources will be modified so that we don’t accidentally perform destructive operations. Next, the `terraform apply` command is run to execute the plan and create the infrastructure on our cloud provider. Terraform finishes executing in a matter of minutes and we have all the infrastructure needed to support the application.
Consistency and repeatability
Using Terraform allows us to specify our infrastructure as code. As with any other code, we can use version control and track changes over time. Infrastructure specified by code also enforces consistency across all our deployments in everything from naming conventions to machine specs to architecture. For each new deployment, we can ensure that it’s nearly identical to the last. Greater uniformity also makes it easier to build tooling around Terraform that allows for a smoother deployment process.
Consistency across deployments is also important for day-to-day maintenance. There was once a time when many of our deployments looked different, causing headaches for engineers. When a problem arose, it was difficult to know where to begin looking. Since we began using Terraform to standardize deployments, we don’t have to waste time figuring out how a deployment is set up before digging into an issue.
Provisioning resources with Terraform ensures that our infrastructure-level security policies are enforced. We no longer have to worry about the human error that inevitably comes with manual configuration. The Terraform providers for Google Compute Engine, AWS, and Azure support firewall rules and security groups. We simply have to specify which ports we want to expose and Terraform ensures that the corresponding rules are created. We can also enforce access controls for storage buckets using Terraform.
Using Terraform to specify infrastructure as code has been a huge productivity boost for us. We can create deployments for new customers much more quickly and with more consistency than before. Better consistency allows for not only a smoother deployment process, but also easier maintenance. With codified infrastructure, we can be confident that our infrastructure-level security policies are enforced and are not prone to human error during configuration.