What is Infrastructure-as-Code?
Infrastructure-as-Code(IaC) is the process of managing and automating computer infrastructure via a descriptive coding language. There are two big players in the Infrastructure as Code space, Amazon’s CloudFormation and HashiCorp’s Terraform. Both tools are extremely powerful and enable developers to manage their infrastructure to support their business without owning any.
Why should your organization adopt Infrastructure as Code?
Whether you have a physical datacenter or not provisioning infrastructure for application teams can be a slow and tedious process that requires numerous checks and balances.
A common workflow for organizations provisioning infrastructure:
- File a Change Management Ticket (i.e., ServiceNow) to request Server and Compute
- Wait days or weeks for the infrastructure to be provisioned
- Response to the Change Management Ticket with all the corresponding networking and access information needed for the servers.
- Deploy core software on to the target server.
If we take this example, there are three teams involved. One is the Change Approval Board, which will review the request, another is the actual Datacenter engineers who will configure the servers for use, and the application team who requested the infrastructure in the first place. This management process will slow down software delivery and feature development because its dependent on other parties completing their tasks in the overall development cycle.
Infrastructure as Code enables teams to centralize the management of infrastructure as a Coded Configuration file. These files including any changes are versioned and audited. Infrastructure as Code also automate the process for making traceable configuration changes reducing development and operations time across the engineers.
Another scenario I’ve experienced at another company, they just completed the migration to the cloud, and they are trying to manage all their infrastructure. As a result, their cloud spend is through the roof. They don’t know what infrastructure their developers were provisioning. They forgot to clean up unused resources, and there’s no way to trace these changes to a team for cost center management. When working with infrastructure as code, the code is the source of truth. Whoever runs or makes changes to the configuration can be identified or versioned via Source Control.
How will this improve our ability to deliver software?
Infrastructure is now versioned and managed by code
With infrastructure managed by code, the App Team, the DevOps team, or Infra Team can manage their Infrastructure in Source Control. Take Github; for example, organizations can enforce branch protection on master before automating the creation of the infrastructure. The developer can make a change on a development branch and call for a Pull Request to Master. This enforces infrastructure changes to be reviewed by a teammate or Infrastructure lead to ensure the changes make sense. Every PR is tied to a commit ID that can be leveraged for auditing/tracking purposes.
Provision what you need and maintain state
Rather than allowing your developers to go directly into an AWS console to provision resources on their own, they can leverage Infrastructure as Code to do so. Companies don’t need to own any infrastructure! Tools like Terraform enable developers to maintain the state of their infrastructure and can easily track and identify changes to their infrastructure. They can also preview the desired state they wish to achieve with the newly committed configuration. This also encourages behavior only to create what you need because Infrastructure as Code provides more visibility into what resources have been provisioned. Outputs of the provisioned infrastructure are captured and can be quickly passed to the developers to consume.
With automation around Infrastructure as Code and Provisioning, a developer team no longer has the bottleneck of having Infra team or Datacenter team physically provisioning infrastructure. They don’t need to wait weeks for a Change Request to be approved. The infrastructure is provisioned, configured with the operating system they need to get their application running from the get-go. All the networking is defined in code and can be captured for application use.
Terraform Versus CloudFormation
Terraform and CloudFormation are both excellent Infrastructure Provisioning Tools. Choosing one over the other will depend on your organization’s skillsets, technology stack, and preferences.
Heavy users of Amazon and AWS solutions typically adopt CloudFormation because of the native integrations with the rest of the AWS Ecosystem. CloudFormation is the backbone for a lot of other tools like AWS Lambda creation and configuration. CloudFormation has the concept of templatizing and parameterizing which allows users to define their infrastructure configuration once. They can pass in different inputs for different environments and different services.
Terraform gives users the flexibility to be in multiple clouds while having one standard configuration language to manage it all. Terraform has the dry-run capability, which allows users to view the Infrastructure to be provisioned. You can also manage the state of all your infrastructure in Terraform by storing state in state files and saving the file in an S3 bucket or pointed to in a DynamoDB table. Developers can also templatize their configuration and leverage `var` files to pass in different inputs for Infrastructure provisioning using Terraform. A best practice for working with infrastructure as code is to allow a base template to be used across the same teams and environments level. All only allowing customizations via parameters or specific inputs passed into the Terraform file.
Regardless of the tool you choose, Infrastructure as Code is a good practice to adopt. Development teams can feel empowered and held accountable for the infrastructure they wish to leverage. It's easier for centralized infra teams to manage an organization's infrastructure. Software development speed increases by cutting down on the infrastructure provisioning dependencies that software may require.