Live data from Hacker News

Ask HN: Why was Terraform created?

news.ycombinator.com

61–64 of 64 posts

Re: Ask HN: Why was Terraform created?

#61
post #57

The complexity of cloud deployments tends to grow wildly over time. What starts as an ECR repo with a single ECS deployment turns into Route 53 zones, S3 buckets, ELBs, multiple deployments of ECS, security policies, the odd EC2 instance (there's always one somehwere), etc, etc. Terraform gives you a commmon language to make sense of it all that can grow as your cloud infra does. When combined with git and CI/CD it's…

Is self-service Terraform as you describe actually successful? I use Terraform frequently and I have zero confidence that this process works except for the simplest changes. For one, building out anything of complexity in Terraform often involves some trial and error to make sure all the resources are wired together correctly. For two, there are some Terraform changes that can incur downtime if you just let Terraform…

> For one, building out anything of complexity in Terraform often involves some trial and error to make sure all the resources are wired together correctly.

This seems like misattribution: you do that everywhere when you’re doing something new - the problem is the underlying gap between the understanding of the problem which you started with and what the underlying services actually require. You can avoid most of that by using modules to reduce the amount of new structure you need to develop and static linters (tflint, tfsec, etc.) to flag things in advance.

> For two, there are some Terraform changes that can incur downtime if you just let Terraform destroy and create resources.

This should never be necessary due to Terraform - that’s one of the major advantages over older tools like AWS CloudFormation. If you’re seeing this as a problem where it’s not imposed by the platform (e.g. many AWS resources won’t allow you to change the name after creation) you can use lifecycle rules to avoid forcing re-creation where that makes sense or to create the replacement first & switch over before deleting the old resource. If you relocated the definitions in your code, you can tell Terraform how to migrate old state non-destructively.

Re: Ask HN: Why was Terraform created?

#62

It's probably overkill for your use case. If you're on AWS you can stick to CloudFormation; with something this simple, you can indeed just (as you suggest) use a bash script. But a lot of applications have infrastructure far, far more complex than a single service running in a container and S3/RDS. It may involve a large number of lambdas, networks, API gateways, firewalls, proxies, certificates, etc. Past a certain…

> If you're on AWS you can stick to CloudFormation

I would caution against this, even if you solely work on AWS. CloudFormation is much, much slower and has failure modes where it can take hours before the CF service returns to a manageable state. This is slightly better now that they added the ability to ignore failures so you can delete resources manually and then restart the CF rollback process but it’s still much more prone to getting into states where someone knows exactly what needs to be done but the tool won’t let them do it.

We switched to Terraform about half a decade ago over that and it was such a great removal of friction from your development cycle. I tried a small CF project last summer and had to help multiple experienced AWS users with the same class of problems within a week.

Re: Ask HN: Why was Terraform created?

#63
Terraform isn't for deploying infrastructure, it's for _converging_ infrastructure onto a desired state. Good luck writing a bash script that can deploy hundreds of different, dependent IaaS resources and deal with any or all of the resources initially being misconfigured or missing.

Re: Ask HN: Why was Terraform created?

#64
> [why not write shell scripts to do what we need]

The shell script needs to determine, for each resource, whether it exists; if it does exist, what changes to make and how to translate those into API calls, or if it doesn't exist, how to create it, and to clean up any resources no longer in the desired state.

Attributes of some resource that might exist only after creation need to be fed into other resources…

For even a single resource, over the lifetime of the many changes and adjustments to the resource, that is extremely complicated to do correctly in shell alone.

The declarative "desired state" style is more useful since the steps required to be undertaken often depend on the state of the infrastructure that exists, or doesn't exist.

(additionally, you'll also need to notate state about what infra exists and what doesn't, and store that somewhere, and transmit that state to coworkers … and TF handles that, too. While "its obvious" for some infra — i.e., the resource has a natural key — not all resources do, and often you have to deal with unmanaged resources and not decide to delete them simply because they're not part of your desired state.)

Lastly, you have to handle bugs and design flaws in the APIs. I've worked with a number of platforms where two, valid calls to the API in a shell script are a race condition because the API doesn't support read-your-writes.

All this reinvents the wheel that is TF.

There's also "why does this infra exist?": I can comment TF, I get a commit history and rationales for why infra exists. Shell scripts really push people towards "I'll just #yolo this small change to the infra" … and now, I don't know why the infra is the way it is. Often, I find dev/prd have drifted, or two prod instances of the "same" thing are really different. Comments cut down on this, TF modules really cut down on it, etc.

> And what is it? It is a shell script inside of a JSON that was created in the shell! What for are these layers of abstraction? Why does he have to wrap the Resource Group name in a JSON? Why couldn't it be just piped in plaintext format, as all the tools that try to be POSIX-compatible do?

JSON is a text format. Your shell scripter has piped that into what amounts to a buggy, broken, 5% reimplementation of a JSON parser. Pipe that to `jq`, instead. (You can also use --query on az to reduce the output to something that will be more easily handled by `jq`, but anything --query can do, jq can too, pretty much, and it might be better to have all the code in one language.)

Or just request that data from terraform, by accessing the appropriate attribute of the that resource.

Post reply on HN