Infrastructure as code (IaC) is a crucial component of the DevOps playbook. It approaches infrastructure by including it in the code, as code, ensuring consistent configurations and environments across many stages of a project.
AWS is an excellent tool to use to facilitate this, as it offers many ways to create and operate infrastructure as code.
In this post, we'll take a look at how to get started with this approach and what it should look like. We'll also look at two tools AWS uses for building infrastructure—CloudFormation and Terraform—as well as best practices for infrastructure as code on AWS.
What Is Infrastructure as Code?
The key goal of infrastructure as code is to automate infrastructure. Rather than having a system administrator (or several, as is usually the case) devote valuable work hours to manually setting up configurations on every single server, configurations can be stored as code.
This configuration then provisions and maintains servers with well-documented and version-tracked code. This comes with several advantages, including:
- Speed—By having a standard code to run for provisioning, deployment, and production, the entire pipeline becomes faster and simpler. It cuts down on decision-making and implementation time needed to run environments significantly.
- Less manual effort — System administrators don't need to handle every facet of infrastructure, meaning less work and lower cost.
- Prevents environment drift—When system administrators handle infrastructure on a server-by-server basis, each configuration is ultimately handled in different ways. This causes the configurations to "drift" further and further apart until the configuration active on one server is impossible to repeat on another. IaC provides a consistent configuration for each environment.
Infrastructure As Code on AWS
AWS is the lead cloud-computing platform in today's market. As such, many infrastructure as code tools are built for or to integrate smoothly with AWS.
However, AWS isn't the go-to infrastructure as a service (IaaS) platform only because it's the most common.
It also comes with a number of advantages. The first and foremost benefit of AWS—and the one we'll focus on here—is that it only charges for computational usage. This goes hand-in-hand with infrastructure as code, as it streamlines provisioning even further.
You allocate servers through AWS, initialize them immediately with an already-coded configuration (aided by AWS' tools for exactly that), and you have a consistent environment ready to go.
But enough about how easy infrastructure as code is. Let's take a look at how to actually set it up and what it should look like!
In this post, we'll look at two tools: CloudFormation and Terraform. If you're ready to get started with your infrastructure setup, you've likely already chosen a tool to work with. However, as a quick recap, CloudFormation is an AWS service for setting up AWS resources, and Terraform is an open-source infrastructure as code tool by HashiCorp.
Both CloudFormation and Terraform are declarative tools. This means that rather than defining what steps to take while provisioning infrastructure, you'll be defining a desired end state. CloudFormation then decides the path to take to achieve that state.
You'll use a template to tell CloudFormation what configurations you want created in the stack. The template is a text file written in JSON or YAML formats. It doesn't really matter which format you use. It can be slightly more advantageous to use YAML, as parsers can read JSON and not vice versa. It's also the default format for other tools, such as Kubernetes and Release's build files, so for consistency's sake, if you're using Release for your project, it might be easier to keep everything in YAML.
The important part is that you have all your desired configuration settings and resources matched to string keys that explain what they do to both the parser and anyone who might be reading the code—for example, "WebServer" followed by specifications for desired web server properties.
Readability is important for template files, as anyone working with this configuration should be able to check the specifics of it.
Once you have a template file, this is used to create a stack. CloudFormation checks if the resources listed in the template are available and creates the stack based on the uploaded template. Use the Events tab to monitor the creation process.
Once the Events tab shows "CREATE_COMPLETE" for a new stack, that stack is ready to go! You can start using those resources right away.
Terraform is an independent program, meaning you'll have to link it to AWS first. Do this by creating an access key for your AWS account and setting the access key environment variables in Terraform to your access key.
Once you've done this, you can get to work on defining an AWS-based infrastructure in Terraform. Terraform has its own native configuration language, and while Terraform also includes functions for encoding and decoding both JSON and YAML, the YAML functions are experimental, so it's best to keep your configuration files in Terraform's native language.
Similar to CloudFormation's template files, the configuration files declare the desired configuration and settings. For a detailed overview of these steps and how to write these configuration files, make sure to read Terraform's AWS-specific documentation.
We then have to implement the configuration files. Terraform does this via the CLI. The configuration is initialized, formatted, validated, and applied using the following Terraform commands:
Once we reach the "apply" stage, we see one of the notable differences between CloudFormation and Terraform. While both are declarative and create a plan to reach the defined end state, Terraform prints this execution plan into the CLI for user approval, detailing the changes made to the infrastructure to achieve the desired configuration. This gives you a bit more control over what exactly happens to your infrastructure.
After approving this execution plan, Terraform applies the steps. This stage is, again, quite similar to the CloudFormation process, though it uses a CLI to monitor instead of a GUI tab.
The end result can be reviewed with the command
Best Practices for IaC on AWS
AWS' focus lies in providing infrastructure and infrastructure as code. As such, they have extensive support and documentation, and it's worth reading their own best practices for infrastructure section. However, let's look at a few of the most important considerations.
- Streamline—Because this infrastructure as code is code, it behaves like code. It's version-tracked, duplicated, and used often. By eliminating duplicates and discrepancies, you can avoid overusing resources to store and integrate the code. Try to avoid unnecessary duplicates of code or code segments, and avoid unnecessary code segments overall.
- Test—Infrastructure as code is also a form of automation and, as such, unit testing and other fail-safes are crucial to ensure that your code is actually doing what it's supposed to be doing.
- Clarify—Infrastructure as code is meant to be used often and will likely be used by several members of your team. Make sure your code is readable, well-documented, and able to be quickly interpret by others. YAML and Terraform's native language are conducive to easy-to-read code, so with a little bit of attention, this is easy enough to achieve.
There's also a lot to be said for using environments as a service (EaaS) to make sure you're getting the most out of AWS with streamlined and tested environments. Release also has existing AWS support.
AWS is the leading Infrastructure-as-a-Service provider, with countless resources for infrastructure as code.
AWS documentation has a wealth of tutorials, best practices, and FAQs for infrastructure as code. Additionally, because AWS is so common and robust, the most commonly used IaC tools—such as CloudFormation and Terraform—work with it seamlessly. This means comprehensive support and resources.
With some attention, you can set up a stable foundation for your infrastructure, making your workflow simpler and more efficient.
Release is the simplest way to spin up even the most complicated environments. We specialize in taking your complicated application and data and making reproducible environments on-demand.