It wasn’t that long ago that you had to open a ticket to ask for more resources within your company, remember? Infrastructure management has changed drastically in the last decades.
Businesses rarely change their infrastructure... and infrastructures themselves don't change every day. Software installation used to be done manually or semi-manually, with scripts that only worked in a specific context. This model raised a few issues:
- It wasn’t scalable: solving issues became more time-consuming as resources were managed in an ad-hoc way
- It wasn’t replicable: it was challenging to understand what production environments were made of and to recreate it for a pre-production environment
- It used a lot of tooling: internal scripts could not be easily reused in different contexts
Thankfully, the context shifted in the last few years. Churn is now growing as projects rise (and fall) faster than ever. Standard tools are available and widespread. And Ops work is shifting towards automation, which handles an increasingly significant part of the tasks. So it's increasingly crucial to automate infrastructures as applications can be deployed into production up to hundreds of times per day.
Manage and provision your infra automatically
Infrastructure as Code (also known as IaC) is a type of configuration that automates the managing and provisioning of the infrastructure through code - without going through manual processes. There are two types of descriptions you can use. The description of the infrastructure resources hosting the application (your VMs, Bare Metal machines, etc.), and the configuration of the services deployed and hosted on this underlying infrastructure - or software environment (installed packages, configuration files, libraries, etc.).
Track your infrastructure with your code workflow
One advantage of using code to describe infrastructure is that the same tooling is used to write the code: the same editor and the same versioning system - without any additional tools. This will allow you to track changes made to the infrastructure the same way you do with your code.
Once a versioning system is in place, you can centralize all changes to a single point, for instance, GitHub or GitLab. This repository creates a single source of truth. For example, a user could use VSCode to write the code and Git to track it.
Centralization is helpful to track all the changes that were made to the infrastructure. It is also helpful to have all commit messages to help to understand what happened.
From imperative to declarative
In mathematics and computer science, idempotence means that an operation has the same effect whether it is applied once or several times.
Here, we want the actions of our infra as code tool to be as idempotent as possible. So we "ensure the presence of a line in a file" rather than "adding a line to a file.”
This allows us to launch our tool in a loop without the state changing in the absence of updates in the code describing the infrastructure.
This notion is crucial to understand the choices and limitations of infra as code solutions. We do not describe actions, we describe the desired state. Then our tool will infer the actions to be performed to converge towards this state.
Simplify the collaboration between Dev and Ops
When this pattern of version tracking is enforced, the repository that contains this code becomes a single source of truth.
Having this unique point of control on the infrastructure helps to gain insight and discover how the infrastructure is built. Infra as code will become a key area of collaboration for developers and operational staff.
What could be easier than sending a pull request rather than a ticket or an email when you want to change something?
What better way to collaborate than on code, which will be executed as written? The idea is to deliver code, whether it's for the application or the infrastructure, and to let automation do the rest.
This is why this infra as code movement often comes from both developers and system administrators: the former see it as a way to gain certain independence while the latter find it makes their daily lives easier thanks to repetitive and often low added-value tasks.
The objective of the DevOps movement is to align teams with business objectives by improving collaboration between Developers and Operations and by working together to develop infra as code as collective property.
Pet vs. cattle
The teams responsible for internal infrastructure often compare servers to pets and even give them nicknames. They take care of them daily. If a "pet" server goes down, it is challenging to rebuild them from scratch because the internal configuration is not well-tracked. Therefore, those servers are fragile, and as time goes on, they become a liability.
The modern approach is more oriented towards cattle management. The objective is to manage the infrastructure like a herd: your servers are simply assigned a number, and you manage them as a whole. It is not sad to see them disappear, and if one gets "sick”, you simply replace them. This "replacement" in a more concrete context would mean a pure replacement of a virtual machine or the re-provisioning of the physical server concerned.
Each server should be able to be assigned a random and unique identifier. However, this does not exclude having some differentiations! Eventually, these servers will be assigned roles or labels based on their capabilities, such as the presence of GPUs.
Multiplatform VS platform-dependent
Is Infrastructure as Code platform-dependent? The provisioning and configuration depend on the software platform, not the service provider. An Ubuntu machine will work the same way with two different vendors, for example. The dependency will be on the operating system: location of files, commands used... In many cases, automation tools can manage this and abstract it for you. If they don't provide an abstraction, you can always use conditional execution to run only a subset of a given program that targets a specific platform.
For the infrastructure, if your resources are configured for a given provider, you cannot copy and paste it directly to another provider.
Some resources will have attributes that are not the same, depending on the cloud provider. The language used to describe the resources is the same, meaning it will be easy to understand exactly what needs to be migrated.
Infrastructure as Code as a way to align Dev and Ops
When Infrastructure as Code is enforced, development and operational teams are using the same source repository, so both those teams can review and apply changes to them. IaC lowers the risk of misunderstandings as both teams share the context and see the same files.
Grasp the infrastructure and contribute to it
As a result, it is easier to grasp the infrastructure if it is in a written format. This allows whoever has access to it to start reading and understand how the infrastructure and provisioning work. It becomes easier to train many people and, by doing so, reduce the risk of depending on a single person to perform a task.
Test a complete deployment using CI/CD
Having a single CI/CD allows you to recreate a copy of the same infrastructure. For instance, having a copy of the same infrastructure for each client.
It also helps you test whether a given release of your software project will work on a given architecture. You can have a build that will create a copy of your infra, deploy the code on it, and ensure that it runs correctly.
Infrastructure as Code is a new way to provision and configure infrastructure. It is also a paradigm shift towards a declarative way of describing infrastructure and using tools to make them happen.
In our next article about infrastructure as code, we will explain how we use infra as code tools - also start managing your infrastructure using these tool.