Infrastructure as Code: From the Beginning to GitOps
Managing infrastructure is a key component of any software development. Without proper infrastructure configurations in place, applications can run into issues ranging from performance bottlenecks to outright failures in functionality. Therefore, infrastructure should be considered a critical part of the overall software delivery process.
However, it has become increasingly difficult to manually manage infrastructure with the rapid pace of modern software developments. Infrastructure as Code evolved as a solution for scalable infrastructure management in the SDLC. In this post, let's explore how IaC has evolved to become the de facto method of managing modern infrastructure.
What is Infrastructure as Code?
Infrastructure as Code or IaC is the process of provisioning and managing infrastructure through code without relying on a manual process such as through a console or the CLI.
This codification of infrastructure enables developers to create standardized, repeatable, and shareable configurations. IaC ensures that the infrastructure is configured well without any unintended changes whenever it is provisioned. Infrastructure as Code goes hand in hand with version control as IaC configurations can be stored and version controlled for simplified management.
IaC eliminates the need for manually provisioning or configuring resources such as servers, load balances, storage, etc., with each application deployment. Instead, all these things can be done via automated IaC as a part of the delivery process. IaC is the perfect tool for infrastructure management in a DevOps environment while facilitating a collaborative configuration experience that goes hand in hand with application development.
Benefits of Infrastructure as Code
- Integrate with version control to create trackable and auditable infrastructure changes and facilitate easy rollbacks.
- Introduce automation to infrastructure management. This can be included as a part of the delivery process by integrating IaC with CI/CD tools.
- Ensure repeatability and eliminate configuration drift
- Introduce standardizations across infrastructure conveniently (Naming conventions, tags, defaults settings, etc.)
- Create modular infrastructure configurations that can be used across projects
- Increase deployment speed and reduce configuration errors.
There are two different approaches to IaC as declarative and imperative when creating these configurations.
Different Approaches to Infrastructure as Code
Imperative (Procedural) IaC
This approach requires users to specify exact commands/steps that are needed to create the configuration. Additionally, these commands/steps need to be run in the correct order to get the required outcome.
Declarative (Functional) IaC
In the declarative approach, users specify the desired outcome without providing the exact steps or commands that are needed. Then, the IaC tool will automatically carry out the necessary steps to obtain the specified configuration.
Tools like Chef and Ansible can be considered imperative, while tools like Terraform, Pulumi, Puppet, and CloudFormation can be considered declarative. Declarative tools are preferred in most cases as they allow users to simply provide a desired state of the infrastructure without having to figure out the exact steps needed to achieve the required configuration. However, users are free to use a combination of these two approaches for their configuration needs.
Types of Infrastructure as Code
At the most basic level, scripting is the starting point for IaC. Users can create a simple script for an ad-hoc task like starting or stopping servers and manage it through a VCS (version control system). However, it's better to use a specialized infrastructure as a code tool for more complex requirements. These IaC tools can be broken down into the following three types;
Provisioning Tools
These tools are focused on provisioning, configuring, and managing infrastructure. Terraform, AWS CloudFormation, Azure Resource Templates, and Pulumi are some examples of provisioning tools.
Configuration Management Tools
Configuration management tools are specialized in managing software. They can be used to install and configure software and related settings. Some examples of these tools include Chef, Puppet, and Ansible.
Containerization and Image Building Tools
These tools are used to create containers that contain portable and self-contained applications with necessary configurations or images that contain all the necessary software and settings. These can range from containerization tools such as Docker and Podman to image builders such as Packer and EC2 Image builder.
In modern DevOps, a combination of these tools is used to manage infrastructure. Some tools like Ansible and Terraform even include capabilities beyond their core specialty. For example, Ansible can be used for infrastructure provisioning, while Terraform can be used for configuration management.
Modern Infrastructure as Code
The requirements of IaC have changed with most application developments utilizing cloud technologies or building completely cloud-native applications. This transformation has led to most IaC tools supporting cloud platforms and major cloud platforms themselves introducing platform-specific IaC tools such as CloudFormation for AWS, Resource Manager for Azure, and Cloud Deployment Manager for GCP. The primary advantages of these tools are their native and tightly coupled integration with the respective platforms.
However, most users prefer platform-agnostic tools such as Terraform, Pulumi, and Ansible since they can be used across multiple providers and services without the need to implement platform-specific configurations.
Another major shift in the IaC space is offering developers the freedom to utilize IaC tools using common software development languages. In most cases, IaC tools relied on proprietary languages such as Hashicorp Configuration Language for Terraform or specific syntaxes and formatting. The complexity of the requirements of IaC tools has also grown due to their widespread adoption. One such instance is relying on a domain-specific language or format limits that can be achieved through IaC. Thus, tools such as Pulumi provide the ability to provision and manage infrastructure through any supported language such as Python, JavaScript, Go, and C# with IaC provided as an SDK. This broad support has led to other IaC tools that used domain-specific languages to provide SDKs, such as the Cloud Development Kit for Terraform and AWS SDK. All these advances have enabled developers to leverage the power and features of modern programming languages to facilitate infrastructure as code leading to ever more complex configurations.
How GitOps relates to Infrastructure as Code
DevOps practices enabled faster and flexible software development lifecycles without compromising software quality while facilitating a more collaborative environment. This adaption has further evolved into GitOps, allowing infrastructure to be included as an integrated part of the development process and managed through a CI/CD pipeline. Thus, users can utilize the same tools and practices used in software development for infrastructure management purposes.
IaC before GitOps
While Infrastructure as Code existed before GitOps, it was not handled as a part of the delivery pipeline. Even with IaC utilizing version control and automation to some degree, these infrastructure changes were managed separately, leading to a disconnect between development and infrastructure teams.
This disconnect led to bottlenecks and delays in the software delivery process as developers needed to wait until the infrastructure changes were completed to deploy the applications. It also limited the functionality and usability of IaC tools.
Modern IaC in GitOps
GitOps allows developers to consider infrastructure changes as a part of the delivery process and integrate them into the same delivery CI/CD pipeline. It has combined infrastructure management and application development.
When a configuration change is needed, a developer will create the configuration and push it to the source control repository the same way software is developed. Then it will be verified and tested through a CI/CD tool, and ultimately the configuration change will be applied to the underlying infrastructure. The best part is that this update can be done through the same CI/CD pipeline used for the software development as an integrated step in the delivery process. The developers can always ensure the consistency of infrastructure as most IaC tools can detect config drift even when conducting multiple developments.
Integrating infrastructure management as a part of the CI/CD pipeline provides both application and infrastructure developers with greater visibility of corresponding modifications. It will also lead to better-optimized applications as infrastructure developers will be able to provide the exact infrastructure configurations best suited for the application changes.
Infrastructure as Code compliments GitOps practices as both aim to elevate the user experience of infrastructure management. GitOps is the natural progression for IaC. Infrastructure as Code is simply a codification of infrastructure management without a proper GitOps based pipeline. GitOps has provided a proper set of guidelines and practices to fully automate infrastructure management using IaC tools.
Conclusion
Infrastructure as Code has become a must-have to efficiently manage infrastructure in modern software development environments. Developers have abundant choices to facilitate their exact infrastructure configuration needs with different tools and services catering to different needs. IaC has come a long way, and the introduction of GitOps has made it the perfect platform to integrate infrastructure management as a core part of the development pipeline.