The point is not how pretty the strings are. The point is there should be no strings at all. These are computer programs, so they should use normal objects. The python code `my_pod = nignx_pod()` will never throw a syntax error because the result has too many/too few spaces.
no one is stopping you from importing k8s types as protobufs and writing a program to talk to k8s api via protobuf encoding. all the types are already protos (except CRDs). it's just not the most user-friendly way so most people don't use it.
And plenty more exist today. But helm got popular first, so due to the collective action problem it's going to take the industry forever to switch off it.
most ops people just like templates bc coding wasn't their strong suit (at least before AI) and helm delivered the least friction way of using templates.
No, crossplane types are CRDs so ironically you have to use the `unstructured` package for them instead of the proper typed structs in the core client libraries. (Unless you also generate typed libraries for your CRDs).
> The python code `my_pod = nignx_pod()` will never throw a syntax error because the result has too many/too few spaces
Yes, but it might throw errors because the client library you're using is too old and attempts to define fields that no longer exist in your newer infrastructure API. You do not find these errors at compile-time, but rather at runtime, and only after both serialization and API request execution finish and you get an error from the API, in the best case, or a silent failure misconfiguring your infrastructure, at worst.
The only time an infra engineer would trust the types is if the vendor themself supplied them, or there's a mainstream community effort to keep them up to date, or they're maintained in-house with procedures to try to keep them up-to-date with new releases. At the end of the day, the API takes a string, not some protobuf or CORBA or God knows what binary serialized monster dujour...
> Yes, but it might throw errors because the client library you're using is too old and attempts to define fields that no longer exist in your newer infrastructure API.
Well. Don’t use a client library that is too old then? Like you do in any other kind of software deployment, where you update your client libraries together with the upstream API you talk to?
Yeah, sure, I'll file that away with the NPM "tens of thousands of tiny dependencies is OK" thinking. Constant dependency upgrades is a nightmare. There's a reason why shell + Helm is popular - they're stable.
There's a difference between NPM package updates and backwards-incompatible API changes, which shouldn't really occur often. Even in the NPM ecosystem, major version updates are not a regular event. So I'll take that over templated YAML in a heartbeat.
> The only time an infra engineer would trust the types is if the vendor themself supplied them, or there's a mainstream community effort to keep them up to date
Good news! The Kubernetes project has a documented compatibility strategy (https://kubernetes.io/docs/concepts/overview/kubernetes-api/...) and publishes new client library versions for every release. There's endpoints in the API to interrogate the API's versions and supported fields/features for every resource. Additionally, most API types will accept old versions and automatically convert them to the newer versions, wherever this is possible.
> At the end of the day, the API takes a string, not some protobuf or CORBA or God knows what binary serialized monster dujour...
This is not necessarily correct. Kubernetes API supports JSON, YAML, protobuf or CBOR over the wire, and all become in-memory structs on the server.
Kubernetes is a decent example of vendor-supplied and/or mainstream community effort, but that's beside the point that (a) Kubernetes is the exception, not the rule, and (b) Helm is popular for other reasons that belie non-string wire options, like: value overlays (how would you overlay binary-serialized CBOR again?), type safety for the stringly-typed JSON/YAML passed over the wire powered by validating admission webhooks, remote-executed-on-the-cluster hooks for pre-/post- installs/upgrades/uninstalls (big help for database migrations, for example, which cannot be connected to from the machine running Helm), etc.
Everything you mentioned as a Helm feature is not in fact exclusive to Helm, and can be done either in code using the client libraries, or other deployment tools. For example I've written my own deployment tools that provide "value overlays" by simply merging the in-memory structs in Python or Go code - a manifest is just a data structure. I've also written code that can do ordered deployments with checks at multiple stages, which is both easier to do and more powerful when you write Python/Go code than trying to twist your dependencies to fit Helm's sync wave system.