8 ms·
Ask HN: Why was Terraform created?
I get the idea and general use cases of Terraform - to have a unified interface with a single language for all kinds of cloud infrastructures where the machine you are deploying to can be virtually anything.
But in majority of the cases developers are very much aware of environments their code run on - they know that their containers are stored in ECR, ran in ECS, their data is stored in S3 and RDS.
It is trivial to build a container, upload it to ECR and then deploy it to ECS from a shell script. And it is a lot more readable and comprehensible for a person not familiar with the tool.
Maybe I am the problem and I just don't get the declarative style, where you only describe the wanted state, not the steps you take to achieve that state?
If we assumed by default that our cloud infrastructure provider is AWS, wouldn't it be simple to write a shell script that would call `aws-cli` few times?
I came to that question, when discussing a problem my friend, a DevOps engineer, was having - he wasn't able to get the Azure Resource Group from his `foobar.tf` files and he ended up with something like the following:
cat << EOF
{
"aksvnet": "$(az resource list --resource-group $1 | grep -i \"aks-vnet- | cut -d ":" -f2 | tr -d '", ')"
}
EOF
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?
UPD:
This question is for environments where all the engineers are (to some extent) familiar with %CloudProviderSDK% and bash. And, in my opinion, it's a lot easier to pick up bash and %CloudProviderSDK%, as those are imperative therefore closer to engineers' daily routine, as opposed to Terraform's declarative style. Shell scripts, in my opinion, are just more intuitive by default.
- warrenm 4y agoTerraform was made for exactly the reason you stated ("single language for all kinds of cloud infrastructures") It was also made for non-developers to be able to deploy what someone else built "anywhere"
- impoppy 4y agoBut using Terraform with $CLOUD implies that you are familiar with $CLOUD - then if you know $CLOUD and bash why would you need to use Terraform to work with that cloud? Also, as stated in a sibling comment, all the commands, expressions and capabilities of Terraform differ based on your $CLOUD, so in the end it's not that universal. In fact, it's not different from bash - bash is always the same, you just type `az` instead of `aws-cli`.
- dagw 4y agoNot everybody deploying to $CLOUD necessarily knows a lot of $CLOUD and bash. They might know that they need an MPI cluster with N Cores and X GB of RAM pr core, 10 Gbit interconnects and 200 GB of shared storage. Learning how to edit a Terraform template that someone else wrote to achieve this probably is a lot easier than learning how to edit an ad hoc bash script and probably a lot less error prone.
- warrenm 4y agoAnd when you don't have bash? ... >In fact, it's not different from bash - bash is always the same, you just type `az` instead of `aws-cli`. Terraform works on many platforms (https://developer.hashicorp.com/terraform/downloads https://developer.hashicorp.com/terraform/downloads) Not all have (or default to) bash Whereas Terraform is "the same" everywhere
- ro_jazz 4y agoNot arguing, just contributing with my personal non-expert experience. I am using Terraform because using AWS directly was too cumbersome, and I'm happy with it.
- dragonwriter 4y ago> then if you know $CLOUD and bash why would you need to use Terraform to work with that cloud? The utility of Infrastructure as Code (IAC) is not “you don’t have to understand the target cloud platform”, which is why cloud providers often have their own IAC solutions (e.g., AWS CloudFormation, and the additional abstractions–Serverless Application Model, Cloud Development Kit–built on top of CloudFormation); Terraform adds multiple cloud support on top, which is useful for people with workloads in different clouds or when working with a vendor whose in-house solution is inferior, but that’s not the whole point. The utility of IAC is that you don’t have to write custom code based on the current and desired state for each state transition change. You write a description of the target state, and the engine handles determining the current state, what transition code is needed, and executing the transition code.
- jasonhansel 4y agoIt'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 point, you need a way of managing all that complexity, keeping things consistent across environments/regions, ensuring all infrastructure changes are tracked and audited, and making it easier to update lots of resources at once, among other things. That's where Terraform helps.
- impoppy 4y agoThen I guess it's a question to the startup I'm working at - why in the world did they overcomplicate so much stuff when in fact we have constant number of environments, workers, load balancers? In fact, every engineer in the company is very much aware on how our system operates and (I believe) could easily imitate whatever Terraform does with simple scripts.
- jasonhansel 4y agoFuture-proofing, I assume. Better to have things in Terraform now than to have to move them all later as you grow the application. Moving things into Terraform can be quite hard, since you essentially need to figure out how to reproduce the entire infrastructure from scratch.
- impoppy 4y agoYAGNI.
- jasonhansel 4y agoYou won't need it. But you'll probably want it, since at most start-ups complexity grows over time.
- hussainbilal 4y agoNot an expert nor a user of terraform, but I'm currently learning about the tool, and I like to learn by reading from books and docs, rather than diving straight in and doing. Based on what I've read, while Hashicorp tools may look like their only contribution is platform agnostic tooling, a deep dive into the docs reveals a focus on dynamically changing architecture and providing tooling to scale dynamically changing architectures in short time scales to any number of resources (i.e. not just machines / VM / containers / compute resources, but resources like users, user-generated resources, user-generated secrets etc.) My impressions thus far is that Hashicorp is aware of the variety of alternative tools, that's why their certifications / training / professional services are only available for the tools truly core to supporting dynamic architectures : Terraform, Consul and Vault. https://www.hashicorp.com/customer-success/professional-services https://www.hashicorp.com/customer-success/professional-serv... https://www.hashicorp.com/customer-success/enterprise-academy https://www.hashicorp.com/customer-success/enterprise-academ... https://www.hashicorp.com/certification https://www.hashicorp.com/certification
- arrmn 4y agoTo get data in Terraform you have outputs and you can display the data. Terraform helps you to have a unified way to manage your resources, sure the bash scripts works for you, but what happens if you leave the company? Somebody else has to maintain your shell script. What happens if somebody else is changing the infrastructure and they're not familiar with your shell script, they need time to dig in to figure things out and then update it, and in best case test it. And you need to keep your scripts up to date, you need to build in fault tolerance, you need to think how you're going to deploy new resources. How are you going to handle destroying resources? And on top of that you also need to learn the cloud Provider CLI tools or API to know what kind of calls to execute. It just provides a standardised way to manage your infra.
- impoppy 4y agoMy complaint is that there shouldn't be unknown or uncertain states in the first place. Infrastructure should be a finite state machine, not infinite. Failure in transition from state A to state B should result in rolling back to state A, not arbitrary state X.
- toomuchtodo 4y agoSometimes you cannot rollback. The peril of infrastructure is that it is an imperfect, living state machine. Terraform is a compromise between runbooks and deterministic definitions. Some operations you are committed to the change and will need to figure out exceptions on the other side of the apply. (infra engineer in a previous life when Terraform was first released)
- impoppy 4y agoWhat I got from this thread is that Terraform was created for this exact reason - to be able to work in a mysterious state that just happened to be there. Therefore Terraform normalizes existence of unknown unpredictable environments (which is already absolutely normal in the real world, as stuff is never exclusively black or white). But, on the other hand, isn't making stuff extremely predictable part of our job? Doesn't it contradict our goals we strive for when creating software?
- Bleloto 4y agoJust because you clicked in some webui to do something doesn't mean it's save. You still need to write how to do it, how to bootstrap it and why you do things. We have a basic tf layer, which does make it well documented, easily extendable and repeatable. Yes we do destroy the whole setup and recreate it. Often no but still. After the tf layer, there is only k8s which is also 100% IaC. Also sry to say but we are experts, learning something like tf should not be a big hurdle. What I saw in old sysadmin setups: tons of snow flake VMS no one knows why they exist, random setups different security versions on it. If you don't have any tool to automate things you will not do it. Feel free to create a small infra setup manually if you prefer, I prefer to codify it once and can recreate it instead of documenting it in some word doc. Tf is not perfect btw.
- rgoulter 4y agoBash is ~okay for small and simple enough tasks. But, above a certain complexity, I think probably anything else is going to be easier to maintain & have fewer footguns.
- awsanswers 4y agoGo down the path of rolling your own shell scripts and if you do a world class job you'll end up reimplementing the functionality and architecture of Terraform. Also, as a commercial open source project, you have the benefit of an entire community using and extending the tool in their own use cases. Read through Terraform release notes, you will see the amount of work & experimentation writing and maintaining a provider can be.
- impoppy 4y agoUsername checks out.
- awsanswers 4y agoOk here's a less friendly version: "The way AWS is implemented doesn't work for me" is a nightmare attitude for everyone on your team and an affront to your productivity. Look at the early (mid 2000s) AWS customer success stories and think about what it did for those companies. Accept the model and get your undifferentiated systems work done quickly.
- impoppy 4y agoI failed to express my take against Terraform: instead of fighting indeterministic nature of infrastructure, it was created to work around it. Why far more experienced engineers than I am came to the conclusion that playing along is better than actively fighting?
- awithrow 4y agoInfrastructure by it's nature won't be deterministic. Fighting it to me sounds like wanting to use "assume a frictionless plane" in a real world physics solution
- d_watt 4y agoI feel like your question is like "Why are there flathead screwdrivers? Shouldn't craftsmen only accept phillips head screwdrivers, since they're superior?" The reality being there are a lot of flathead screws out there. An engineers job is to get stuff done and not fight an ideological battleground. The world is impure, and requires impure solutions. Terraform is a tool to get things done, and given the realities of managing stateful infrastructure it does a pretty good job of addressing the failure states of it.
- cs_tiger4 4y agoOne killer feature of Infrastructure as Code, be it terraform or any other is idempotence. You have to be careful not to run your bash script twice or you get another instance/vpc/loadbalancer or whatever. You run "terraform apply" twice and it does nothing on the second run. If you start implementing that in your shell scripts you start implementing terraform in bash.
- whoomp12342 4y agoanother killer features is creating modules so you dont repeat yourself
- icedchai 4y agoI wound up at a shop where one of the original people involved and left clearly did not know about modules. It's all copy-paste.
- awithrow 4y ago> But in majority of the cases developers are very much aware of environments their code run on - they know that their containers are stored in ECR, ran in ECS, their data is stored in S3 and RDS. This has absolutely not been my experience. I've worked with a few devs who might be curious to know how everything worked. Most devs I've worked with focus solely on the code they write. I've also inherited many systems over the years and I'd take the ones managed with tf over bash every single time. A non exhaustive list of what tf helps with. 1. Being able to know what has changed and what needs to change before you run 2. Managing infra outside of the large cloud providers and being able to combine the two 3. Quickly being able to add a new environment or region to an existing cluster 4. Some requirement has changed and some new policy/tool needs to be stitched in across all your environments
- c0balt 4y agoI second the value that is added by having a history of changes and the ability to project changes with tf. Not all deployments need this but for mid to large setups this is very convenient. It is not that a simple bash-script couldn't do this however it is often not done in my experience, ymmv. Mostly due to the added complexity while writing such a script.
- morsecodist 4y ago> to have a unified interface with a single language for all kinds of cloud infrastructures where the machine you are deploying to can be virtually anything I don't think having a unified interface is the motivation behind Terraform. You still need to understand the underlying resources you are dealing with, Terraform doesn't abstract that at all. The big idea behind Terraform is procedural vs declarative. You can write scripts to bring up all of your infrastructure but what if one of your scripts fails in the middle? What parts of it actually went into effect and which didn't? Can you just re-run it or will the first part now fail because the infrastructure already exists? What if you have several engineers working on the same environment applying scripts that may interfere with one another? What if there was an incident and you made some manual changes and now production is out of sync with what is represented in the script? What if you made some complicated infrastructure changes and you broke something and want to bring everything back to exactly how it was before? Declarative infrastructure answers all of those questions. It lets you keep track of what the current state of your infrastructure is, and what you want it to be. It automatically identifies areas where the two don't match up and serves as a forcing function for documenting changes to your infrastructure. Declarative infrastructure is more complicated than procedural because bringing up infrastructure is a procedural process so you need a tool to make it into a declarative one and that is not always easy. But if your team's needs get complex enough the tradeoff is well worth it. I honestly can't even imagine life without it. As a bonus it makes it easy to ship complete infrastructure solutions as re-usable modules that you can compose.
- j0yb0y 4y agoGreat answer! One minor point, I agree it’s not the motivation but it _does_ provide a unified workflow across service providers, which is valuable!
- dragonwriter 4y ago> One minor point, I agree it’s not the motivation but it _does_ provide a unified workflow across service providers, which is valuable! IIRC, it is part of the motivation for Terraform specifically, though not for the broader class of Infrastructure as Code tools, some of which are provider-specific (but also likely quicker to support new platform features.)
- dimitar 4y agoThe example you gave is of a wrong way to write Terraform; you should be able to query the cloud API using using data sources. In your case (getting a VNet) that would be this: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resources https://registry.terraform.io/providers/hashicorp/azurerm/la... In case you need to get the metadata of a resource group you can use this: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group https://registry.terraform.io/providers/hashicorp/azurerm/la... I am a very happy Terraform user, here are the benefits for me: * Very simple workflow that helps prevent unintended consequences - first you write your code, generate a plan, inspect it carefully and only then apply. It is easy to work in a team setting where you can have one person write modules and others supply variables to them. * I personally don't want to burden myself with Azure Resource Manager, CloudFormation or any other vendor specific IAC tool. * I don't like other people's bash; there are tools like shell check, but usually a larger infra codebase becomes an awful ad-hoc mess of ENV variables and clever hacks. And infrastructure code is nasty to test and refactor. Try to keep it simple as possible; anytime you are fighting Terraform it usually means there is a much simpler way to do it. And if there is inherent complexity it could be the wrong thing to do. In case you need very dynamic behaviour (basically a part of an application) I advise the following - put in terraform the things that are not likely to change often or where the cost of breakage is higher - your virtual networks, DNS configuration, Load Balancers, VPNs, Autoscaling groups, important alerts, etc. Manage more ephemeral workloads in a more general purpose language if there is no straightforward way to do it in the official APIs. I am also very happy user of the AWS CLI in some cases + the cognitect aws libraries for Clojure. However if you need to do something very dynamic it is also likely to be wrong.
- mdaniel 4y ago> first you write your code, generate a plan, inspect it carefully and only then apply Be aware that this experience differs wildly by terraform provider. I can very easily demonstrate that `terraform plan` for AWS consults absolutely zero of the AWS infrastructure, relying solely upon terraform.tfstate. So, great if everyone in the entire organization is entirely disciplined, but in a less disciplined environment terraform's aws provider does nothing to help warn the user of the demonstrably false plan. I don't know what the situation is with the other cloud providers in order to know if that's just "the terraform way" or what
- cybrexalpha 4y agoThe 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 also an amazing self-service experince. For example you can put the Terraform code that describes your environment in a git repo, and allow any employee to open pull requests, and deploy changes on merge automaically, and require IT approval to merge. Now any engineer can self-service request access to a prod environment (by modifying IAM in Terraform), or configure a production deployment without ever needing actual access to prod. IT gets an audit log, they get a control gate (the code review), and engineers get to self-service changes which reduces the load on IT.
- dolni 4y agoIs 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 destroy and create resources. The solution I employ for this is what I not-so-affectionately call "Terraform surgery". It usually entails standing up the new resource(s), cutting over to them, and then destroying the old ones. Sometimes I will manually remove some stuff from the state file and delete it once Terraform has performed the cutover. That stuff is possible to do in CI, but it would be inefficient and painful. To me, the biggest benefit of Terraform is managing changes to cloud resources. You know what resources are added when, why, and by whom. You have a mechanism for promoting changes between environments confidently. And if your infra ever blew up, you would be able to put stuff back.
- cybrexalpha 4y agoI've seen it work best with an embedded plan. So engineers open a PR with terraform changes, the CI runs `terraform plan`, and comments on the PR with that diff. So you can see if your terraform is valid, if you're going to be destroying things you shouldn't, etc. Larger, more complex testing is generally done by locally invoking your terraform on a testing environment. How this is setup kind of depends, but I've seen this work well for testing out complex changes before going to the PR & Plan stage.
- wereallterrrist 4y ago"Random shell script is more readable than terraform". Yeah, no. Not if you mean bash, and certainly frickin not if theres a modicum of reliability/retries/recreaet logic in them. I dont think you have a good view of the landscape.
- typedef_struct 4y agoTerraform creates a virtual infrastructure against which diffs can be performed.
- thomasmcfarlane 4y agoIt's much more about standardising the approach within a team, and not needing to know your target infrastructure state. Especially at the stage of a scale up, you'll get a lot of differing views as where to write your scripts - Terraform provides tooling for a specific use case where you don't need to reinvent everything. At Nimbus[1], we have been trialling using Terraform for template definitions as users are mostly familiar with it, and it allows them to integrate more easily with existing CI/CD processes. They can easily just add a new Nimbus Workspace to their Terraform and have it spin up a new development environment when their CI requires it. [1]: https://usenimbus.com https://usenimbus.com - Easy remote development infra for teams
- ukoki 4y agoTerraform 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.
- deathanatos 4y ago> [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.
- ggeorgovassilis 4y agoI can't answer "why terraform was created" because I wasn't there. Also I only recently started working with it, so by far no expert on the matter. People who don't know terraform often praise it for its platform-agnostic language, but there's an important caveat: the language is platform agnostic, not the templates one writes as they are riddled with platform-specific nouns. You can't take an Azure template and deploy it on AWS. Having said that, I (so far) like terraform for the same reason you noted: it's more readable and there is great tooling around it. I like state management and the ability to invoke lower-level components (as the shell breakout in your example) when you really have to. edit: > the declarative style, where you only describe the wanted state, not the steps you take to achieve that state That is a good and useful thing. It's called "desired configuration management", Ansible works the same way. When the underlying tool works well, it decides on its own how to implement what you want. If you ever watch terraform deploy a complex (10+ dissimilar resources) infrastructure it comes close to magic how it discovers what already has been done and what still needs to be done and in which order.
- impoppy 4y ago>That is a good and useful thing As long as you manage to pick it up, which I'm struggling with - you have to approach the problem from an entirely different angle with an entirely different paradigm. I'm struggling with adopting Nix on my personal machine for the same reason - I get `dnf install foo bar` but I don't get `I want foo and bar installed on my machine.` I want my machine to do the stuff only when I explicitly ask it to do stuff and only when I explicitly tell it when to do it. UPD: >If you ever watch terraform deploy a complex (10+ dissimilar resources) infrastructure it comes close to magic how it discovers what already has been done and what still needs to be done and in which order. But why would you have half-ready environments you aren't even aware of state of? Isn't our job about having as little magic, mysteries and unknown variables as possible? I'm a big opponent of magic and, probably, one of bigger fans of KISS - simple implementation, not simple usage.
- rgoulter 4y ago> But why would you have half-ready environments you aren't even aware of state of? Isn't our job about having as little magic, mysteries and unknown variables as possible? Abstractions are the art of revealing the right information. With an abstraction, you don't pay attention to lower-level details that aren't related to what you're interested in. This makes it much easier to write complex systems. When someone teaches you how to "hello world", you're able to go and write programs without needing to understand NAND gates & how a CPU works. I think "terraform lets you work at a level of abstraction above needing to care about what is deployed in what order" is a point in terraform's favour above bash-scripts.
- warrenm 4y agohttps://developer.hashicorp.com/terraform/intro https://developer.hashicorp.com/terraform/intro
- Someone 4y agoOne thing that terraform does (see below) is that it diffs the desired state with current state (again: see below), and then makes the necessary changes. So, if you have terraformed a load balancer balancing load between 2 machines, and change your terraform to declare a load balancer balancing load between 3 machines, it won’t destroy two machines, destroy the load balancer, create a new load balancer, and then create 3 machines. Instead, it will create a new machine and change the load balancer to know about it, so that your service is uninterrupted. Problem is that the above isn’t quite true. Firstly, comparing with the current state is slow, so terraform has a cache of what it thinks the current state is. If they get out of sync, things can get interesting. Secondly, all changes are done by plugins of varying quality. Your cloud provider may, for example, support reconfiguration of a load balancer, but if the plug-in doesn’t, terraform will destroy and create a new one.
- jjice 4y agoAnother part of Terraform's power is the fact it's all text. We can store it in version control and see changes over time, as well as have it go through CI/CD. While there are platform specific alternatives like Cloud Formation, learning a new system for each platform would be a pain, and frankly, things like Cloud Formation just aren't as nice to work with compared to Terraform.