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.
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.
If you're using terraform with multiple people and are having problems keeping the state in sync I would suggest looking at remote terraform backends and state locking.
For example on AWS we use the s3 backend and a dynamodb table for locking. This way when terraform runs it will first acquire the lock, and then access the state on s3. And everyone is working on the same state.
Ansible doesn't handle the delete case. It has no way to "notice" that a resource is no longer in the playbook and therefore should be removed. This is why terraform keeps it's state file so it can do that sort of operation.
Ansible handles deletion just fine. Provisioning instances for example takes a number of instances, set to 0 to delete them. The more stable resources have a separate command to delete like ec2_vpc vs ec2_vpc_delete.
IMO The way terraform automatically/accidentally delete stuff is a major design flaw, not a feature to emulate. It's madness that it tries to auto nuke potentially a whole company just because it lost track of one resource identifier.
I'm not sure why you've had problems with Terraform trying to nuke things - I'd say the planning capability was one of its strong points. A quick glance at the plan will tell you what it needs to remove to put an environment in the expected state (and it's called out again in the destroy count summary at the end of then plan). Terraform doesn't "accidentally" delete things - it's doing it because you've told it they're not needed anymore.
>> Terraform doesn't "accidentally" delete things - it's doing it because you've told it they're not needed anymore.
That's putting it backward to say the least. One never tells terraform that something is not needed anymore. One declares what is needed and terraform will find a way to get there by altering/creating/deleting stuff.
There is a review phase of course and it's very important because it might do anything. Anybody who's had to use terraform can attest that it is scary to run. Any slight error in configuration or state can be tremendously destructive.
>> There is a review phase of course and it's very important because it might do anything. Anybody who's had to use terraform can attest that it is scary to run.
This is no worse than Ansible - if for a set of EC2 instances the user "set to 0 to delete them" then Ansible will blindly do as requested and be just as destructive. On the other hand:
* Terraform does its best to enforce the recommended plan/apply workflow - the plan is always presented before any changes are made, and auto-approval is strongly discouraged.
* There are multiple options for review - do it there and then, or store the plan as an artefact and share with others for review.
* It doesn't matter when you run a stored plan - the plan is the set of changes that will be applied regardless of current state.
* The summary makes very clear if anything is going to be destroyed in bright red text.
Ansible offers some visibility of what it will do with dry runs, although it's not as complete - there's no way to guarantee it will do the same thing next time if changes have been made in the interim.
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.
Ansible has everything that's needed to automate instances, security groups, ELB, S3, RDS and few more things. I automated all the infra for a startup mainly with ansible (tens of services and a hundred hosts).
Terraform has better support for some static things, mostly VPC, routing tables, gateways. I've had infra retrofitted in terraform but honestly it's more for the show and as a documentation. Low level needs only be setup once and it's always been done manually forever ago.
If you were working around 2014-2017, both tools and many AWS services were new. There were significant gaps in support as well as a few bugs. Had to run from the beta build regularly. It is much better nowadays.
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.
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.