Having recently picked up Rust (yes, sorry for mentioning it, I promise it's relevant), I picked up Terraform the other day. I was shocked by how weak its language-level developer experience story is.
I am working in VSCode, which by and large tends to be the editor supported best, with the most mindshare. Terraform has static and mostly strong typing, yet some testing revealed I was able to pass an argument of the wrong type to some variable I declared. This is type safety 101: variable declared `str` shouldn't accept `int`, ever. Yet `tf validate` was silent, so was all IDE-integrated tooling (whatever the VSCode TF extension does).
Jumping to/from symbol definitions/usages was also flaky (but not entirely absent).
Really disappointing! My excitement of diving into TF went poof. Maybe I'm overly sensitive, but I was so excited to escape YAML hell (Ansible).
Now I'm even firmer in the boat of just using a regular old language, like Pulumi with Python (with full typing).
Did I do something wrong or can anyone confirm my findings?
You can, for most of the cases. You just need a way to tag resources as belonging to the tool. This can be done via prefixed (or suffixed) names, tags, etc.
That… is state, just stored elsewhere. It’s also not usable for lots of important parts of AWS, which does not have consistent tagging support and would leave you running very much foul of API rate limits.
Terraform having state wasn’t some easy button decision, it was absolutely required and carefully considered.
The state is stored in the resources themselves, to be precise.
> It’s also not usable for lots of important parts of AWS, which does not have consistent tagging support and would leave you running very much foul of API rate limits.
As someone who worked on tagging inside AWS, I don't believe that there are any major AWS services left that don't support tagging. These days, tagging-on-creation also guarantees that you won't have untagged resources if your provider happens to die between "CreateResource" and the "TagResource" operations.
You can also sometimes use prefixed names to signal that a resource belongs to the infrastructure-as-code.
API limits for "describe" calls are also pretty lax. And you need to use them anyway to check if the current state of the world matches with the saved state.
State will be needed for some integrations that don't support tagging/naming (Okta, I'm looking at YOU!), but at least for AWS it's not needed.
There may be no services at large that don’t support tagging (certainly was historically not the case though), but there a hundreds of resources that don’t.
Furthermore, tagging is restrictable by IAM, is often co-opted by finance for cost allocation, and is subject to often-bizarre limits about what the content can be (even more so across providers).
Finally, how would you manage tags as an actual resource themselves in this model?
For resources that don't support tagging or user-defined naming, you'll need state.
> Furthermore, tagging is restrictable by IAM, is often co-opted by finance for cost allocation, and is subject to often-bizarre limits about what the content can be (even more so across providers).
You can fix your IAM. Cost allocation tags are treated specially.
> Finally, how would you manage tags as an actual resource themselves in this model?
I would support (with my own money) a fork that would re-use the Terraform providers, and reimplement the language as something not so insane.