Infrastructure as Code - Best Practices, Benefits

Infrastructure-as-code (IaC) is a very important concept to understand in the DevOps world today. It has become almost ubiquitous across the industry and is absolutely key to modern engineering roles.
What Is Infrastructure as Code (IaC)
Put in the simplest terms, using code, you define the infrastructure that needs to be deployed in a descriptive model. Similar to code for applications, the code for the infrastructure becomes part of the project and is stored inside your version control system (or VCS).
For example, consider that you have developed a web application. That web application needs to be hosted on infrastructure somewhere to be consumed. Using IaC you could define things like where the infrastructure is deployed to, such as a public cloud provider like Microsoft Azure, Amazon AWS, or Google Cloud, and what type of service your web application will run on, such as an Azure web app, or an AWS S3 Storage account. Further to this, you can then define the settings required for the web app, which might include things like how much server compute power is required (in terms of CPU and memory), how the networking is secured, and how the domain name for your app will be exposed, to name a few among many other considerations.
Infrastructure-as-code (IaC) is a very important concept to understand in the DevOps world today. It has become almost ubiquitous across the industry and is absolutely key to modern engineering roles.
In this post, I will explain what IaC is, what its benefits are, some of the tooling options available, and point out some best practices along the way. I will then look at some code examples for each tool to compare and contrast.
You will learn:
What Is Infrastructure as Code (IaC) Benefits of Infrastructure as Code Challenges and Limitations with IaC Why Should I Store My Infrastructure as Code in a Version Control System (VCS)? Declarative vs. Imperative Approaches Infrastructure as Code Tooling Infrastructure as Code Examples What Is Infrastructure as Code (IaC) Put in the simplest terms, using code, you define the infrastructure that needs to be deployed in a descriptive model. Similar to code for applications, the code for the infrastructure becomes part of the project and is stored inside your version control system (or VCS).
For example, consider that you have developed a web application. That web application needs to be hosted on infrastructure somewhere to be consumed. Using IaC you could define things like where the infrastructure is deployed to, such as a public cloud provider like Microsoft Azure, Amazon AWS, or Google Cloud, and what type of service your web application will run on, such as an Azure web app, or an AWS S3 Storage account. Further to this, you can then define the settings required for the web app, which might include things like how much server compute power is required (in terms of CPU and memory), how the networking is secured, and how the domain name for your app will be exposed, to name a few among many other considerations.
Benefits of Infrastructure as Code
IaC solves many common problems with provisioning Infrastructure.
- New environments or infrastructure can be provisioned easily from your IaC configuration code. Infrastructure deployments with IaC are repeatable.
- Manually configured environments are difficult to scale. With environments provisioned using IaC, they can be deployed and scaled rapidly.
- If you want to make changes to the existing infrastructure that has been deployed with IaC, this can be done in code, and the changes will be tracked.
- When IaC is used with a declarative tool (it describes the state you want your environment to look like), you can detect and correct environment drift. If a part of the infrastructure is modified manually outside of the code, it can be brought back in line with the desired state on the next run.
- Changes can be applied multiple times without changing the result beyond the initial application. This is known as idempotence.
- Avoid manual configuration of environments which can typically introduce mistakes due to human error. With IaC, these can be avoided.
- IaC is a means to achieve consistency across environments and infrastructure. The code can be reused.
- Infrastructure costs are lowered as the time to deploy and effort to manage, administer and maintain environments decrease.
- IaC can be used in Continuous Integration / Continuous Deployment (or CI/CD) pipelines. The main benefit of doing this is to automate your Infrastructure deployments.
- DevOps teams can test applications in production-like environments early in the development cycle.
- With your Infrastructure configuration code held in your version control system alongside your application source code, commonly in the same repository. Now everything can be held together.
- Productivity will increase due to a combination of all the benefits of using IaC.
- As the code is held in your version control system, it gains all the benefits of the VCS.
Challenges and Limitations with IaC
The adoption of IaC is not without its challenges.
Typically, traditional infrastructure or operations teams within organizations may not be familiar with version control systems, use of Git, or be comfortable using tools for code editing such as visual studio code.
Further to this, there is certainly a learning curve when it comes to the adoption of new technology within an organization. Training will be required and time will be needed to develop the appropriate skills.
Skills in IaC and DevOps are currently highly sought after in the industry and so therefore it may be difficult to hire staff with these skills.
The journey to managing your environments using IaC will typically start with a small deployment of new resources to your chosen cloud platform, and from there once adoption within the organization grows, more of your infrastructure can start to be deployed and managed in code. Eventually, when your organization is mature and comfortable with the principles and operation of your chosen IaC systems and tooling, existing resources can be brought under IaC control.
Why Should I Store My Infrastructure as Code in a Version Control System (VCS)?
Without diving too deeply into the benefits of using a VCS in this article, we will summarise them here as storing your IaC in a VCS automatically gives you a raft of additional benefits.
In summary, a VCS enables developers and organizations to work more efficiently in improving the quality of their product while recording and evaluating a detailed history of their improvements that will lead to a successful end product. In short, using a VCS enables governance, versioning, and increases collaboration.
Efficiency
As configuration files are amended incrementally with changes, testing becomes easier as rollback to previous versions is possible. New features can be built up over time.
Tracking & Versioning
Track who made the change, and in which version of the file. Comments can be added to each code change (or commit).
Collaboration
Multiple people can work on the configuration files at the same time using branching. Changes can be merged together using pull requests.
Governance & Compliance
Tracking changes automatically gives you a powerful audit trail, enabling risk management.
Management
A management overview becomes possible through being aware of the author of the configuration, how long it took to make changes, the timeline and its impact.
Reduces Duplication
Multiple and out-of-date configuration files are reduced.
Backup
Users will typically clone the repository their configuration code is held in and work on it locally. The code then exists locally and in the VCS. The VCS itself is also backed up.
Declarative vs. Imperative Approaches
There are 2 approaches to the templates used when writing IaC configuration files. Different tools use different approaches, which are listed in the next section.
Declarative — you define the desired state of the final solution.
The tool or automation platform determines how the goal is reached, the step-by-step executions are handled by the tool and hidden from the user. Declarative tools are the most popular and most dominant in the IaC space. They are most useful when changes or updates need to be made to your solution.
Declarative tools are idempotent because you are defining the required state of the solution. Idempotency refers to a process that can be executed multiple times with the same result.
Imperative — you define the steps to execute in order to reach the desired solution.
An imperative approach allows you to build up multiple layers of commands to reach the end goal. Imperative tools give you more control over how the goal is reached. These tools are most useful when you need to deploy and not update or change the solution in the future.
Imperative approaches may not lead to idempotency, the end goal may be different depending on the starting point, as a series of steps form the process. Consider a process with 10 steps, for example, starting from step 1 would lead to a different result compared to starting with step 6.