
Ask HN: What is the real difference between Terraform and Ansible? - ejanus
I am beginning to learn these tools and I noticed that Ansible is used to configure servers and Terraform does something similar but I can&#x27;t figure what makes Ansible poor choice when doing provisioning? 
NB: I am still learning please bear with my poor use of technical terms.
======
digitalsushi
Terraform is for building infrastructure, you know foundations, skyscrapers,
streets. Build an empty restaurant with a giant yellow excavator (Terraform)

Ansible, Chef are for building configuration, you know menus, staff schedules,
grocery lists. Ensure a restaurant is configured correctly to serve customers
with its wait staff (Ansible)

You can use an excavator to configure the stuff inside the restaurant. People
do it. It's just not generally the most efficient way to do it. And you could
have the wait staff at a restaurant pouring concrete for their second place a
town over. You could do that too, but a lot of people would use the excavator.

So what really makes these tools effective is when you start using them at
scale. They start to become helpful once you realize how much you can do with
how little, and they each have this same strength solving different levels,
and their strengths become weaknesses at the other end.

~~~
gitgud
That's a great analogy. Breaking down concepts like this helps a lot more than
most people realise...

------
jaejae
There are five broad categories of IAC (Infrastructure as a Code) tools:

a)Ad hoc scripts

The most straightforward approach to automating anything is to write an ad hoc
script. You take whatever task you were doing manually, break it down into
discrete steps, use your favorite scripting language (e.g., Bash, Ruby,
Python) to define each of those steps in code, and execute that script on your
server

b) Configuration management tools Chef, Puppet, Ansible, and SaltStack are all
configuration management tools, which means that they are designed to install
and manage software on existing servers.

c)Server templating tools An alternative to configuration management that has
been growing in popularity recently are server templating tools such as
Docker, Packer, and Vagrant. Instead of launching a bunch of servers and
configuring them by running the same code on each one, the idea behind server
templating tools is to create an image of a server that captures a fully self-
contained “snapshot” of the operating system (OS), the software, the files,
and all other relevant details.

d)Orchestration tools Server templating tools are great for creating VMs and
containers, but how do you actually manage them? Handling these tasks is the
realm of orchestration tools such as Kubernetes, Marathon/Mesos, Amazon
Elastic Container Service (Amazon ECS), Docker Swarm, and Nomad

e)Provisioning tools Whereas configuration management, server templating, and
orchestration tools define the code that runs on each server, provisioning
tools such as Terraform, CloudFormation, and OpenStack Heat are responsible
for creating the servers themselves. In fact, you can use provisioning tools
to not only create servers, but also databases, caches, load balancers,
queues, monitoring, subnet configurations, firewall settings, routing rules,
Secure Sockets Layer (SSL) certificates, and almost every other aspect of your
infrastructure

~~~
ForHackernews
This is a good overview, but notice how hazy these different categories are
around the edges.

> not only create servers, but also databases, caches, load balancers, queues

These things are, I would say unquestionably "infrastructure".

> firewall settings, routing rules, Secure Sockets Layer (SSL) certificates

These things are more or less configuration, basically files that exist on the
above.

And yet, as you say, it's common to manage them using provisioning tools like
terraform.

~~~
ethbro
> > firewall settings, routing rules, Secure Sockets Layer (SSL) certificates

> These things are more or less configuration, basically files that exist on
> the above.

Part of the different perspective feels like managed cloud vs on prem.

In the former, these are all actually things to be created, albeit as an
abstraction on the underlying implementation. Which you don't have access to.

In the latter, they're configurations on things you have access to.

------
oneplane
If you are new to both and to IaC and DevOps as a whole:

Ansible is for 'inside' virtual machines or computers, Terraform is for
'outside' virtual machines or computers.

Inside a machine you might have software, configuration, assets. Outside a
machine you might network connections, firewalls, disks, dns etc.

This isn't a comprehensive comparison, but when you start from nothing, it
doesn't really help to do a syntax, provider or imperative vs. declarative.

~~~
bryogenic
Ansible also does 'outside' virtual machines.

See
[https://docs.ansible.com/ansible/2.3/list_of_cloud_modules.h...](https://docs.ansible.com/ansible/2.3/list_of_cloud_modules.html)

~~~
scoot_718
My advice would be to avoid Ansible for that sort of thing like the plague.
All the nice things like idempotency and having the same script for setting
things up and tearing them down no longer function when using those modules.

Essentially you need to 1. do the checks to ensure your playbook won't just
create a new set of VMs every time it's run if they already exist 2. maintain
a teardown playbook alongside your setup one because Ansible is entirely
procedural and the steps would be reversed in that case and 3. do queries
first to determine what actually exists in the cloud and do lots of jinja
manipulations to work on the right things. Did you know EC2 has default
subnets and routing tables? Did you know that the Ansible module will error
out if you try to delete those objects?

If only there was a thing like Terraform that could just rely on a single
description of the setup you'd like. Seriously. There's an Ansible module that
will run a Terraform .tf file, and there's a provider for terraform that will
run Ansible on the servers it provisions.

~~~
PaywallBuster
I think you're exagerating.

I use Ansible to provision dev environments on each PR, it works fine, every
time a deployment occurs Ansible will deploy if required, otherwise proceeded
with the deployment.

Destroying the environment is done separate, triggered by a webhook once the
PR is closed.

~~~
scoot_718
If you're just provisioning software on an individual server, then sure. I
agree. It kinda works okay.

What I'm talking about is using the cloud modules to spin up servers, and god
help you, entire VPC set ups.

~~~
PaywallBuster
Each PR will provision a new server and then configure/deploy.

~~~
scoot_718
So wait, you make a playbook per individual server instance? Why?

~~~
zufallsheld
He didn't say that. He presumably uses one playbook that creates vms and
provisions the software for every PR. With ansible this can be idempotent and
creating vms is by default idempotent.

------
gazoakley
Take a look at this talk - it explains what both tools do and how they can
work together well:

[https://www.hashicorp.com/resources/ansible-terraform-
better...](https://www.hashicorp.com/resources/ansible-terraform-better-
together/)

TLDW; You can do resource management (e.g. creating EC2 instances in AWS) and
deployment (e.g. installing packages on an instance) through both Terraform
and Ansible. Terraform is best used for resource management - the
documentation states using the "provisioning"/deployment function is a last
resort. Ansible is great at deploying packages but less so at resource
management for the reasons you'll see in the other comments. Either use them
together for what they're good at, or use Terraform to do resource management
and other techniques (such as prebuilt images) for deployment:

[https://www.terraform.io/docs/provisioners/index.html](https://www.terraform.io/docs/provisioners/index.html)

Also useful:

[https://blog.gruntwork.io/why-we-use-terraform-and-not-
chef-...](https://blog.gruntwork.io/why-we-use-terraform-and-not-chef-puppet-
ansible-saltstack-or-cloudformation-7989dad2865c)

------
busser
Ansible connects to remote servers to configure them, while Terraform calls
cloud provider API’s to provision resources.

For example, you can use Terraform to provision virtual machines, database
instances, or Kubernetes clusters on AWS. Terraform does this via the AWS API.

In my opinion, Terraform is better for provisioning because of the way it
manages its own state. Terraform remembers what resources it created the last
time it ran, and can edit or delete them according to any change in your
Terraform code.

I like Ansible, but not for managing cloud resources. Ansible has no memory.
For example, if I ran a playbook that installs MySQL, Ansible has no built-in
way to undo this change and bring me back to my previous state.

~~~
user5994461
Ansible has full integration with cloud providers API. It's actually better
for managing instances and highly dynamic resources because it has much better
state management than Terraform.

If you (re)create some EC2 instances with Terraform. Terraform save the ID the
first time they are created (in a state file that needs to be shared and keep
in sync). It goes mental the next time it runs if any of the instances are not
found, or the state file is missing, or some of the instances were modified or
died.

Ansible always lookup what's actually running, instances with the intended
name/tags and match versus what's expected. It skips when it's already there,
it's much less accidentally destructive and never run out of sync.

~~~
lawik
How does the coverage of APIs compare. Just AWS is a gigantic set of APIs. I
see most of what I'd need in the Ansible Module Index but it doesn't seem like
it covers all that is available.

~~~
akvadrako
Terraform has way more coverage. I used ansible for aws a couple years ago and
needed to rewrite many of the modules myself.

Tracking AWS apis is a fulltime job and ansible for clouds just isn’t popular
enough.

~~~
gazoakley
Unfortunately this is true - the Terraform AWS provider has thousands of PRs
closed (and hundreds still open) as proof. Nevertheless, things seem to get
support quicker in Terraform than in CloudFormation.

------
thraxil
I know I'm late to comment, so this will probably get buried, but I think a
key to understanding Terraform and why it is different is to understand that
it's an implementation of the Reconciler Pattern. This is a more useful
distinction than the usual declarative vs imperative contrast that is usually
brought up.

The Reconciler Pattern basically means:

* there is some notion of "expected" state, which is what you define (declaritively) in the configuration

* there is some "actual" state, which is basically what is running at whatever cloud service, etc. you are dealing with.

* the reconciler's job is to query the actual state, compare it to the expected state, calculate the difference (usually in terms of a graph), then make whatever changes it needs to to bring "actual" in line with "expected".

Kubernetes, SaltStack, and others implement the same pattern (just on
different levels of resources) and it's becoming increasingly common and
important to understand if you're working with cloud stuff.

[https://www.oreilly.com/library/view/cloud-native-
infrastruc...](https://www.oreilly.com/library/view/cloud-native-
infrastructure/9781491984291/ch04.html)

------
styluss
Terraform is a declarative way of setting up your cloud infrastructure. You
specify the state you want your cloud to be in.

Ansible is an imperative way of setting up your cloud. You tell it to do
certain things, install this package, copy this over there.

Hope it helps

~~~
PaywallBuster
Ansible is mostly declarative.

by default you use Ansible modules/roles and specify the desired state.

E.g. have these packages installed, have these directories created/deleted.

Use cases not covered by modules can fallback to using shell commands

~~~
piroux
To define something as declarative or imperative, it is important to compare
the definition model to the execution model.

So I would rather say that Ansible is much less declarative than Terraform,
because Ansible tasks (the different steps of an Ansible Playbook) are
executed sequentially.

The tasks of Ansible are its statements, so yeah we would say that each
Ansible task is declarative. And still, a requirement for that would be for
the task to use a module/role which is idempotent, right? Another proof,
Ansible natively offers loop, blocks, and conditional to control the execution
flow throughout its tasks.

(This is not a critic of Ansible. I am happy to use it as is, as a high-level
scripting mechanism.)

------
user5994461
Ansible is really SSH on steroid across multiple hosts, with extra commands
that bash never added. It can configure servers and services. It can also
configure cloud products and it's a better choice than Terraform for many
things because it's more flexible.

Terraform can only provision cloud resources on AWS/GCP/Azure/other. Usually
it gets support first for new products they release. Terraform is very static
(see issues with sharing the state file) so it's more indicated to configure
very static stuff, like networking and subnets.

~~~
dynamite-ready
This is not a bad high level description. I asked myself almost the exact same
question as the OP a year ago, though I had prior experience with Ansible, so
knew what I was getting into.

My advice to the OP, as it's all new to you, is to learn Ansible. It will
require more work than Terraform, but Ansible can be made to perform the same
functions as Terraform, and a heck of a lot more stuff that will prove useful
to you, if you're looking into how to provision cloud instances.

That makes Ansible sound like it's hard work, but it's actually quite the
opposite. It's surprisingly easy to do something useful with it.

Ansible is probably best described as a scripting environment / DSL
combination to help you control multiple machines remotely for build and
provisioning purposes.

You have 2 separate remote machines, and want to install Postgres on both of
them? Use Ansible.

Want to install GIT and then pull your project repo onto two machines? Use
Ansible.

Perhaps you have 3 machines, want git on all 3, but Postgres on only one of
them? Ansible again.

Where there is an overlap with Terraform, is that Ansible can also be used as
an interface to control AWS/Google cloud/Whatever services, which is
Terraform's sole purpose. Terraform provides a cloud platform agnostic
interface to allow you to spin up new cloud instances, and perform some
provisioning tasks, but it will only skim the surface of what you can do with
dedicated Ansible scripts.

~~~
ejanus
I learnt a bunch ...I will build up my knowledge from Ansible first.

------
ForHackernews
Very crudely, Ansible is like a YAML frontend to SSH, Terraform is like a TOML
frontend to AWS CloudFormation.

~~~
lawik
Not quite accurate but very funny :)

------
jonahbenton
There are a lot of answers but none are geared to the beginner. I read the
question as asking for an answer like the below-

To a large degree expressing something is a "poor choice" is an opinion, maybe
expert, about optimizations, not about capabilities.

When one is learning, adopting the value judgements of experts is a form of
premature optimization that actually prevents learning.

The only way to build your own opinions is through your own experience. You
will need to have your own problems, and solve them using a variety of tools,
to build your own opinions.

Try both tools in real problems, and the mental model that accrues in your
experience will start to guide your opinions about ways to optimize your work.

Also- everybody is just making it up. And all tools suck.

~~~
ejanus
Okay...and thanks for being frank

------
Xophmeister
Terraform is best at provisioning "hardware" (physical or otherwise); Ansible
is best at provisioning software.

------
toyg
Terraform is very good when it comes to _declaring topologies_ : “there should
be N items of this type, in this network, with these characteristics”. It
remembers state; as you add or remove stuff to your topology, it will take
care of doing all the necessary work to go from topology A to topology B, and
detect any inconsistency.

I don’t know Ansible much, but I believe it’s more of a procedure-oriented
system, where you declare the steps necessary to reach A, then again to go
from A to B. This can be an issue if any item is actually not in the state you
expected.

------
acd
Terraform tracks and provisions cloud provider state. Ansible you need to pass
and parse Ansible output around which can take considerable time.

Terraform tells how your Infastructure should look like. Ansible what software
should be on your infrastructure/servers.

I tend to use Terraform to describe how the underlying Cloud infrastructure
should look like. I use Ansible to describe and configure what software should
be running on those servers.

Usage cases:

Simply put Terraform cloud infrastructure provisioning. Ansible server
software and configuration files provisioning.

~~~
peterwwillis
Technically Terraform tracks and provisions its own state. The cloud
provider's state at any given time may be different, and Terraform may find it
impossible to resolve the difference, leaving you to manually fix it.

Ansible (mostly) does not refuse to do anything just because the state
changed. If you need to make sure something happens, you can be more confident
Ansible will do it, because it doesn't care what the state was before now.

------
tarun_anand
I like both of them. One thing interesting in Terraform is the ability to say
I want to go from X to Y and see what will be the impact _without_ actually
doing the steps.

Otherwise both are quite good.

~~~
pintxo
Check mode in ansible

> \--check

------
speedgoose
You can use Ansible to provision servers, it works, but if you do that a lot
it's better to use Terraform. With Ansible you are a bit at a lower level and
you need to manage the state of your system yourself. It's fine for 4
permanent VMs but not for more complicated infrastructures.

~~~
eusebius
I'm not very familiar with Ansible but consider it to be somewhat
interchangeable with Puppet (which I use extensively at work). You can
certainly use Puppet to manage thousands of hosts but it entirely depends on
other practices and technologies (an external node classifier in Puppet's
case) to keep things manageable. I assume the same is true for Ansible.

~~~
lukevp
Ansible is agentless, so the management of endpoints is entirely based on your
server doing the scripting. It can use a static inventory file (text) or a
dynamic one which can be served from anywhere (eg, sql query). Whenever you
write playbooks you target groups of hosts based on tagging that’s done
through inventory.

------
sadjunky
Ansible is primarily used for provisioning resources, on the other hand,
Terraform is used for managing and deploying cloud resources. This
differentiation falls fairly well in the concept of immutable infrastructure.

If you're familiar with Packer, then Packer is responsible for creating
identical VM images which can be integrated to a CI pipeline and provisioned
and baked using Ansible. This baked image is then deployed using Terraform.

Be advised that provisioning in Terraform during VM deployment is not
recommended since it increases startup time of the machine. To perform ad hoc
configuration management, you use Ansible.

You could very well use Ansible for managing and deploying cloud resources,
but that's not what it's meant to do. Moreover, Ansible does not support the
concept of state as does Terraform.

------
borplk
They somewhat compliment each other, they are not really alternatives to each
other.

Usually Ansible is used for declaring the desired state of the individual
servers for example you may use it to manage installed packages and
configuration files on the servers.

Whereas with Terraform you declare the desired state of cloud resources for
example you may ask Terraform to give you 5 EC2 instances, 1 RDS instance for
DB and 1 S3 bucket for storage.

There's some overlap between them but what I've said is largely accurate.

------
phedoreanu
Have a look at Pulumi - a modern infrastructure as code platform.
[https://www.pulumi.com/docs/intro/vs/terraform/](https://www.pulumi.com/docs/intro/vs/terraform/)
and
[https://www.pulumi.com/docs/intro/vs/chef_puppet_etc/](https://www.pulumi.com/docs/intro/vs/chef_puppet_etc/).

------
jake_morrison
The fundamental model behind Terraform is declarative. You use the Terraform
language to define resources for your target system, e.g. a load balancer in
AWS. You then run Terraform and it checks the desired configuration vs the
running configuration, and it shows the differences. If the new config is what
you want, you apply the changes, and it updates the production system.

Ansible is much more of an imperative system, sort of "executable YAML". You
define a series of tasks in a YAML file. There are predefined tasks for
standard things that you need to do when configuring a system, e.g. creating a
directory or generating a config file by merging Ansible configuration
variables with template. You can and should make these tasks idempotent, but
as the system gets more complex, it becomes difficult and runtime can be slow
as it compares tasks one by one to the running system.

Both systems suffer somewhat from difficulty in writing code. The fundamental
task is to transform configuration variables and templates into running
resources. To do that, you need loops, if/then/else logic, etc. Ansible has
some constructs, but it is basically string manipulation, with a backdoor of
being able to write modules in python. Terraform has a better syntax to define
resources. Logic is generally things like ternary operator and list
comprehensions. Terraform 0.12 improved this tremendously, but it is still
somewhat weak. Ansible has a bit better management of config variables.
Terraform tends to make you serialize things through environment vars, and
it's awkward to define structure sometimes. Both would benefit greatly from
first class functions and programming logic, even as they are "functional",
just transforming data.

I love them both, and I hate them both. Terraform is best for provisioning
complex infrastructure. Ansible is great for setting up instances, and it's
easy for everyone to understand, dev and ops. Here is a complete example of
deploying a complex, full-featured app to AWS using Terraform and Ansible:
[https://github.com/cogini/multi-env-deploy](https://github.com/cogini/multi-
env-deploy)

I feel like we are suffering through a period where the tools are immature.
People are focusing on syntax, but we are missing fundamental parts of the way
the system should work. [https://www.cogini.com/blog/is-it-time-for-lisp-in-
devops/](https://www.cogini.com/blog/is-it-time-for-lisp-in-devops/)

The exact same thing is going on in the Kubernetes world. Back in the .com
days, we would laugh at the "HTML programmers", but now we are "YAML
programmers".

There are a couple of fundamental ways of managing the new cloud systems, all
of which are better or worse depending on what you are doing. There are
declarative systems like Terraform or CloudFormation. There is imperative with
tasks, like Ansible. There are things that talk directly to the API like boto.
There are tools like Pulumi which take a library approach in a general purpose
programming language. Dockerfiles are crying out for higher level solutions,
which are being developed. Ultimately I like the approach of a dedicated
syntax like Terraform, but with more programming capability, or Pulumi.

~~~
specialist
Your description of Ansible makes me think of the Apache Ant build system.
James Duncan Davidson's post mortem was illuminating. He never intended to
create executable XML scripting.

Am noob. Have done a wee bit of CloudFormation, Docker, k8s. And once
completed a Terraform howto. I've never touched Ansible, Chef, Puppet, etc.

I'd love a feature comparison matrix. Or maybe a decision flowchart on how to
choose which tool for which job.

\--

Update: This comparison was linked upthread. It's pretty good.

[https://blog.gruntwork.io/why-we-use-terraform-and-not-
chef-...](https://blog.gruntwork.io/why-we-use-terraform-and-not-chef-puppet-
ansible-saltstack-or-cloudformation-7989dad2865c)

~~~
jake_morrison
Big fan of terragrunt.

------
piahoo
terraform manages infrastructure (e.g. creating VM). ansible manages
configuration (e.g. installing tools on fresh VM)

~~~
h91wka
To be fair, one can manage infrastructure with Ansible too.

~~~
toyg
And one can manage configuration with Terraform too, via null-resource blocks
and so on.

------
rad_gruchalski
Obligatory plug, you can use both together:
[https://github.com/radekg/terraform-provisioner-
ansible](https://github.com/radekg/terraform-provisioner-ansible) I’m the
author.

