DEV Community

Cover image for Making the Right Choices with Infrastructure as Code
Komal-J-Prabhakar
Komal-J-Prabhakar

Posted on • Updated on

Making the Right Choices with Infrastructure as Code

Virtualization is in full swing, prompting businesses to step up the ultimate digital transformation. Companies today perform hundreds of deployments into production per day. Look at this article by Hubspot describing their feat of 300 deployments per day. An increase in deployments has made it important for enterprises to have automated infrastructure scaling. This is brought about by Infrastructure as code that enables you to treat your infrastructure as you treat your application code.

What is Infrastructure as Code?

Infrastructure as code (IaC) enables automated provisioning and de-provisioning of an IT infrastructure with the use of a high-level descriptive code language. It enables organizations to build, deploy and scale cloud applications faster with lesser security risks and reduced costs. Thereby eliminating the dependency on developers to manually provision and manage servers, database connections, operating systems, storage, and other elements of infrastructure, every time new software or code is created.

Usage of cloud configuration tools worldwide in 2022, current and planned
Source: Statista

Why do we need Infrastructure as Code?

For an all-success journey of code from the developers’ environment to the production environment, we need a consistent infrastructure configuration throughout. The best practice says that our test environment and dev environment need to mimic the production environment.

Let’s understand it with an example. Suppose we are building an application on cloud, let’s say public cloud. In this particular scenario, I am considering my application is built on Kubernetes, thus it’s a Kubernetes application stack. For this purpose let’s take a VM which carries a legacy application. Now to connect all of them, we need a VPC (Virtual Private Cloud). And now we have a basic infrastructure put in place.

Basic Infrastructure

Looking forward to testing the application, we all know that the Test environment must mimic the Dev environment.

Environments

This is critical as no matter how well an application is designed, it would break if the environment is different. While building we have definitely documented every aspect of the infrastructure, but does that happen always? Picture this, what if any modifications are left out in the documentation? It’s simple, the application won’t perform.
Imagine, you’re adding a new section to the application that makes the customer experience seamless. To make it happen, we open a communication port on our firewalls and servers of the proprietary protocol and in the process create a change ticket. And you didn’t document it. Well, eventually while auditing, this open port will be brought to question regarding its nature and the reason behind it. On the surface, it doesn’t look like a huge issue, however, if you look through it you need to reason all the time spent by the Security team in tracking the origin of the open port. Had this little thing been documented, you’re not just saving time for unwarranted trouble but you’re also ensuring nothing gets unnoticed. And unnecessary wastage of time.

To solve the problem, this is where we bring Infrastructure as code into picture. There are basically two approaches to bring about this:

  • Imperative Approach
  • Declarative Approach

Imperative Approach

Also known as the Procedural approach.

In this, we dive into specifics, defining step-by-step to develop a certain state of the infrastructure. Now, this approach is chosen quite instinctively by developers. The reason is the control it gives over defining the state and other aspects of every single element of the infrastructure.

diagrammatic reference for Imperative Approach

Advantages:

  • With the power of cloud tools, the definition becomes even more highly customizable.
  • Makes it easier for the administrative staff to understand every inch of detail pertaining to the code developed.
  • That enables them to leverage configuration scripts that are already developed and have been put in place.

Disadvantages:

  • The level of customization and specificity involved in building it makes it a tad difficult to break it or scale it. Basically, developers have to again create custom scripts for every section for either teardown or scale-up.
  • It’s time-consuming, both in the sense of creation and after-creation changes/modifications.
  • If the imperative script is run multiple times we end up having several environments. Suppose, it fails at any step, we have to create custom scripts to teardown completely.

Declarative Approach

Also known as the Functional Approach.

This becomes the most preferred option for the majority of tech teams as it involves only defining the final state of the infrastructure, and the rest is handled by an IaC tool like Terraform. Some popular choice configuration management tools are Puppet, Chef, etc.

These tools enable spinning up a VM or container and installing & managing the different resources by bringing in necessary changes in their configurations.

diagrammatic reference for Imperative Approach

In this approach, we define the resources of all our infrastructure elements. In reference to our above example, we will define the Kubernetes resources, VM resources, and VPC resources.

Advantages:

  • No matter how many times the script runs, every single result will be exactly how we defined it.
  • What simplifies even further is that they are managed with simple config maps. This essentially means we can bring alterations, add or customize changes like defining a host, subdomain, etc.
  • It is easier to have principles like one-click teardown. This enables us to scale infrastructure without the need for custom scripts.

Disadvantages:

  • The prime downside to this method is that it requires the expertise of a skilled administrator. They usually specialize in their preferred solution.

Example to understand the difference between Imperative and Declarative Approach of Infrastructure as Code

This can be analogous to finding a route by GPS or following turn-by-turn directions. If you’re thinking how — then understand how both of these methods work. For GPS, you feed your final destination details, and it automatically maps for you the shortest route with low traffic. Whereas the turn-by-turn instructions are created on the basis of personal experience. To understand why a certain route was taken by GPS, we need the knowledge of an expert. For understanding the turn-by-turn instructions you either need the person who gave them to you or maybe refer to the description provided in the document. Here, GPS is symbolic of the Declarative approach and turn-by-turn directions is the Imperative approach.

Benefits of Infrastructure as Code in DevOps

Faster Time to Market

  • Manually building infrastructure on cloud can be time-consuming and error-prone.
  • Codifying it entirely ensures automated provisioning and de-provisioning of IT Infrastructure. Also makes it easier to scale.
  • Less Configuration Drift
  • Through the version control system, every change, and every detail gets documented.
  • It makes it easier to mirror the Dev environment, test environment, and Production environment.

Reduces Churn

  • If not done through a tool, they get delegated to a few skilled engineers.
  • In this case, if they leave the organization it becomes a tedious task to recreate everything.
  • With infrastructure being treated as code, and automated, it enables the organization to retain the provisioning intelligence.

Improved ROI

  • Through IaC tools we can leverage the power of cloud computing that allows us to have a consumption-based cost structure.

Reusability

  • By codifying every document, it becomes quite convenient to automate the provisioning of legacy infrastructure. This otherwise would have required us to go through a time-consuming process like pulling a ticket.

Best Practices of Infrastructure as Code

Preferring an Immutable Infrastructure Approach over a Mutable Infrastructure Approach

An important aspect to consider while automating Infrastructure is to choose between having an immutable infrastructure or a mutable infrastructure.

What is Mutable infrastructure?

Going by the literal meaning of the word “Mutable” is changeable. So, here we are able to introduce changes/modifications to the infrastructure that is originally provisioned. This level of flexibility looks nice on the surface but considering it practically might make you think otherwise. Why?

  • It undermines the key feature of IaC of maintaining consistency across environments
  • Makes it harder for infrastructure version tracking

diagrammatic reference for Mutable Infrastructure

What is immutable infrastructure?

The exact opposite of mutable infrastructure. The infrastructure that has been originally provisioned cannot be changed or modified. If you want to implement changes, you have to spin an entirely new infrastructure and replace it. This might sound time-consuming and cumbersome but it’s not. With the help of cloud tools — especially IaC tools, spinning up new environments is easier and faster. This option is much more feasible and secure as compared to mutable infrastructure.

diagrammatic reference for Immutable Infrastructure

The reasons why teams prefer it:

  • It prevents configuration drift across various environments.
  • It makes it easier to roll back to any previous versions

Version Control for Infrastructure

In line with the above point of easier rollback, we need a version-control system to store the data of every IaC file. This helps in keeping track of all changes, which further helps team members to work on the latest version. This is similar to how developers record the detail in application source code. In addition to that, it can be referred to in the future to understand the evolution of the current infrastructure version.

Following Modular IaC Rules

It is totally possible to define all the resources or aspects of infrastructure in a single IaC file. To define the type of Operating system to be installed, the category of user accounts to be configured, the applications to install, the networking policies that are needed to be applied, and so on and so forth.

Just because it can be done, it’s not an effective approach to be followed. If we break down these details and define them in separate files or modules, life gets simpler! The teams can easily execute custom changes to specific elements and not everywhere.

To understand better, suppose there are two servers that need to have similar operating systems to be installed but different user accounts. In this usecase, different modules come in handy to implement custom changes.

Treat Infrastructure as Code as an Application Code.

At the end of the day, IaC is a Code that essentially means we can apply the rules of continuous integration, testing, and deployment. We can say that we are putting into the DevOps cycle. Ensuring errorless codes because an error in the IaC file can cost us a fortune.

Therefore, IaC scanning can be incorporated into the CI/CD pipeline which ensures:

  • Compliance regulation
  • No database password or a secret credential exists in the code

Secret Management is Vital

To configure certain resources IaC tools do require access to sensitive information like passwords, encryption keys, etc. Including the secrets in the IaC definitions might look like the easiest way but this is the riskiest thing you’ll ever do. If anyone manages to access the IaC file, they can read this sensitive data.

In view of security, we need to use a secret manager. We have in-built secret management in some IaC tools like Chef-vault of Chef. Preferring a third-party manager like AWS Secret Manager in conjunction with IaC tools is also a wise choice. Thus, secrets can be accessed when required and stay protected from getting exposed.

Managing the Lifecycle of Infrastructure as Code

Infrastructure as code aligns with the DevOps approach, one can otherwise phrase it as “empowers DevOps.” It enables faster deployment with reduced costs and enhanced security. Throughout its implementation, we need exceptional observability and monitoring. A minor error can result in a major liability.

When we are able to treat infrastructure with the same quality as we work with our application code, a lot of changes can be brought in simultaneously documenting every bit. If built with CI/CD pipeline, the code gets subjected to automated continuous testing like comprehensive CI scanning, unit testing, etc. As the software development progress through the pipeline, different team members can integrate custom updates, which is usually the case with changing client requirements. This again gets tested and integrated with the source code, resulting in an updated errorless version of the IaC.

Wrapping Up…

Infrastructure as Code injects efficiency and agility into our product release cycle. The agile practices of Digital Transformation are impossible to imagine without bringing in IaC.
Quick & easier tracking of infrastructure changes and the ease of integrating with CI/CD pipelines, make it vital for building scalable infrastructure. By adopting an enterprise-wide approach to automation, we are not just managing IT processes, but the entire system, teams, and organization.

Top comments (1)

Collapse
 
srshifu profile image
Ildar Sharafeev

Nice article! There is also another way to provision infrastructure simply by drag and dropping blocks on visual canvas, check it out in my article: dev.to/srshifu/build-your-infrastr...