Infrastructure as code is managing and provisioning of infrastructure using code (basically property files and configuration files that define your setup and configuration files for the software you plan to use on it) instead of manually doing it. Using an automated method to handle your infrastructure saves a lot of time that lets you do amazing things like setup a whole development test infrastructure for testing on a whim before rolling out a product, update, software, etc. However setting up the automation takes time and usually the people who dont realise its benefits are people who have not set up and disassemble infrastructure on a whim and as needed for many many different things, from migration a production to speeding up the setup for testing, and for trying out many different things. While some organisations may maintain a static infrastructure setup for production and development, not everyone needs and benefits from an automated setup since they may never need to apply changes on a whim. It is not worth the time and effort to automate your infrastructure if you rarely apply any change to it and your infrastructure isnt big enough that the time spent automating would save more time than manually setting up individual parts of it. The benefits of automation depend entirely on how they use the infrastructure, how often they need to change things, whether or not they need to constantly create and destroy infrastructure for testing and development and how big their infrastructure is especially for deployment. Automating 100 servers for production may take less time than manually configuring 100 servers in production, but it might not for just a few servers that rarely ever change.
Here we will compare a few well known tools used to do this. These tools make doing so easily without having to use bash scripting or actual coding using something like python instead. Theres a lot of manual process that goes into setting this up, so it does not mean just using a tool and instantly getting things done in seconds. The configuration must also first be tested manually before the tool can be applied in deployment as well.
Ansible uses SSH to connect and perform tasks on the host we want. Because it uses SSH, it is compatible with almost all platforms both linux and not. For instance you could use this to automated the setup of mikrotik since even mikrotik does have SSH but mikrotik does come with its own tool for automating its setup. Mikrotik is just one example that is typically used in large scale deployments on bare metal, and the setup of a deployment can involve many steps as devices may only come into network reach only after another has been setup. Ansible uses plugins for dealing with the various functions and softwares you may want to install and set up, even updating packages through apt exists a plugin on ansible. To use ansible you need to install the plugins you want to use on a host that will run ansible as a deployment server which will then contact other hosts you want to deploy on. These plugins/modules need to be configured using a properties file written in YAML that defines the configuration/commands that will run on them. You will also have to define the hosts that ansible as an inventory. Ansible works by logging into hosts defined in the inventory, preferably using SSH keys and pushing the config from the server to clients. Unlike many IAAS solutions, ansible is free, and does not require any prior configuration on the client. Once your OS is installed with the SSH server, you can begin deployment. I consider Ansible to be a fundemental to know since it is not only free, but for linux servers requires no prior setup except installing the OS with SSH enabled.
Puppet is a non-free alternative for IAAS, and takes the opposite approach to ansible. Instead of a server pushing updates to clients, clients request updates from the server. The difference here is you do not have to set up firewall traversal prior (though doing so would be my preferance to create a secure networking layer for communications) but you end up spending more time setting up puppet on each new node you create. Puppet is a lot older than ansible with a larger user base and uses their own declarative language (ruby DSL) to define configurations and properties which to some may consider it easier than YAML to debug. Since puppet is not a free software, a lot of effort was put into making it easy to use such as providing a GUI for administrators.
Chef uses the master client method of pushing configurations, and requires installing an agent on the client first. Chef like ansible is free and opensourced but instead uses ruby DSL like puppet instead of YAML. Unlike Ansible, authentication and validation of the source is done with the server and not with the playbook in the case of ansible. For many other things, chef tends to be similar to ansible, for instance while ansible uses playbooks, chef uses cookbooks but they perform the same thing.
Terraform unlike the others uses a language it invented called Hashicorp Configuration Language (HCL). Terraform is mainly focused on infrastructure provisioning by focusing on existing cloud providers rather than software. Hence unlike other solutions terraform cannot deploy software, only services and infrastructure that is offered by other cloud providers. Terraform uses a declarative model unlike the other solutions which tend to be procedural which can at times be a disadvantage when dealing with complexity.
Saltstack like many of the solutions uses an agent based master method as well and using its own messaging protocols and APIs as well. Unlike ansible it is heavily bloated with a focus on features and ease of use compared to ansible. However saltstack suffers from a lot of issues despite being heavy in comparison, from lack of backwards compatibility and security issues. Although some might think saltstack is more suited for integrating with code in software, it’s not true either as you can integrate any of the solutions open sourced or with API into your software.
One could argue that you can achieve better automation by combining tools even bash scripting. In my opinion it is better to avoid combining tools to reduce the amount of overhead in the number of tools you need to learn and manage. One example would be using ansible to install the IAAS agent of your choice and then proceeding from there with the IAAS tool you want.