The Language That Wasn’t Supposed to Be One
If you hang around DevOps Twitter or Reddit long enough, you’ll stumble across a familiar fight: “Why does Terraform use HashiCorp Configuration Language (HCL) instead of a real programming language?”
Half the crowd insists HCL is the perfect middle ground. The other half sees it as YAML’s slightly hipper cousin — still clunky, but with more curly braces.
So, how did we end up with HCL at the center of infrastructure-as-code? And what would’ve happened if Terraform had just picked Python or Go instead?
HCL’s Origin Story(I think)
Terraform needed something that ticked a very specific set of boxes:
Human-readable syntax: not just for developers, but for ops folks and managers who only glance at infra configs.
Declarative, not imperative: you declare what you want, Terraform figures out how to get there.
Machine-friendly: structured enough for parsing and state reconciliation, flexible enough for humans to write without crying.
JSON was technically supported from day one. Nobody used it. Too verbose, too painful. HCL struck the balance.
Why Not Just Use a “Real” Language?
Imagine Terraform configs in Python. Sounds nice. Until you realize you’d need to write orchestration logic for every single dependency. Want an S3 bucket before your EC2 instance? Better remember to write that await_bucket()
function.
Terraform’s declarative model saves us from that nightmare. By hiding the “how,” it:
Reduces mistakes and redundancy.
Keeps configs readable across teams, even for folks who aren’t software engineers.
Manages state safely (rollbacks in Python would be a comedy of errors).
General-purpose languages give you infinite flexibility. But in infrastructure, infinite flexibility often means infinite footguns.
The Trade-off
Of course, HCL isn’t perfect. Anyone who’s wrestled with for_each
and dynamic blocks knows it can feel like you’re fighting the language. And yes, sometimes you wish you could just drop a real loop or function in there.
But that friction is intentional. HCL’s “simplicity ceiling” prevents configs from turning into full-blown software projects. Terraform wants you thinking about infrastructure states, not writing infra-flavored spaghetti code.
The fight over HCL isn’t really about syntax. It’s about philosophy: do we want infrastructure to look like code, or like configuration?
HashiCorp bet on configuration — and for all the complaints, that bet made Terraform the standard. If it had been a Python library, it probably would’ve ended up as just another provisioning framework.
HCL isn’t beautiful, but it’s pragmatic. It forces us to think declaratively, keeps the focus on infra states, and saves us from writing orchestration logic by hand.
So the next time someone complains “Why not just use Go/Python/TypeScript?”, the answer is simple:
Terraform doesn’t want you to write software. It wants you to write infrastructure.