Terraform is getting better at the loops and stuff but I still have a bunch of code from older versions of terraform that are erb templates that output terraform files, thus allowing to use Ruby functions. That was/is probably the least evil solution I've seen. The worst is when the infrastructure or devops team (or someone else) decides, "we need to abstract this away with our own tool."
I'd argue this is one such guardrail. Way more than once I've seen infrastructure resources exhausted (frequently cloud provider limits), because a hard line wasn't maintained between infrastructure code and application code. Frequently in the form of "It just makes sense for us to create one %s infrastructure resource for each %s in our application!" followed by a series of midnight conference calls weeks-months later.
I think those days of magic-HCL-generators are more-or-less behind us.
All we need now is variables in backend config and delayed provider initialisation and we’re laughing !
Well-meaning DSL constraints very quickly evolve into hackish defacto "actual code". Every. Time.
I do understand the intent of a constrained DSL mapping to constraints of underlying resources, but more often than not those constraints are short-lived in the lifespan of the DSL, and quickly give way to it becoming a badly architected near-turing-complete programming language.
Ansible (which you've listed) is a prime example: it's not YAML, it's a frankenstein of YAML + logic-heavy Jinja-hacks that really remove a lot of the constraints of pure declarative YAML. The only thing holding it back from becoming a horrible logic mess is very deliberate and well-marketed community convention.