IaC best practices
IaC, like software development, requires the implementation of practices and processes that allow the evolution and maintenance of the infrastructure code.
Among these practices are those of software development, as in these examples:
- Have good principles of nomenclature.
- Do not overload the code with unnecessary comments.
- Use small functions.
- Implement error handling.
But there are more specific practices that I think deserve more attention:
- Everything must be automated in the code: When doing IaC, it is indeed necessary to code and automate all of the provisioning steps and not to leave manual steps out of code that distort the automation of the infrastructure and that can generate errors. And if necessary, do not hesitate to use several tools such as Terraform and Bash with the Azure CLI scripts.
- The code must be in a source control manager: The infrastructure code must also be in an SCM to be versioned, tracked, merged, and restored, and hence have better visibility of the code between Dev and Ops.
- The infrastructure code must be with the application code: In some cases, this may be difficult, but if possible, it is much better to place the infrastructure code in the same repository as the application code. This is to have a better work organization between developers and operations, who will share the same workspace.
- Separation of roles and directories: It is good to separate the code from the infrastructure according to the role of the code, so you can create one directory for provisioning and for configuring VMs and another directory that will contain the code for testing the integration of the complete infrastructure.
- Integration into a CI/CD process: One of the goals of IaC is to be able to automate the deployment of the infrastructure, so from the beginning of its implementation, it is necessary to set up a CI/CD process that will integrate the code, test it, and deploy it in different environments. Some tools, such as Terratest, allow you to write tests on infrastructure code. One of the best practices is to integrate the CI/CD process of the infrastructure into the same pipeline as the application.
- The code must be idempotent: The execution of the infrastructure deployment code must be idempotent; that is, automatically executable at will. This means that scripts must take into account the state of the infrastructure when running it and not generate an error if the resource to be created already exists or if a resource to be deleted has already been deleted. We will see that declarative languages, such as Terraform, take on this aspect of idempotence natively. The code of the infrastructure, once fully automated, must allow the construction and complete destruction of the application infrastructure.
- To be used as documentation: The code of the infrastructure must be clear and must be able to serve as documentation. Indeed, infrastructure documentation takes a long time to be written and in many cases, it is not updated as the infrastructure evolves.
- The code must be modular: In an infrastructure, the components very often have the same code—the only difference is the value of their properties. Also, these components are used several times in the company's applications. It is therefore important to optimize the writing times of code, by factoring it with modules (or roles, for Ansible) that will be called as functions. Another advantage of using modules is the ability to standardize resource nomenclature and compliance on some properties.
- Having a development environment: The problem with IaC is that it is difficult to test its infrastructure code under development in environments used for integration and to test the application because changing the infrastructure can have an impact. It is therefore important to have a development environment even for IaC that can be impacted or even destroyed at any time.
For local infrastructure tests, some tools simulate a local environment, such as Vagrant (from HashiCorp), so you should use them to test code scripts as much as possible.
Of course, the full list of good practices is longer than this list; all methods and processes of software engineering practices are also applicable.
IaC is, therefore, like CI/CD processes, a key practice of DevOps culture that allows, by writing code, the deployment and configuration of an infrastructure. However, IaC can only be effective with the use of appropriate tools and the implementation of good practices.