Architectural Design Patterns: Infrastructure as Code
- Posted by Daitan Innovation Team
- On January 28, 2022
- Design & Architecture, Infrastructure as Code
No service will ever fulfill its destiny until deployed, but that’s the easiest step, right? Not really.
Imagine you have dozens of completely different services that require different environments, or maybe you have weekly (or even daily!) deployments. Now think about the amount of work to define and manually manage the configurations for these environments. We can clearly see that this type of activity does not scale well. In this post, we will explore a technique called Infrastructure as Code (IaC), which will help us overcome these challenges.
IaC uses the principle where servers and other infrastructure equipment can be managed and deployed through a set of machine readable files, allowing infrastructure change management to leverage the processes of software development such as code review, static analysis and versioning.
What it Supports or Enables
Infrastructure as Code makes it possible to automate the process of infrastructure creation and configuration, saving a lot of time and avoiding misconfiguration. It also helps with elastic and horizontal scaling, allowing infrastructure to be created and destroyed dynamically, avoiding the need of user intervention during the process. Through the use of immutable infrastructure, it also helps controlling configuration drift, independently of how many instances are deployed in production.
Some techniques, like blue-green deployment and canary rollout, sometimes require your application to be deployed into a different infrastructure for testing and, if everything goes well, be moved to production.
When using microservice architecture this process can become complex and the exact scenario we mentioned in the introduction shows up, since your application release may depend on the deployment of two or more microservices. The process for creating and configuring server instances manually can take a huge amount of time and money, and make those techniques unfeasible.
Now we know the idea behind this methodology, however, not all IaC solutions are created the same. You will often hear terms like “declarative” and “imperative” when discussing this topic.
Declarative IaC defines the desired state of the system, but not how to achieve this state. This method relies on tools to actually create the defined instances. AWS CloudFormation and Terraform are examples of declarative IaC tools.
On the other hand, the imperative method explicitly defines commands that, when executed in the right order, produce the desired state. This method usually makes use of command-line interfaces, like the AWS CLI and Azure CLI, along a command or scripting language.
Both of these methods are perfectly valid and can be used to achieve the same results. But, they have some key differences:
- Teardown: Using the imperative approach, you have to indicate when and how to remove the resource. You need to do this for every resource you create. With the declarative approach, teardown is already included for free, as it keeps a clear view of the components and tools are smart enough to deal with this process.
- Idempotency: Whenever you deploy using declarative IaC you get the same result. To achieve this behaviour using the imperative method, you need to write conditions like if-already-exists-don’t-perform, which is often an error-prone and difficult task
- Configuration Drift: The environment changes over time, creating a unique configuration that cannot be replicated anymore. This is often a problem when not using IaC, but in reality, it also affects those using imperative methods.
It’s important to know that these methods can be used together in a hybrid approach. Some tools, like Ansible, Chef, and Puppet, even provide support for both methods, and it’s up to you to see what works best for your case.
When to Use
As mentioned before, infrastructure as code allows the servers to be created and replicated in an automated way, helps the service to scale and avoids misconfiguration. Knowing this, there is no downside in adopting this technique. However, the adoption of this technique is questionable when applied on short living projects, like proofs of concept or prototypes, since those are not supposed to be scaled or maintained for a long time.
Adopting in a greenfield
Applying laC in the beginning of the project means that nothing should be done manually or outside of the code that will get your infrastructure up and ready for use. Even the most simple tasks like setting a flag on the server, that will only be done once, must be done by laC.
This culture can be enforced by removing the permissions from the team to change infrastructure components manually and replacing it with continuous delivery tools.
Adopting in a brownfield
When an environment is already configured and running without a code to do that, the complete migration to laC may take some time and should be done gradually.
The rule of “each new infrastructure component created must be done by code” can be adopted in order to have a code that will handle all the new servers and, after that, the migration of the pre-existent infrastructure can be planned.
Another strategy is to adopt the immutable servers technique, which means that the old servers can’t be changed manually. If a server needs to be altered in some way, code must be written to get this server up and configured correctly.
- If you will start a new long term project, the rule of thumb is “the sooner the better” for automation, including IaC
- In a brownfield, start applying IaC using a gradual strategy
- IaC is required to implement some deployment techniques, so using it may open the door for new strategies
- Declarative IaC offers more robust control over the infrastructure than Imperative IaC, but both can coexist depending on specific needs
- There are very mature tools to assist in this journey towards IaC
This article was written by João Pedro São Gregório Silva, from Daitan Innovation Team and co-authored by Isac Sacchi Souza, Principal DevOps Specialist, Systems Architect & member of the Daitan Technology Council. Thanks to João Augusto Caleffi and the SRE/DevOps Community of Practice for reviews and insights.