Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Being able to inherit from Ingress and add a parameter of say public=True/False and then it change annotations, middleware, etc and then being able to re-use that across 100s of stacks is very powerful. DRY is not something HCL is good at.




Getting too clever with an imperative language in what is inherently a declarative domain, is an idea bad enough that they invented a whole new language to avoid you doing it. But some lessons have to be learned the hard way I guess

The problem is they did an exceptionally poor job at designing their language. A reasonably large Terraform codebase is almost universally hard to read for one of two reasons: it's either unexpressive (read: verbose to the point it's hard to read) or modularized but hard to read because it's fragmented into a bajillion reusable modules.

SQL is also declarative, but incredibly expressive. A thousand character query contains enough complexity that it's hard to reason about. A thousand characters of Terraform will barely stand up a CRUD app on AWS.

Designing a language from first principles for this was a mistake. HCL is awful; they should have gone the Starlark route and made a stripped-down version of an existing language instead of making their own language from scratch. This feels like the worst of both worlds. The language is practically imperative, but it has its own syntax that isn't useful outside of this one single domain.


> reasonably large

Anyway you shouldn't have too many resources in a single Terraform workspace, for performance reasons. The real issues with Terraform come when you start to want to orchestrate different workspaces triggering each other, and trying to write that orchestration language, which itself would be declarative.

Terraform built a Stacks feature, but support is Terraform Cloud-only. OpenTofu has issues in the area that have been open for years: https://github.com/opentofu/opentofu/issues/931 https://github.com/opentofu/opentofu/issues/2860 and progress is slow, in part (IMO) because a genuine solution requires server-side evaluation (i.e. triggering applies as Kubernetes Jobs) and the open-source implementation of Terraform Enterprise/Cloud is a completely separate project with a completely different group of maintainers, Terrakube.


I'd argue the real issue with Terraform is that workspace orchestration is necessary in the first place. If they addressed the performance issues with large workspaces, then we wouldn't need to split up workspaces and Terraform could just orchestrate changes naturally.

The performance issues in large workspaces are due to needing to refresh status on all the resources in the large workspace before coming up with a plan. Actual apply time is either negligible or the inherently long amount of time it's supposed to take.

You split the workspace into smaller workspaces precisely to tell Terraform that you haven't made any changes to the networking layer, so don't bother trying to refresh the status of the networking layer to see if any changes are needed, it's not relevant when you're trying to scale up your Kubernetes cluster or whatever.


Declarative vs. imperative doesn't have anything to do with power or expressiveness. Some general purpose programming languages are declarative, and some declarative DSLs are Turing-complete.

I worry that comments like this lead the average newbie to overlook (or worse, avoid) declarative languages (both among DSLs and among general-purpose languages) because they will associate the term with hacky, confining, gotcha-ridden messes like Terraform's HCL, Azure DevOps' standards-breaking "YAML" DSL, etc.

Incidentally I agree that a language like Python is a terrible fit for this domain, but it's also plain to see that HCL is a shitty tarpit. It's not hard to understand why people want to get away from HCL.

And concretely, you can use Pulumi in a pure functional style with F# or Scala.


They invented a language to avoid you imperatively updating infrastructure, but that's not what CDKTF does; it just makes it easier to materialize that declarative output.

It also makes it easier to reason about that output as you can avoid awkward iteration in your declarative spec.


Yet said language continues to add imperative-inspired constructs to make up for its limitations..

The end result is still declarative, your just using an imperative language to keep your IaC DRY.


If you have the expertise and restraint to not go off the rails, I agree, imperative is more powerful. That plan does not survive teams of sizes over 2 in the majority of cases.

But it's not even imperative. Your code runs, declares all its resources up front and then normal terraform runs on it. With cdktf you can even have it output the HCL.

At the point where we are templating Terraform files we've already lost the plot. You might as well get to use a real programming language.


I have used Terraform, Puppet, Helm, and Ansible (although that's not strictly declarative), and all of them ran into problems in real-world use cases that needed common imperative language features to solve.

Not only does grafting this functionality onto a language after-the-fact inevitably result in a usability nightmare, it also gets in the way of enabling developer self-service for these tools.

When a developer used to the features and functionality of full-featured language sees something ridiculous like Terraform's `count` parameter being overloaded as a conditional (because Terraform's HCL wasn't designed with conditional logic support, even though every tool in this class has always needed it), they go JoePesciWhatTheFuckIsThisPieceOfShit.mp4 at it, and just kick it over to Ops (or whoever gets saddled with grunt work) to deal with.

I'm seeing the team I'm working with going down that same road with Helm right now. It's just layers of templating YAML, and in addition to looking completely ugly and having no real support for introspection (so in order to see what the Helm chart actually does, you essentially have to compile it first), it has such a steep learning curve that no one other than the person that come up with this approach wants to even touch it, even though enabling developer self-service was an explicit goal of our Kubernetes efforts. It's absolutely maddening.


That is... not a good idea at all imo. It's very, very easy to over-DRY infrastructure config and it sounds like you're well past that point.

Make a module



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: