Original Author Date: 8/2017
I had to see why Terraform was gaining such a marketshare so rapidly for Infrastructure Automation (IA).
After all, Cloudfront seemed to do the job. Sure, it was a pain at times, but generally speaking I could accomplish what I needed to, and honestly, the promise of “cloud vendor agnostic” both feels like a pipe dream, AND just isn’t something I worry about generally (I’m not a CTO of a fortune 500 company). I worry about DR, sure, multi-region, sure, but not “cloud vendor”. Isn’t that why we pay a premium for AWS? So we’re confident?
I wrote a small application – a Cloudwatch trigger scheduled Lamba function that reads from an API and writes to S3.
Big enough to express some complexity but small enough to not feel monstrous for a comparison effort. There’s probably a thousand other ways to do this and of course one would need to get highly modular to support crafting an entire infrastructure but I like the idea of figuring out ways to keep stuff reasonably self contained.
Manual Scripts:
I’m a traditionalist, and I love that the AWS CLI gives me pretty much all the power I need. For smaller apps it is reasonable to just script up what you need, a bit of Bash, a touch of Python, and poof, reproducible infrastructure.
I like it. I get it. I understand its not for everybody, and of course, if you are building projects with self-contained IA this is a reasonable approach. But get to over 10 or so individual resources and things quickly become a maintenance nightmare.
- (WIN!) Simple. Readable. No extra tools beyond the CLI. If you know Bash, and ideally a bit of Python or Ruby
- (WIN!) Self contained, a solid solution for the small-project use case
- (LOSE!) Becomes complex quickly
- (LOSE!) Not so good for that demographic of web-developers trying to “build and ship” on their own and possibly don’t have this history of ops skills
All in all, I like this approach when I can keep it small. Trouble is…nothing ever wants to stay small!
CloudFormation:
The AWS gold standard approach to IA works. It’s a bit of a chore with the way functions and references work in the context of JSON but hey, its AWS, they know what they are doing, and you can get the job done.
Big CFT’s (cloud formation templates) become chore-some quickly however, and start to hurt my brain.
- (WIN!) It’s AWS. It stays current with their product line.
- (LOSE!) Comments. Yes ok, you CAN comment but you do it as a “metadata” node in the json. 1. That doesn’t REALLY feel like a comment, and 2. The comment is buried in the definition.
- (WIN!) In CFT you can simply inline “ManagedPolicyArns” as part of the properties of the group definition. This is more effort and (seemingly) unnecessarily explicit in Terraform.
- (WIN!) I like the definition of a users groups as part of the user definition.
- (WIN!/LOSE!) The Cloudformer tool is a bit of a pain and though I’ve used it a couple of times, I’m dubious about its value. The way it presents the resource ID’s, most of the time I have to go manually cross check everything to figure out which ID’s I want to pull in. Also – what’s the deal with having to use CloudFormation to launch an instance to run Cloudformer? C’mon guys.
Edit! This was written before the YAML Cloudformation was really a thing. The YAML approach and some of the enhancements they’ve done have made this solution a bit more appealing for me
Terraform:
HashiCorp’s IA offering, Terraform. At first I disliked the “it’s not json” (or yaml) nature of the HashiCorp Configuration Language (HCL).
I quickly realized though that it was partly what enabled two of my favorite aspects, terser syntax and simpler functions.
- (WIN!) Comments in the config.tf file.
- (WIN!) That’s worth repeating – comments in the config.tf file, one-line or block.
- (WIN!) One more time – comments in the config.tf file //A Comment or /* some comments*/
- (WIN!) Deltas inferred through diff, rather than “change sets”. Less “idempotent infrastructure” approach but ultimately I think more desireable.
- (WIN!) Smart variable management. Somehow the approach simply feels more articulate. Maybe it’s because I’m chiefly on the dev side and not the ops side, but ${something} reads better than the JSON equivalent.
- (WIN!) `terraform plan` – yeah – tell me what you are going to do before you do it. What brilliance! In CFT land I have to just send up the config and then troll for “events” and errors and see what happened.
- (WIN!) More terse syntax and much more standard, non-json-based function application, e.g.
- ${var.var_name} vs { “Ref” : “targetEnvironment” } and
- bucket=”${var.var_name}foobar” vs “BucketName”: { “Fn::Join” : [ “”, [ { “Ref” : “targetEnvironment” }, “foobar” ] ] }
- (WIN!) Code completion in Intellij (WIN WIN WIN)
- (LOSE!) The <
- (LOSE!) The explicit sub-definition as-an-object of every managed policy. It seems like you could just have this inline as a list. In CFT you can simply inline those as part of the properties of the group definition.
- (UNDECIDED) Adding a group to the user is defined at the user level in CFT and this feels right. In Terraform it is not done in either, both are defined and there is then a join target “aws_iam_group_membership” – which doesn’t feel wrong but is another block… On the other hand there is a general pattern of 1. Create A, 2. Create B, 3. Join A to B. This feels natural after a minute and though it might slightly bloat the config it is still very easy to “reason about” and well-articulated in the config – and the config is STILL smaller than CFT.
- (WIN!) Ability to create S3 resources directly. The hokey workaround in CFT land is to create a lambda that creates the resources that then get torn down. Or any of a number of other hokey solution.
It’s strange – all the same data is there but it just feels cleaner and smaller with Terraform.
Altogether Now
Docs – all of this is really well documented. I didn’t have any trouble finding information I needed in any case I tried.
The weakest was probably the Boto examples but overall that was great to not struggle with or have to peruse source code to get the job done.
There’s something to like about every approach, and something to dislike, I think. I’m sure I missed somebody’s favorite feature in one of these, and failed to state a flaw somebody thinks is critical. Let it go, internet. My only intent was to represent first experiences and key points that were valuable to ME, hoping this helps YOU.
DISCLAIMER: I do NOT work for HashiCorp – and in all honesty fully expected to hate Terraform before this exercise began, because it seemed like just another me-too solution that will always lag behind. Well…it’s not. It has legitimate differentiators and improvements over the alternatives.