Infrastructure as code - When to use Terraform and Ansible
Here I describe the different problems Ansible and Terraform try to solve and which tool you should start with.
Let's talk about the different problems you can solve with Terraform and Ansible. To some extent, you have the possibility to do infrastructure as code deployment with Terraform and Ansible, but as always each tool has certain pros and cons.
So the question is:
When to use Terraform and when configuration management like Ansible (Puppet, Salt, Chef, etc.)?
What problem does infrastructure as Code, in general, try to solve?
If something goes wrong or you need a second environment in order to test things, you can just replicate your complete infrastructure for disaster recovery or use it as a test environment. It makes your infrastructure reproducible.
You can also easily remove your test environment when you are ready with testing. Infrastructure is expensive and so you can just kill everything when the workday ends and over the weekend. You can recreate it anyway.
You can also be confident about the current system's status. Is the firewall change really applied everywhere? Did you miss a server? Does the load balancer use all webservers as targets? You can look it up in the code.
Scaling is also a big factor. If you are at a certain point in time where you have 50 or more servers, there is just no way to manage all that with dirty bash scripts and SSH into the machines. Please do not do this. The human error potential is just too high and you can never be confident about your system's state. "Pets vs cattle" comes to my mind.
Okay, now when you have to decide what to use (Terraform, Ansible) how shall you decide? In my opinion, you should learn both. You will strongly benefit from this. But there is also time as a constraint. So let's check which tools will solve which problem.
What problem does Terraform solve for you?
In my experience (and opinion) Terraform is really, really good at creating infrastructure. Create a server, attach storage, network, and IPs to the server. The more complex your setup will be the more you will thank the tool.
If you understood terraform it also comes in handy learning other cloud providers. If you used it with AWS and switch over to Azure, Hetzner, or whatever cloud, you will get a quick understanding of their cloud building blocks.
But it comes with a cost. You have to learn the quirks of Terraform and state management. Learn how to write good modules, version them, handle secrets, etc. That is time.
If you have a more or less complex infrastructure with a lot of networks connected to each other, hundreds of servers, databases, load balancers, and whatnot. Terraform will help you make your infrastructure easily reproducible.
If you have just a hand full of servers to deploy in a fairly simple manner terraform is the wrong tool. That is because your problem is not to provision complex infrastructure but the configuration of those servers at this point. In that case, I would just skip terraform (for now) at the moment and do configuration management with Ansible.
You can always come back when you have finished the configuration management and then do Terraform.
Learning resources for Terraform
First of all, HashiCorop started their learning platform: https://learn.hashicorp.com which might be a good place to start.
If you are starting out with Terraform now, please read this awesome resource from gruntwork:
It will save you from stupid mistakes. Like building big modules which will let you cry 100% later in the project if you missed those tips!
Here are the blog posts about Terraform by gruntwork (the book is essentially a more comprehensive version from these blog posts):
- A Comprehensive Guide to Terraform
- Why we use Terraform and not Chef, Puppet, Ansible, SaltStack, or CloudFormation
- An Introduction to Terraform
- How to manage Terraform state
- How to create reusable infrastructure with Terraform modules
- Terraform tips & tricks: loops, if-statements, and gotchas
- How to use Terraform as a team
Terraform Remote State
If you work with Terraform in a team you want to have a remote state. Especially if you work nearly the same time you do not want to apply changes at the same time and delete each other's infrastructure. Locking a remote state is for you.
Also when you work alone on a project you want to have a remote state because your Laptop could break or get stolen and then your state is gone and therefore your infrastructure.
There are a few ways to run your remote state but Hashicorp itself offers a generous free tier for 5 users at no cost (06.08.2021): https://www.hashicorp.com/products/terraform/pricing
What is Terraform bad at?
From my experience terraform is hard to do right when you have a lot of migrations happening. With terraform you describe a state. Terraform abstracts how it gets there for you. That is mostly good. But sometimes you need to go from state A over B to C and that is where terraform gets hard.
Doing a lot of terraform move statements to change resource names is also cumbersome but sometimes necessary.
Still, I think terraform is awesome!
Just a good video about the Gruntwork founder
General tipps for Terraform
- Avoid big modules
- If your Terraform plan/apply does always show you a big diff, think again and maybe restructure. It is always a red flag!
- Use remote state with locking, when working in a team
- Use Terraform target with care!
- Use Git and versioned modules, just do and thank me later
- Version pin all your modules and providers! Otherwise, you could have change where you did not expect change at all
- Use Git branches with care when working on a team and applying. You could delete each other's provisioned infrastructure since you will have not the same files on your machine. More a development problem. Can be solved with pipelines in prod.
- In order to apply and delete your stuff with confidence, you should look into automation and pipelines, and testing
- Testing infrastructure code is hard. I myself did not have the chance to get into it yet. I only know I would look at Terratest (of course by gruntwork)
- Try to have separate accounts for your live production environment and for your testing environment
- Have a real dev environment for your infrastructure as code things to test. Do not confuse this dev environment with the dev environment you have for your software engineers. It NEEDS to be separated. Otherwise, you will disturb software engineers in their development process. This is unnecessary, will cause a lot of friction, and is expensive for the company (people not working)
- Do not always reinvent the wheel and have a look into other modules in the Terraform Registry
- And last a really good talk about Infrastructure as Code
What problem does Ansible solve for you?
Ansible is good at configuration management but not that good at provisioning.
If you want to install packages and set up your server with the right configurations Ansible is for you.
There are of course other tools. Just to name them: SaltStack, Puppet, Chef come to my mind. These however focus on having a central server storing the state and local clients getting the changes from that central servers.
Ansible is only ad-hoc without any server. There is a server component by RedHat but I will not focus on that since I have no experience with that now.
Ansible will help you to replicate the configuration for a server. You create playbooks to target specific machines with specific roles and tasks which then will be executed via Ansible command which only needs SSH access. No server setup is necessary other than having SSH access.
The roles could describe your database server, web server, load balancer, or whatever the case may be. If a server bites the dust you can boot a new machine, target the machine in your inventory and run ansible. In no time you will have your server up and running again. No manual work necessary despite provisioning.
In my opinion, Ansible is relatively easy to pick up and immediately gives you the ability to describe your server's configuration in code. Especially teams or individuals with just a couple of servers have an immediate benefit.
The benefit of having the ability to be certain of your infrastructure and the ability to replicate a server really quickly.
Learning resources for Ansible
I can highly recommend all content made by Jeff Geerling. He is the defacto Ansible guy in my opinion and his book is good!
He also has a nice YouTube channel where we have an Ansible 101 to get you started quickly:
Check out his channel for more Ansible stuff.
General tips for Ansible
- Use roles
- Do not always reinvent the wheel and check out Ansible roles on Ansible Galaxy
- Avoid using the shell or command modules. If you need those be sure that these commands are idempotent
- Idempotent operations can be applied multiple times without changing the result, shell and command statement may not be idempotent
- After development test your changes on a blank system, sometimes you miss something
- Order in Ansible actually is important
Conclusion: Terraform or Ansible?
If you are an individual or small team with just a hand full of servers I would definitely start with Ansible.
Ansible will solve the problem of configuration drift and your pet servers. Not knowing how the state is. Did I patch the latest CVE? Where was that backup directory again? Everything would be answered with a git repository full of ansible YAML files.
The time spend doing terraform for just 5 servers is not really worth it. You could easily spin them up via the web interface pretty fast, put in your SSH key and be done with it for now. I mean if you could do both, for sure do both. But you will get a faster return on investment with Ansible.
Terraform will bring a lot of benefits when having more servers, complex network setups like you can have on AWS VPC with different availability zones, subnets, etc. Then absolutely yes, take terraform!
So that is my take on terraform vs ansible. Great tools for solving different problems.
Enjoy learning them!