Hacker News new | ask | show | jobs
by 7ewis 3299 days ago
Terraform has interested me for a while, and I've been meaning to give it a try, but haven't had a chance just yet.

From what I have seen so far though, there isn't really that much difference/benefit over CloudFormation. We currently have 95% of our resources in AWS with about 4% in Azure, and 1% in Google Cloud. It's great that Terraform is 'mulit-cloud' but it still seems like you have to write .tf's catered to each cloud, you can't just lift and shift to another cloud by copying and pasting a file?

People say the 'plan' feature is one of the advantages over CFN, but as far as I can tell, CFN now offers the same feature... it tells you what's going to change when you upload a new stack.

I sound like a CFN advocate now, but I genuinely don't have that much experience with it, and really do want to give Terraform a chance. Convince me?

Oh, and since CFN started supporing YAML it looks easier to write too

6 comments

I've been thru the CFN v TF question. We came up with a list of benefits of TF over CFN. (Yes, I know - one-sided, but we wanted to document the decision with a bit more substance than "oh it's just better")

  * Ability to separate data (variables/parameters) from configs.
  * Easier to read (well at least pre-YAML CFN). 
  * Allows comments in the code.
  * Version control changes (diffs) are easier to read.
  * Multi-Cloud support. Works against AWS, Google Compute, Azure, Docker, more.
  * Multi-provider in general: can provision resources across multiple different cloud providers at once.
  * Can write modules in TF that can be reused in multiple different configs.
  * Tracks state via a version-controllable data file.
  * 'terraform plan' is essentially a no-op mode to see what changes would occur without actual running or making changes.
  * Actively developed.
Cloud Formation has good support for use from Python, Ruby, Node and the JVM (with template generators, to help out). If you're writing JSON directly, yes, some of the points above -- the first four, and the seventh -- are an issue; but if you use Python you get all the benefits of it being "real code" and "just a library" (unlike Terraform).
This is a situation where I think not being "real code" is a feature of terraform. You declaratively represent your infrastructure rather than generate it with real code.
Over time, I have come to view "declarative infrastructure" as unrealistic. It's right 90% of the time, but not 100% of the time -- kind of like using only CSS and HTML. One should use markup whenever possible; but not everything on a page is truly "declarative". Occasionally one needs to script an input field or a transition.

One example of this is scripting the handoff process that's part of a blue/green deploy. In practice you'll want to look at organization defined metrics. There are libraries to do this -- either internal to your organization, or provided by a metrics vendor -- and scripting the process looks like this:

    (1) Setup new environment.
    (2) Divert some traffic.
    (3) Check metrics.
    (4) If metrics are okay:
        (4.1) Post message internally (IRC/Slack).
        (4.2) Divert all traffic.
        (4.3) Set up timed task to tear down old environment (in a day, hour, &c.).
    (5) If metrics are okay:
        (5.1) Post message internally (IRC/Slack), maybe to different people.
        (5.2) Stop diverting traffic.
        (5.3) Tear down new environment.
A large part of the work here is declarative: (1) by itself is a big piece of it, and is fully declarative, as is the teardown in (4.3) and (5.3). However, the need for control flow in this and many other cases means that, without a library, one must drive Terraform by templating and shelling out. Not being "real code" pushes one in the direction, not of greater declarativeness (libraries can certainly have declarative interfaces, like Troposphere does), but of worse code.

Many complex and powerful features are exposed to a modern business through libraries -- AI, payments, telephony -- and software defined infrastructure can be, too. The benefits of "infrastructure as code" won't be realized until that happens.

A note on the Multi-Cloud support; OP is correct, it's not "switch to another provider" type setup - that's not where the power lies, the cool stuff is about being able to share attributes across clouds - Think about creating an AWS ELB, and then adding that CNAME entry into your CloudFlare account.

It also makes it for when/if you want to switch or start supporting other providers - your tool is already agnostic, and you don't need to go from CloudFormation and port over - you're already there.

I have seen similar comments about "what happens if you want to switch providers" or "don't want to put all your eggs in one basket'. I can understand the comments but at the same time I do a lot of enterprise migrations with companies. We do not go in there while working through a plan on how to migrate to AWS or Google cloud and start promoting the multi provider feature of terraform. Why would you be going through so much effort to plan and move an entire enterprise into the cloud and use terraform and then throw in the idea that "Hey, you can also write the code to stand up similar services in another provider?" Maybe for smaller projects it would be attractive but for the big boys I don't see that to be very beneficial. At least this ability would not sway me to use Terra over CFT.
Here's a real-world benefit I had over the weekend. I've been using Terraform for a Google Cloud project, and was coming to setting up DNS records. I wanted to have dual DNS providers for redundancy. With Terraform, it was trivial, as I just added a second Terraform resource for DNSimple (with Google Cloud DNS as my 'main' DNS resource).

The beauty of Terraform is that you can orchestrate all of your infrastructure, not just the stuff in one stack. If you've got 95%/4%/1% in AWS/Azure/GCP, how do you manage/reference the non-AWS resources? Terraform gives you a unified way to reference and link cross-infrastructure resources.

> It's great that Terraform is 'mulit-cloud' but it still seems like you have to write .tf's catered to each cloud, you can't just lift and shift to another cloud by copying and pasting a file?

We're not quite at the point where even the "comparable" cloud services across clouds are drop-in compatible with each other, so this is not going to be possible for a while for reasons not related to Terraform.

> I sound like a CFN advocate now, but I genuinely don't have that much experience with it, and really do want to give Terraform a chance. Convince me?

You could spend your time learning either a vendor-specific tool (CFN), or a vendor agnostic one (Terraform). Since Terraform can do a lot of what CFN does, it may make sense to spend your time learning Terraform instead.

Edit: not sure about CFN, but Terraform is open source: https://github.com/hashicorp/terraform

I think this sort of abstraction risks making some things awkward and will cater to the lowest common denominator. Better to just be explicit and have a config for each provider.
CloudFormation's approach for post-provisioning deployments is much more limited than the options that Terraform provides as first-class citizens. For example, there's a Chef provisioner as well as local-exec and remote-exec. With CloudFormation, the only options exist in the form of cloud-init that uses userdata.

However, this isn't to say that Terraform is always better than CloudFormation. In fact, I'd prefer to use CloudFormation for A/B | Blue-Green deploys because it supports UpdatePolicy options for rotating newly configured images into an autoscaling group. The logic to do that in Terraform is really not trivial at all (there is no clean, straightforward way to do such deployments with Terraform). Furthermore, rollbacks are significantly more reliable in my experience using CloudFormation than Terraform. Rollbacks may be easier to orchestrate using Terraform than CloudFormation though due to easier reference to non-AWS resources.

My preferred style of AWS deployments and infrastructure-as-code layering is Terraform with broken out modules and generating smaller CloudFormation templates for individual application components that need to be deployed often. This seems like a worst-of-both-worlds option but I think keeping CloudFormation templates constrained to just ASG modifications avoids a lot of the problems.

CloudFormation has a lot of things going for it, but it was unsuitable for us ~18 months ago when I was looking around for a way to "infrastructure as code"-ify our setup, because it can't "adopt" existing resources into your setup, and we have tons of stuff we don't want to bring down/up just to bring under cloudformation.

I used the terraforming gem (either because "terraform import" didnt' exist at the time, or because I just didn't like the way it worked) to bring a lot of things under management by terraform.

Isn't Cloudformation limited to 100 items?

That's not even enough for our Network ACLs.

How do you work around that?

it's 1000 by default now (per account per region) and you can get it raised substantially higher
Really?!? That's awesome.

Docs say 200 though http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuid...