The code comparison between CloudFormation’s abysmal JSON formatting and Terraform’s DSL is a bit disingenuous.
CloudFormation has supported YAML for at least a year or two now, and it’s leagues more readable and compact, not to mention maintainable—you can even add comments to your code with YAML (something that is impossible with the old JSON format).
I’ve spent a lot of time working between the two, and while Terraform does have a lot to offer and is often a very valid option, CloudFormation has its virtues, especially the fact that almost all bleeding edge AWS features are first available to be managed via CloudFormation (sometimes with weeks or months of lead time), and many bugs can be more readily ironed out with AWS support (assuming you have it).
Again, not saying don’t use Terraform, just that I don’t think the decision is quite as black and white as this blog post seems to make it.
Personally I find YAML for cloudformation worse than JSON because of the whitespacing requirements. JSON isn't much better mind, especially once your template reaches to hundreds of lines with nested objects.
Recently I've come around to using Troposphere [1] to write cloudformation templates, it's actually very pleasant to use. You just write your infrastructure in python, and it will generate you a template at the end. The developers seem to respond quickly to changes AWS make to the CF templating language too.
I'm sorry, what? You don't like YAML because it uses whitespace as a delimiter instead of curly braces? That is probably the least important feature that YAML adds for CF templates.
YAML, despite its warts, is much more readable and maintainable for CF templates than JSON, particularly when you are doing non-trivial things and need to use a lot of intrinsic functions and string manipulation. Or you want to put comments in your template.
I've worked on huge JSON and huge YAML CF templates (I'm talking templates that are thousands of lines long--in YAML). YAML is without a doubt easier to maintain.
I can't recommend any CF libraries for generating templates either, unless you want to wait around for new CloudFormation features to be implemented or suffer from half-broken existing implementations (or waste time hunting down bugs and submitting patches). Sometimes it makes sense to use a template engine like Jinja or ERB. But I'd stay away from libraries that generate CF templates--they're mired with missing edge cases and they're mostly an unnecessary dependency.
Absolutely agree! Have been smashing out YAML templates for 12mths with pleasure (3yrs of JSON templates beyond that), comments are the winning proposition, allows neat sectioning of various parts.
+1 for Troposphere. It reduces the noise from your CF template while bringing the flexibility and ease-of-use of Python. I've also discovered that it's far easier to get new developers spun up on than Terraform.
> The code comparison between CloudFormation’s abysmal JSON formatting and Terraform’s DSL is a bit disingenuous.
CloudFormation has supported YAML for at least a year or two now, and it’s leagues more readable and compact, not to mention maintainable—you can even add comments to your code with YAML (something that is impossible with the old JSON format).
There are also decent tools atop CloudFormation for using an actual programming language instead of whatever HCL wants you to think it is. The Cfer[0] project that I contribute to (and use as the underpinnings for the Auster[1] cloud workflow tooling) is the thinnest possible wrapper around CloudFormation that we could come up with. But it just by existing lets us do things like...y'know...if statements and loops...without breaking our backs. Code reuse is better than whatevery module reuse, too; I wrote a gem, which this reminds me that I need to open source, that lets me roll out a standardized three-tier network of varying size (important because AWS tends to work best with /24 subnets but hey, you might want more than three of them per tier) without really thinking about it too hard.
(Back when Terraform was new, I tried writing a halfway decent DSL on top of it; turns out "it's really just JSON under the hood" was untrue and no testing had been done on that path. I assume it has since. But HCL still exists, and HCL is still pretty awful.)
I would say not to use Terraform if you're using only AWS, because Terraform has a nice habit of hosing your state when you look at it funny and I've had it literally regress to the point of making states in version X unreadable in version X+1. But those issues are separate from the clunky DSL.
> The Cfer project that I contribute to [...] is the thinnest possible wrapper around CloudFormation that we could come up with.
I've found preprocessing CloudFormation YAML using a standard template language (e.g., ERB) to be the thinnest possible wrapper around CloudFormation for providing if statements and loops without breaking our backs. Cfer looks nice and lean, but it still adds another domain-specific language on top of the stack while ERB is part of Ruby's existing standard library.
Granted, using an existing template preprocessor or a lightweight DSL can both work well and I think it's largely a matter of preference as to which feels thinner/easier to work with.
I agree with your assessment of HCL, a range of tooling choices for CloudFormation are largely possible because CloudFormation runs on standard JSON/YAML documents rather than the domain-specific, vendor-specific Hashicorp Configuration Language that lacks as robust tooling and support across languages/IDEs.
It is a DSL, but it's literally as thin as it gets. =) `method_missing` calls define properties. I'd take YAML+ERB over HCL for sure, though. And Cfer treating everything as objects gives us a really simple packaging mechanism for reuse--they're just gems.
Objects just work way better for reuse and aggregation than text, IME.
Which seem to mostly revolve around AWS vendor lock-in. Which, you know, can be a valid business decision - accepting vendor-exclusive tooling for better vendor support to try and simplify initial deployment and lower near-term, initial ramp-up costs - but it has its downsides too, like losing control of costs over the long term and making advanced work (like multi-cloud deployments to improve reliability) more fragile, difficult, and sometimes de-facto impossible.
Seems to me like the question of CloudFormation vs. Terraform has more to do with whether the business makes a strategic decision to allow for vendor lock-in or not, rather than mostly aesthetic discussions over the merits of YAML vs HCL.
> Seems to me like the question of CloudFormation vs. Terraform has more to do with whether the business makes a strategic decision to allow for vendor lock-in or not, rather than mostly aesthetic discussions over the merits of YAML vs HCL.
While I agree that CloudFormation is a vendor-specific tool which makes Terraform the obvious choice to avoid vendor lock-in more generally, in this particular case, the author is fully entrenched in the AWS ecosystem without any hint of desire to avoid lock-in, and gave as reason #1 for his decision a mostly aesthetic discussion over the merits of YAML vs HCL.
unless your vendor goes out of their way to be compatible with aws apis no tooling is really portable. true that you can write terraform targetting both aws and gce, but there's no non-trivial terraform plans you can apply to both aws and gce
I am not ashamed to admit that I felt the same way for a time. I don't know when things changed, but it started to click recently, and I actually like yaml. I guess that it helps that it has become rather ubiquitous in our build tools between cloud-init, puppet hieradata, and ansible roles/playbooks.
What hasn't been helpful is what others here and elsewhere have reminded me time and time again... "JSON is a subset of yaml"
Initially I was that way too, only took a couple weeks and a few reference templates that demonstrated the constructs to get past that and haven't done JSON since. Definitely more efficient to develop with.
The real advantage of CloudFormation comes in combining it with the AWS APIs -- you can define your infrastructure as code in Python, NodeJS, Java, Ruby, &c.
Driving infrastructure with a general purpose programming language actually works pretty well in practice.
As things have developed, I've come to question infrastructure-specific external DSLs, like Salt, Terraform, even Chef to some extent. Infrastructure is not any less programmable than payments, machine learning, graphics, app servers. Why can't the tooling be provided as libraries, consumable from ordinary programming languages?
> I believe there was a case last year when one of the new AWS features was available in Terraform before it made it to CloudFormation :)
Yes, this has been known to happen, here is one example: https://stackoverflow.com/a/42142791/2518355 - this AWS feature was added Sep 21 2016, Terraform resource released support on May 11 2017, CloudFormation resource released support on Jun 6 2017.
However, several points should be added to this comparison:
- CloudFormation supports Custom Resources so you can always implement new AWS features yourself with a few lines of JavaScript, without waiting for the official resource implementation to be published.
- CloudFormation resources have extensive documentation, and are officially maintained + supported by AWS.
It's still the case. I can't find it on mobile, but I asked a StackOverflow question and later answered it myself after discovering something like this buried in the AWS documentation.
CloudFormation has supported YAML for at least a year or two now, and it’s leagues more readable and compact, not to mention maintainable—you can even add comments to your code with YAML (something that is impossible with the old JSON format).
I’ve spent a lot of time working between the two, and while Terraform does have a lot to offer and is often a very valid option, CloudFormation has its virtues, especially the fact that almost all bleeding edge AWS features are first available to be managed via CloudFormation (sometimes with weeks or months of lead time), and many bugs can be more readily ironed out with AWS support (assuming you have it).
Again, not saying don’t use Terraform, just that I don’t think the decision is quite as black and white as this blog post seems to make it.