Live data from Hacker News

Terraform should have remained stateless

bejarano.io

141–150 of 329 posts

Re: Terraform should have remained stateless

#141
post #51

> Ansible, Puppet, etc. don’t have intermediate stores of the hosts’ configuration, but then again they are used for different things. Ansible, Chef, Puppet and co existed long before Terraform. If the stateless way would work better, these tools take over the cloud infrastructure space. But they didn't. To me it seems like a good sign that the their approaches didn't fit to infra. Additionally, one of the biggest te…

One of the fundamental issues that I’ve encountered in all of the puppet managed environments is that people would remove resources from the configuration without first explicitly setting them to “absent”, effectively leaving them in an unmanaged state of the previously management configuration. If that state differs from the default, a new machine would end up with a different configuration, potentially breaking things.

Re: Terraform should have remained stateless

#142
post #67

I maintain a Terraform provider for Kubernetes. And one of the main reasons for that is because the Terraform state ensures purging of deleted resources. Something that kubectl is not capable of. The lastAppliedConfig annotation does not help for purging, because once the manifest has been deleted on disk, there is no way of knowing what to delete from the server. The unusable apply --purge flag is the best example o…

Could you elaborate on the poor usability of the --purge flag?

Re: Terraform should have remained stateless

#143

Earlier quoted context omitted.

It's not a drift detection tool for resources that are manually created.

Are you saying it should? I think whether that's desirable or not is a matter of preference. The nice thing about Terraform is that you don't have to go all in. I don't really want to have to tell it to ignore every resource that I want to manually manage, and I don't want it wasting the extra API calls on trying to find every resource that's not in my configuration every time I want to deploy. Now, if they provided…

Not suggesting it "should", I was just pointing out that it's not a complete drift detection tool.

Re: Terraform should have remained stateless

#144

Earlier quoted context omitted.

I'll play devil's advocate (because I understand the need for a state): What if terraform was able to perform a complete audit of your environment for each provider and say "this is what you've got, mate", then give you options for each resource: 1. Accept (turns it into terraform code) 2. Reject (removes the resource) Taken further, this idea effectively means that manually creating something like EKS could be a way…

That approach wouldn't work if your infrastructure is spread between multiple Terraform workspaces. (as is often done).

I think that my imagining of the tool is sufficiently different to think that it isn't the same tool at all, and different workspaces wouldn't even be a thing. The composer UI in this case would provide a way to logically separate infra into different code bases but it would still have to know about all of them.

Edit: and actually, without a state there is no concept of a remote state. All codebases talk to the same "service" so circling a bunch of infrastructure and saving it to a specific git project would be easier than connecting to a bunch of remote states and reading specific resource days from them. Even if you're code repo doesn't declare a resource, the omniscient IAC service "knows all"

Re: Terraform should have remained stateless

#145
You could work in some way without a state but actually the state is a feature which helps you.

Imagine you go down the ansible route and you write idempotent ansible code than you could argue: “See. I don’t need state. My code is idempotent. I just use this playbook to apply”

Now think of deleting resources.

You could have a delete playbook maybe. Then how would choose whether to create or delete stuff? Maybe a colleague gives you a ticket: “please delete”

Now there are various scenarios:

You do your thing (on your laptop) and tell everybody else in your team to not run the CreatePlaybook as you have to run the DeletePlaybook first for this one machine. Afterwards you delete the actual machine/resources from your ansible repository and tell the team: “please use the newest main branch”.

So: Here is your equivalent to terraform state, the coordination effort on your side since you are the only person who currently “knows” what’s going on with deletion/applying.

So your next idea is: “no problem, I make a Pipelines which runs the playbook on your behalf”. And the pipeline will update maybe the Git repo accordingly in some way - after the run (since ansible needs to know in the run, what to delete).

Everybody can see the pipeline . The pipeline will ensure you sequentially apply the playbooks to coordinate with your colleagues.

Next problem: how does the pipeline know which playbook and resources to run on?

You create a selection box for your hosts and for the playbook yaml to trigger the pipeline.

=> there is your state. Your ticket information are transferred to your manual labor to fill in the correct items in your selection box. To reestablish want went on you now have to look in the ansible code and the pipeline Paramus and pipeline logs.

More examples are: you only want to update some stuff with your ansible playbook. Therefore you might introduce tags on the resources and the playbook knows how to handle those tags. The extreme case might be:

TTag:state:present, tag:state:absent.

Then you can run a single playbook which can call the deletion and installation playbook for you and everybody is happy that you have everything visible in Git.

Problem here: your 2 step process to decommission things from git. First a commit which sets state:absent. Then run the pipeline and then another git commit to delete the code.

So what I am saying is: You can do all of this with ansible for sure. But you will have state somewhere:

In a Ticket, a Pipeline log, in git, in a wiki

I am not saying absible should not be used. It makes sense to configure things. (I personally would wrap a terraform hull around my absinble code and call it, just to have terraform handle the locking for my playbooks)

But just watch out for the hidden state in your workflows and better make it explicit. This is why people love GitOps for traceability.

You can all do this by hand and document your process in a Wiki for your colleagues so that they known what the “tag:state:absent” means for them. Or you can rely on somebody who has done this for you already and maintains documentation and what not.

Re: Terraform should have remained stateless

#147
Terraform having state is a trade-off:

Pros:

- it can manage resources where not all information can be queried

- reading state is almost always significantly faster

- it can identify deleted resources

Cons:

- state can go out of sync

- every resource type has to implement state well while tracking changing features, so it’s fragile

- fixing broken state can be a PITA

Without making these trade-offs, terraform would only be able to support a smaller subset of the providers it currently does and perform poorly.

Re: Terraform should have remained stateless

#148
post #67

I maintain a Terraform provider for Kubernetes. And one of the main reasons for that is because the Terraform state ensures purging of deleted resources. Something that kubectl is not capable of. The lastAppliedConfig annotation does not help for purging, because once the manifest has been deleted on disk, there is no way of knowing what to delete from the server. The unusable apply --purge flag is the best example o…

> I think the state mainly exist to know what has been created in the past but since been deleted from manifests and therefore needs to be purged. The caching/performance argument is rather weak, because Terraform refreshes by default anyway before any operation.

Beautiful summary.

For resources with flexible tags, one could easily imagine tags like Kubernetes's:

    terraform.io/name
    terraform.io/instance
However, for tag-less resources you have no choice but to store state to map real-world IDs with what is in the config.

I wish Terraform "tried harder" to avoid state when it can be avoided. Perhaps it could introduce some soft state, where deleted resources are refreshed by looking at tags and not state.

Re: Terraform should have remained stateless

#149

The article misses a key bit of information TF needs when making a plan: 4. The previous Terraform configuration This is effectively stored by state. We need this because if a resource is removed from the new config then Terraform needs to be able to delete the existing resource from the world. If we don’t have the state then Terraform must either: 1. Not delete it from the world 2. Or risk deleting something not man…

The whole idea of the article is that “previous state” is something that can be derived from tags / metadata in the provider’s resources, rather than a standalone file. In other words, this metadata then is the state.

Could you give an example of a situation / transition that cannot be captured correctly by managing the state using these types of tags?

Re: Terraform should have remained stateless

#150

I respectfully disagree. If TF was stateless, you'd have to manage situations by hand that involve changing the idempotency key, such as the name of a VM. You'd also have to manage situations by hand where a resource is removed from the config. The whole point of TF is that it has state and doesn't require workarounds for these scenarios. Yes, you have to maintain state, but the state problems usually come from buggy…

I'll play devil's advocate (because I understand the need for a state): What if terraform was able to perform a complete audit of your environment for each provider and say "this is what you've got, mate", then give you options for each resource: 1. Accept (turns it into terraform code) 2. Reject (removes the resource) Taken further, this idea effectively means that manually creating something like EKS could be a way…

Sounds like a plan for a next generation cloud provider. They all have internal state about your account and what's running there; they just don't really expose it in a standardized way. Nor do they provide standardized ways to update that (other than a lot of cli tools and REST APIs).

We keep coming up with these layers of abstractions around stuff that at the bottom is essentially already stateful but just not in a useful way. Doing it right from the ground up might help. Of course, left to the usual suspects, this would just turn into another Frankenstein blackhole of devops time. The usual suspects are billion dollar corporations that thrive on layers of complexity.

Post reply on HN