I honestly love Terraform as a product. It was one of probably three tools I've used in my entire career that made me feel immediately more productive. After using it for a very short period of time I was shocked developers continued to struggle through CF templates and the fragility the whole process entailed.
Viewing Terraform solely through the lens of cloud automation and in comparison with CloudFormation is a shortsighted mistake. Terraform has providers for plenty of other services that don't qualify as "cloud things" and lack proper configuration of their own. In a very general sense, Terraform is a terrific resource management tool with state versioning & locking built in. For example, there's a terraform-kafka-provider[1], which can be used to manage topics in a Kafka cluster. Could shell scripts be written to accomplish the same goal? Of course. Would those scripts inevitably develop in a haphazard, organic way to form a buggy and incomplete implementation of something like Terraform? You bet!
"Cloud" configuration may have been Terraform's proverbial toe in water, but the truly untapped potential lies in the other providers. Anything that can be packaged as a Terraform provider exposing resource abstractions can be easily managed using convenient HCL syntax. This, IMHO, is the unfortunately buried lede.
Someday folks will rediscover the potential of Puppet for these use cases. Until then, I'm content to watch countless alternative implementations come and go.
Before using Terraform I tried to use Puppet to manage AWS infrastructure. It was a fun but short adventure.
The idea of having all your configuration in one tool is nice but Puppet just isn't that tool. The one thing I found lacking the most, which made Terraform the tool for the job, is awareness of state. Having the triangle of what configuration you want (HCL), what configuration you expect to have (state) and what configuration you actually got (real world), with the tools to observe the differences between these and the ability to make careful changes is just what you need for important infrastructure changes.
With Puppet every change felt like Fire-and-pray. Sure you can run a 'noop', but if anything changes in between that and the actual run that could trigger another resource you would be catch by surprise. On OS/App level the impact can often be contained, but on infra, not so much as you would have reduce the powerful features of Puppet to much as to it not being a benefit anymore.
You are implying that people who use Terraform are not aware of Puppet. Puppet is a terribly complicated thing compare to Terraform. We use both on a daily basis and everybody agrees that we need to move away from Puppet. Terraform + Ansible is the way for us to go.
It is nice that puppet defines a graph of dependencies compared to doing this in ansible.
What I find tough is that you have another indirection when using puppet to configure your tools. So you first have to figure out the puppet module’s configuration and how it maps onto the actual tools configuration
Wonder why you got downvoted, as someone who has been using ansible for years to accomplish what was said and what you accomplish with puppet I wonder what I am missing out of terraform
The nice thing about Terraform (and Ansible) imo is that they don't require a daemon but just run locally (or on CI), with some shared state in a object store.
Doesn't puppet only support success/changed/error status for resources? How does it work with AWS infrastructure where you may need to possibly remove dependencies before the change, update the resource in place, or update other resources to point at what you just created? You need at least 5 states, I believe? (That depend on properties, not resources, so notification is not enough)
I wish we could add providers by having terraform load python modules (or tcl, lua, js) and call it a day. Instead they chose to offer a statically-linked binary that forks gRPC plugin servers, and supporting that looks like a hell of a lot more work than writing and running a script.
this is short-sighted. Terraform and CloudFormation are not even in the same league. One of them works and actually can be used for Infrastructure as Code, the other one does not roll back in the face of failure - it effectively craps for reasons ranging from network failure, process crash, even normal operation.
One is heavy kool-aid with bugs that go unresolved for years, the other behaves as advertised.
Sorry, but I have yet to meet a developer that used Terraform and willingly wants to keep using it after seeing it fail. When your tool cannot keep track of the resources it created or when it gets into situations where it doesn’t allow you to do certain things (like deleting all resources created) and you have to relearn how the underlying cloud works, it’s time to move on.
Do yourselves a favor and use Cloudformation (or your favorite cloud’s equivalent and just move on with your life)
I mean, this is harsh, but there's a running joke that the big feature terraform is missing is a -twice flag so that it'll re-run itself on failure, since that's what you end up having to do anyways.
Also, the terraform language, HCL? It's, I guess there's no better way to put this: not good.
Am I misunderstanding the complexity of what Terraform is trying to do? To me, it looks like a bunch of tiny API clients tied together with a topological sort --- in other words, it's just another species of "make". It feels like it carries a whole lot more complexity than that concept warrants, but just enough simplicity to make it not a serious programming language. It's, to me, one of those frustrating uncanny valley systems.
Yeah, HCL's limitations have been an enormous thorn in my side for a long time. HCL2 (Terraform 0.12) is a big step forward, but even still I pine for a proper programming language, even if it has foot-guns.
I do think you're selling Terraform short, though. Sure, the core is the toposort-create-things. But it also stores the state of its created things and (crucially) has the ability to diff the actual state of resources against what it thinks they ought to be.
Being able to inspect existing resources and diff state is also what lets it import existing resources, so that they can be Terraform-managed going forward.
Terraform is also capable of determining if its planned changes can be performed in-place or if they require resources to be destroyed and re-created. That boils down to a boolean flag on a field, ultimately, but it's still something a dead-simple make clone probably wouldn't do well.
I've only really used Terraform seriously for AWS, so I'm not sure about the other providers, but the Terraform AWS Provider has an enormous amount of work behind it. Basically every resource API has schema validation written in the AWS provider, and depending on the resource there are often eventual-consistency issues handled by the provider. See for example [0].
In contrast, AWS CloudFormation: can't import existing resources; isn't always sure whether an update will require replacement or not; and, as of ~6 months ago, can detect configuration drift, but not correct it (!). Of course, CloudFormation wins in other areas...
CloudFormation has an “easy button” if you are part of an organization with a business support plan from AWS. If you can’t figure out something you can submit a ticket and start a chat.
Also CF is the “native” language of AWS. There are plenty of getting started examples from AWS where they give you the template. Also Elastic Beanstalk extensibility is built on top of CF.
Not to mention Codestar that will set up environments for you for common use cases and exports templates and the lambda environment lets you configure everything from the console, test it and then you can export the CF definition.
Like one sibling comment mentioned, getting support from AWS is nice. You can buy Terraform support, too, but knowing HashiCorp it'd probably cost more than most peoples' AWS bills in their entirety. (This is me being a little cheeky and unfair—HashiCorp handles community support via GitHub Issues for Terraform really well.)
CloudFormation's built straight into AWS, so there's no need to set up state file storage or locking or worry about a state file at all, really. This has its own set of drawbacks, but it's nice for getting started, and in theory it makes CloudFormation more robust out-of-the-box.
CloudFormation StackSets are really nice if you have identical resources that need to be placed in many different regions and accounts. (Example: we use it to place GuardDuty and Config, both regional services, in every region.) With Terraform, this means copy-and-paste, as far as I know, though maybe Terraform 0.12 sets up the groundwork to make this better?
The Service Catalog is basically a way to let technical end-users manage products via CloudFormation templates. Something could be built to do the same for Terraform, but I don't think there is anything like that right now.
CloudFormation does (attempt to) roll back to a known-good state if an update fails. Terraform just stops in the middle of what it was doing. I have mixed feelings about that.
I find YAML to have better tooling/editor support than HCL, though I actually prefer HCL.
There are existing CloudFormation wrappers (e.g. Troposphere) that can give you a full programming language on top of CloudFormation. To my knowledge, there isn't anything similar for Terraform.
Some things that have changed with 0.12:
CloudFormation has had `AWS::NoValue` for as long as I can remember. Terraform <=0.11 had special values (like empty string, number zero, etc.) that were special-cased as no value. Terraform 0.12 now has `null` properly.
Terraform <=0.11's ternary operators were maddening because both sides were evaluated, which led to errors, unlike CloudFormation's !If. In Terraform 0.12, the ternary only evaluates one side.
Cloudformation will leave your infrastructure in a consistent state. Period. It will consistently drive things from point A to point B or rollback to point A if it cannot get to B. It will also correctly remember all the resources it created and allow you to properly identify them and/or delete them. These sound like tablestakes but Terraform cannot do this. Add the frustrations of HCL on top and it’s a big no go for me.
I've had CloudFormation fail to roll back plenty of times, though never in a situation where it actually mattered.
I've never had Terraform "forget" resources or disallow me from deleting them (unless I requested that). Maybe those are bugs that've since been fixed?
It sounds like we've had very different experiences with these tools.
My experience with CloudFormation has been consistent with what you just said. CF will fail to delete resources and then lock them in that state, requiring AWS tickets and reps and all that. I have not had anything like that in TF.
> can detect configuration drift, but not correct it
if by "correct it" you mean update the current template to match what's there, that'd be good, as AFAIK there's no easy way to do this at the moment. if by "correct it" you mean revert or change resources, no thanks. that sounds like a production accident waiting to happen, and you can un-drift (?) resources manually already.
I do mean revert or change resources. Making manual changes outside the context of an IaC tool is largely madness, in my opinion, although sometimes the situation warrants it.
Auditability and controls are one of the many facets of IaC. We require code changes to be approved by another developer, and similarly we require infrastructure changes to be approved by another developer. Regularly working outside the IaC tool would be in violation of that policy.
It's in this approval step that the change-set (CFN) or plan (Terraform) should be carefully reviewed by a human. If someone's made manual changes, reversion of them should appear here, and those should be unusual and eyebrow-raising. At that point, it's either fix the IaC definition of the infrastructure, manually un-drift it as you say, or do some workaround to ignore specific changes.
(To reiterate, IMO no one should ever run CFN/Terraform unattended on prod infrastructure, and there should always be a step to review the change-set/plan.)
I'll also say that the sword cuts both ways when it comes to prod outages and manual changes. Not so long ago, I ran into a prod-impacting issue when turning on multi-AZ for an RDS instance. In the other regions that had multi-AZ enabled, someone had manually added an extra parameter to the RDS parameter group, one that was required for certain app functionality to work. No one ever added it back to CloudFormation and that knowledge was eventually lost. When we enabled multi-AZ in a different region, we expected no problems at all, but instead we ended up with a whole section of app functionality breaking.
(This would've been before drift detection was a thing in CloudFormation, but actually I don't think RDS parameter groups are supported in CloudFormation's drift detection right now anyway. [0])
detecting resources that are already there may be useful in a limited set of scenarios (prototypes / retrofitting) but definitely should not be the way you build things. thinking through what your cloud infra is doing and expressing it is the way to go.
there is also a way to do this for cloudformation. look up cloudformer.
I agree, importing resources is a limited use-case. However... it's one I find myself in more often than I would like. Reality is often disappointing. At least, with the companies I've work(ed) with.
That said, I don't think CloudFormer does the same thing. I haven't used it before, so please correct me if I'm wrong, but to me it looks like it takes existing resources and generates a CloudFormation template out of them. But then you're still expected to upload that template and create a new stack, with all brand-new CloudFormation managed resources—is that right?
So for example, CloudFormer for an RDS instance would probably be a no-go.
In the Terraform case, after you've imported resources, there's no need to re-create them. There's the question of if what's in the template will match what the resources actually are, but there are also tools to generate Terraform templates straight off resources.
Well said. Its basically ANT for the cloud, in that its an annoyingly limited DSL with just enough power to work, but in a verbose and frustrating way.
Speaking of real code (not YAML or HCL) as infrastructure, anyone have experience with Pulumi?
I've been using Pulumi for a few weeks now and it works pretty much exactly as advertised (for AWS at least). I am yet to run into any major hurdles and for any minor issues I have had the Pulumi team have been very responsive (they have a public Slack channel available).
It actually uses terraform's API's under the hood which is comforting in a way because you know it's building on a solid foundation.
I would not go back to writing HCL after experiencing Pulumi if I can avoid it, using a "real" programming language just feels a whole lot more natural and allows for much more powerful abstractions.
It basically depends on the formation of your team.
A bunch of oldschools sysadmins who "don't code"? Terraform is ridgid and on-rails enough that it probably helps sort of keep things sensible compared to just using boto. Almost like it was a framework, specifically defined to do that sort of thing.
It does sort of suck though, but what sucks less?
Edit: My solution is to stick as much as possible into k8s, but obviously that comes with its own warts, and to be fair to terraform, a lot of terraforms warts are just the underlying API warts leaking through.
The most sensible way I’ve used TF was to create an api for others to consume, containing models of terraform modules.
Users can pick and chose what modules, how many and set some params which are then validated.
The components are then rendered as json, fully declarative, no counts, no fancy TF hacks.
Data sources and a couple of home grown providers take care of whatever needs to be dynamic.
This way a lot of foot-guns are removed for consumers, and it simplifies the whole thing.
At the expense of writing some code... worth it though, in a more enterprisey setting.
No, it's pretty straightforward, terraform is just intended to parse and execute random functions in a graph generated by a template language. It is absolutely a form of 'make': overcomplicated and generic to serve the needs of supporting random companies' infrastructure as versioned code, without having to write the implementation bits.
It's a good idea and not a bad design, but the user experience is pretty bad and nearly all the operational aspect is an afterthought. It was not built to be sold as a product, hence it kind of sucks as a product, but it's fine as a free tool. The fact that it's the best free tool we have for this task speaks volumes about how most companies are deathly afraid to work as a community to build better solutions.
Well, judging from the release notes, with for-loops you are now one step closer to a real programming language. Looks like the beginning of the end of the "declarative" paradigma which keeps people running their heads against the wall like this https://blog.gruntwork.io/terraform-tips-tricks-loops-if-sta...
the complexity of Terraform does not come from the happy path. It comes from when things go wrong and now you have to understand what went wrong and how to correct it. Now you’re in a world of pain since TF just throws its hands in the air and you’re left holding the bag.
i have hear several people referring to terraform as Terrafail. I have also observed good dev/devops people struggling to make it work when shit hits the fan.
Well, if you don't follow the obvious advice of storing your state in a S3 bucket... If the idea of storing your state somewhere is so abhorrent for you, you can also tag your resources and import them with Ansible/Bash as per the obligatory CloudFormation workflow. Then your state becomes local-only. That's a pretty useless thing to do for purely ideological reasons, though: storing your state in a cloud-agnostic way is what allows being able to manage a Gitlab repo, a Cloudflare domain and AWS or GCP instances in the same tool. That is what the "multi-cloud" means.
If you are saying a nonsensical argument like "not IaC because it can't rollback" I can say CloudFormation is not IaC because it can't even import a local file to grab some values. Or run external commands
Agreed about CF. AWS puts a huge emphasis on CloudFormation when they know it is sub-par. Ansible is pretty cool too because you can easily convert between YAML/JSON for CF, and add a lot of flexibility based on variables and other things such as error handling that you can't do with Terraform.
I don't agree it is subpar. I have a fairly long list of reasons for preferring CF over Terraform. I agree on combining CF with Ansible though. My recipe is to wrap a CF template in an Ansible role. It makes for a versioned chunk of automation that composes well with my other roles, including ones that are not CF based. Plus I can do non-CF setup tasks using any Ansible module, and even run tests, to get pretty much full end-to-end automation for a given stack. I haven't found a way to get the same degree of power and flexibility from Terraform without resorting to writing custom plugins.
My experience of TF is very much the opposite. It looks fantastic on paper (well, in the browser) and I was excited to start using it. But the shine quickly wore off. It claims to be multi-cloud but it's not as if you can take some TF from AWS and run it on Azure - it's a rewrite. And it claims to be able to import existing, running cloud configurations so migrating to it should be easy, but it doesn't work, so that's a rewrite. And it is terrible at modifying existing things, the developers of TF seem to be believe that destroying everything and rebuilding from scratch is the way to, say, add another node. Of course by the time you figure all this out you have invested so much political capital in persuading the organisation and your peers to adopt it that you're stuck with it. But the lesson is really, use whatever is native to each cloud, such as CF on AWS, beyond any trivial deployment you're locked in anyway, might as well enjoy it.
I'm an ex Googler and 2nd time founder of a company in the computer vision / robotics space and started hacking when I was 14. I'd consider myself pretty knowledgeable in my area -- yet, I must admit that I have absolutely no clue what Hashicorp and Terraform do and why everybody likes it.
I am very curious though. Would you mind explaining this from a high level (to someone who knows cloud technology about as well as your dog)?
Terraform serves to translate a descriptive statement about a desired infrastructure state into the sequence of API calls that will bring about that state.
Given something like
"I want three auto-scaling groups, each containing a minimum of three instances of type m4.xlarge, in the AWS us-west-2 region. And I want an S3 bucket that has permissions set up so that only the code running on those instances can read and write to the bucket. And I want a load balancer between all of them. And I want the instances to run Ubuntu 18.04 and to install these 6 dependencies on startup. And I want a large pepperoni pizza[1]."
Terraform will read your credentials and make it happen.
The terms "provision", "manage", "infrastructure" and "service" alone can each have 10s of different meanings. Hence if you multiply it out that sentence could have 10000s of different meanings.
Both CloudFormation and Terraform are tools that allow a dev to define Cloud Resources (databases, networks, permissions, instances, all that) as code/markup, and then run those markup files through their respective engines (CloudFormation or Terraform) and have those resources get created/modified/whatever.
They both have their drawbacks, Terraform obviously suffers from not being a first-class service to AWS (since their service CloudFormation is a direct competitor). It is also possible to accidentally discard your Cloud "state" file, that keeps track of every instance that already exists and its current state (so TF can do a "diff" on what is there vs. what you're trying to apply), which definitely causes some headaches. In my experience the benefits of the design decisions from the tool far far outweigh any of the cons.
On the contrary, I have never had a good experience with CloudFormation. The workflow is long/slow, some of the AWS Best Practices are hilariously bad (looking at you "Paste this entire Python file as a text string into a yaml file), and more than a few times have I gotten into a state where CF-generated instances cannot be deleted and require the intervention of an AWS Rep.