Hello Everyone 👋
IaC is basically the way to convert your manual actions to code. GitOps is closely related to this and I will come up with a blog on it soon
What is Infrastructure as Code ?
Infrastructure as Code is basically managing and provisioning infrastructure using code. like we code for software, here we code for infrastructure. You can do it both for on-prem infrastructure as well as cloud providers. For example if you want to provision servers using AWS, Azure, GCP, Civo etc you can just use various tools available to do that and define everything in their code language and enjoy the magic. You can also setup configurations inside these servers. for example if you want to setup docker inside a EC2 instance, you can easily just use the tool of your choice, write in it’s preferred language and you’ll have a docker daemon running in it very soon without manual installation. There’s also a very popular practice known as GitOps which helps in practicing IaC and I will write a blog on it soon.
If you search for IaC tools in the internet, you will come across a lot of tools like :
Terraform
Ansible
Chef
Puppet
Cloud provider’s own IaC tools like AWS CloudFormation
Now, all the tools you see on the internet are a vast ocean of knowledge, and you can refer to their documentation to understand them in depth. Some tools are meant for provisioning infrastructure, and some are for managing configuration inside the provisioned infrastructure. Find the details below.
Approaches to IaC
Every tool you see follows one of two approaches to IaC.
Imperative - Here you describe all the steps to set up the resources and reach the desired running state. Think of it like having a friend who is helping you reach his location. You tell him your current location, and he begins giving you instructions like go 5KM right, then 2KM left, then 100M inside a colony until you finally reach the desired location.
Note the term “current location” because that’s what we need to know to successfully describe all the steps via code. Any changes, and you will have to look at the current setup and describe steps from there onwards. For example, you provisioned two EC2 instances using the setup and now want 3 instead of 2. You will have to write a plan to do a +1 for instances instead of straightaway 3 because if you do that, you’ll have 5 instances (2+3). Chef and Ansible are popular tools which follow this approach.
Declarative - Here you state the resources you want and the desired state. The tool will figure out everything on its own. Take my above example, and instead of a friend telling you the turns at every point, he just straightaway provides you the address. Then you can reach it on your own via Google Maps. Your friend does not need to know your current location or anything for that matter.
If you have any changes here, you don’t have to consider the present state of the infrastructure and just provide the final state via code. The tool will do that for you. For example - You provisioned two EC2 instances using the setup and now want 3 instead of 2. You can simply mention 3, and the tool will set up one more instance. This helps you know the current state of your infrastructure just by looking at the code. Terraform and Puppet are popular tools which follow this approach.
Provisioning vs Configuration Management
Provisioning tools are meant to provision the servers themselves (as well as the rest of your infrastructure, like databases, networking configuration, load balancers, etc.). They do not care about the internal configuration of servers. Tools like Terraform and Pulumi are dedicated provisioning tools and do not provide functionality for configuration management.
Meanwhile, configuration management tools are meant to install and manage software on existing servers. These tools excel in managing configuration inside servers, and you can write a single file and apply it to multiple servers. Tools like Ansible, Puppet, and Chef are popular configuration management tools. Ansible and Puppet also have some provisioning capabilities, but since they are not dedicated provisioning tools, they are not as popular as tools like Terraform for that purpose.
Using tools as a combination
There are popular combinations for server provisioning and configuration management, such as Terraform plus Ansible, and Terraform plus Puppet. For example, you can provision 5 EC2 Ubuntu instances using Terraform and maintain the exact same configuration inside each using Ansible or Puppet to manage the software, settings, and applications within those instances.
Benefits
You do not have to remember the details of the instances you create. You can simply put everything in the code files, for example - Ubuntu with 16GB RAM with some user setup and some firewall rules, and look at it when you feel a bit lost.
You can utilize version control. Since it’s files, a separate repository can be created, which is accessible to all the teams and end users, and can simply be used by anyone to replicate infrastructure provisioning or configuration management. The repository would act as the single source of truth. GitOps is the term for it, and I will write a blog on it soon.
You can easily setup CI/CD Pipelines and this enables automated deployments, error reporting etc
You can avoid a lot of errors by avoiding manual changes. Version control + IaC helps in identifying what could have gone wrong instead of looking up individual errors.
You can achieve uniformity and avoid repeatability in both provisioning and configuration. Suppose you need every instance with Python3 installed, you can do it with just one code file.
You will save a lot of time and headaches. The biggest headache comes only while choosing the right tools in the beginning.
Languages used in Popular IaC Tools
Each IaC tool uses either a Domain-Specific Language, a General Programming Language, or both. This is a major consideration factor when deciding on the tool for your infrastructure.
Terraform uses HashiCorp Configuration Language (HCL) as its primary language. You can also use JSON or Cloud Development Kit for Terraform (CDKTF). CDKTF is not very stable yet and is being prepared for the v1.0 release at the time of writing this blog.
Chef uses Ruby along with its own Domain-Specific Language (DSL).
Puppet uses its Domain-Specific Language (DSL) known as the Puppet language. It also supports Ruby for custom needs.
Ansible uses YAML for playbooks and Jinja2 for templating.
How to Choose the Correct Tool for Yourself ?
I am not making any comparisons here since that would limit the scope to only my perspective. However, I will list some of the factors that are considered:
Open-source vs Closed-source
Languages used and if the team is ready to adapt to them
Master-Agent architecture vs. Agentless architecture
Master-Agent: Requires an additional dedicated master server but provides centralized control and monitoring.
Agentless: Reduces infrastructure overhead but may rely on remote execution protocols (for example, Ansible uses SSH).
Community Size (The stronger the community, the more support and custom-tailored solutions)
Paid vs free offerings
Tool maturity (If it’s stable or in the beta phase)
That's it from my side. Please leave comments if you have any doubts, and I will answer them. Subscribe to my newsletter !
Connect with me on LinkedIn | GitHub.
Thanks for reading :)