Skip to content(if available)orjump to list(if available)

Yoke: Infrastructure as code, but actually

danw1979

I think a majority of the rants about Terraform I read are written from the perspective of someone managing inherently ephemeral infrastructure - things that are easily disposed of and reprovisioned quickly. The author of such a critique is likely managing an application stack on top of an account that someone else has provided them, a platform team maybe. CDK probably works for you in this case.

Now, if you belong to that platform team and have to manage the state of tens of thousands of "pet" resources that you can't just nuke and recreate using the CDK (because some other team depends on their avaiability) then Terraform is the best thing since sliced bread; it manages state, drift, and the declarative nature of the DSL is desirable.

Horses for courses.

robertlagrant

For me Terraform's biggest strength is also its biggest source of pain: it can integrate all sorts of technologies under one relatively vendor-agnostic umbrella and enforce a standard workflow across a huge amount of change. However, that means any bug in any provider is sort of Terraform's fault, if only in the developer's mind.

bayindirh

> Horses for courses.

I think with YMMV, these are the two most important things we need to keep in our mind. With plethora of technologies and similar tools, we generally read the tin superficially but not the manual, and we declare "This is bollocks!".

Every tool is targeted towards a specific use and thrive in specific scenarios. Calling a tool bad for something not designed for is akin to getting angry to your mug because it doesn't work as well when upside down [0].

[0]: https://i.redd.it/mcfym6oqx5p11.jpg

solatic

> If you really do think that Terraform is code, then go try and make multiple DNS records for each random instance ID based on a dynamic number of instances. Correct me if I'm wrong, but I don't think you can do that in Terraform.

It depends on where the source of dynamism is coming from, but yes you can do this in Terraform. You get the instances with data.aws_instances, feed it into aws_route53_record with a for_each, and you're done. Maybe you need to play around with putting them into different modules because of issues with dynamic state identifiers, but it's not remotely the most complicated Terraform I've come across.

That's a separate question from whether or not it's a good idea. Terraform is a one-shot CLI tool, not a daemon, and it doesn't provide auto-reconciliation on its own (albeit there are daemons like Terraform Enterprise / TerraKube that will run Terraform on a schedule for you and thus provide auto-reconciliation). Stuff like DNS records for Kubernetes ingress is much better handled by external-dns, which itself is statically present in a Kubernetes cluster and therefore might be more properly installed with Terraform.

voidfunc

I ditched Terraform years ago and just interact with the raw cloud provider SDKs now. It's much easier to long-term evolve actual code and deal with weird edgecases that come up when you're not in beholden to the straight jacket that is configuration masquerading as code.

Oh yea, and we can write tests for all that provisioning logic too.

kikimora

I’ve been thinking about this for a long time. But doesn’t it brings a host of other issues? For example, I need to update instance RAM from 4 to 8 Gb but how do I know if the instance exists or should be created? I need to make a small change, how do I know what parts of my scripts to run?

voidfunc

You write code to do these things? If there's a requirement for you to be able to do such a thing make it a feature, implement it with tests and voila, no different than any other feature or bug you work on is it?

diggan

> For example, I need to update instance RAM from 4 to 8 Gb but how do I know if the instance exists or should be created?

    let front_id = if instance_exists("front_balancer") {
      return fetch_instance("front_balancer").id
    } else {
      return create_new_instance("front_balancer", front_balancer_opts).id
    }
Or however else you would manage that sort of thing in your favorite programming language.

> I need to make a small change, how do I know what parts of my scripts to run?

Either just re-run the parts you know you've changed (manually or based on git diffs), or even better, make the entire thing idempotent and you won't have to care, re-run the entire program after each change and it'll automagically work.

plmpsu

How are you handling creating multiple resources in parallel? or rolling back changes after an unsuccessful run?

gorgoiler

Not OP, but for rolling back we just… revert the change to the setup_k8s_stuff.py script !

In practice it’s a module that integrates with quite a large number of things in the monolith because that’s one of the advantages of Infrastructure as Actual Code: symbols and enums and functions that have meaningful semantics in your business logic are frequently useful in your infrastructure logic too. The Apples API runs on the Apples tier, the Oranges API runs on the Oranges tier, etc. etc.

People call me old fashioned (“it’s not the 1990s any more”) but when I deploy something it’s a brand new set of instances to which traffic gets migrated. We don’t modify in place with anything clever and I imagine reverting changes in a mutable environment is indeed quite hard to get right (and what you are hinting at?)

solatic

> I imagine reverting changes in a mutable environment is indeed quite hard to get right (and what you are hinting at?)

I guess you're not managing any databases then? Because you can't just treat those immutably, you have to manage the database in-place.

beacon294

I agree that the SDK is better for many use cases. I do like terraform for static resources like aws vpc, networking, s3 buckets, etc.

akdor1154

Hill I will die on: Terraform being less expressive than a real language is a feature, not a drawback.

CDK/Pulumi/Yoke is optimised for being easy to write, but code should be optimised to be easy to READ.

Sure, cdk/pulumi/yoke lets you write the most clever and succinct construction you can compose in your favourite language.. however, whoever comes across your clever code next will probably want to hit you, especially if it's not a dev from your immediate team, and especially if you have succumbed to blurring the lines between your idk code and your app code.

If they instead come across some bog-standard terraform that maybe has a bunch of copy-paste and is a bit more verbose... Who cares? Its function will be obvious, there is no mental overhead needed.

On the flipside Helm templating is an absolute abomination and i would probably take anything over needing to immerse myself in that filth, maybe Yoke is worth a look after all. But the REAL answer is a real config language, still.

Aeolun

> code should be optimised to be easy to READ

You say that as if it’s impossible to write clear code. As soon as you have any form of multiple resources (e.g. create x of y) I’ll take the real programming language over terraform.

liampulles

As the Go proverb goes: "clear is better than clever". https://go-proverbs.github.io/

WatchDog

I'm quite happy with CDK[0].

My experience is only with the main AWS cloudformation based version of CDK, although there is also CDK for terraform, which supports any resource that terraform supports, although some of what I'm about to say is not applicable to that version.

What I like about CDK, is that you can write real code, and it supports a wide range of languages, although typescript is the best experience.

Provided that you don't use any of the `fromLookup` type functions, you can run and test the code without needing any actual credentials to your cloud provider.

CDK essentially complies your code into a cloudformation template, you can run the build without credentials, then deploy the built cloudformation template separately.

You don't need to worry about your terraform server crashing half way though a deployment, because cloudformation runs the actual deployment.

[0]: https://github.com/aws/aws-cdk

cedws

In your experience how often have you had template builds succeed but then fail at apply time? This kind of issue is what I find most frustrating about IaC today, your 'code' 'compiling' means nothing because all of the validations are serverside, and sometimes you won't find out something's wrong until Terraform is already half done applying. I want to be able to declare my infrastructure, be able to fully validate it offline, and have it work first try when I apply it.

Aeolun

I find Pulumi very nice here because it persists state after every successful resource creation. If it breaks somewhere in the middle, the next run will just pick up where it left off last time.

CDK… well, CDK doesn’t get in an invalid state often either, but that’s because it spends 30m rolling back every time something goes wrong.

WatchDog

I've had less such issues with CDK, versus raw cloudformation, or terraform, but it can still happen.

skinkestek

>> Wait, there's something here that I'm not getting. Why are you compiling the code to WebAssembly instead of just running it directly on the server?

> Well, everything's a tradeoff. Let's imagine a world where you run the code on the server directly.

> If you're using a language like Python, you need to have the Python runtime and any dependencies installed. This means you have to incur the famous wrath of pip (pip hell is a real place and you will go there without notice). If you're using a language like Go, you need to have either the Go compiler toolchain installed or prebuild binaries for every permutation of CPU architecture and OS that you want to run your infrastructure on. This doesn't scale well.

> One of the main advantages of using WebAssembly here is that you can compile your code once and then run it anywhere that has a WebAssembly runtime, such as with the yoke CLI or with Air Traffic Controller.

At this point, why not use a proper runtime like JVM or .Net?

Then one can also easily use reasonable languages like C#, Java or Kotlin as well.

LoganDark

> At this point, why not use a proper runtime like JVM or .Net?

Because then you are forced to only use managed languages?

skinkestek

Ahh, good point.

I guess Rust (and maybe other unmanaged languages) can be compiled to WebAssembly?

LoganDark

https://logandark.net/calc is C++ compiled to WebAssembly using Emscripten. Back from I think 2018.

These days Rust is practically the poster child of compiling to WebAssembly because it's so easy. Most WASM content I see is actually about Rust.

bbu

Looks promising but it starts with a (justified) rant about terraform and then goes into how to replace Helm.

I am confused. Can yoke be used to create and manage infrastructure or just k8s resources?

thayne

Indeed. This isn't really a replacement for terraform, unless you are only using terraform to manage k8s resources. Which probably isn't most people who are currently using Terraform.

xena

Author here. It's mainly for k8s resources; but if you install operators like external-dns or something like crossplane into your cluster, you can manage infra too.

groestl

> into your cluster

I guess the point is: what if you don't have a cluster.

sureglymop

What alternative to terraform would one use to set up the whole cluster before provisioning any resources?

I currently have a custom script that is a mix between terraform and ansible that sets up a proxmox cluster, then a k3s cluster and a few haproxys with keepalived on top. Granted, maybe not the most standard setup.

bbu

ok, that makes sense. A better Helm would be nice. timoni.sh is getting better and better, but Cue is a big hurdle.

Unfortunately, I'm not a big fan of the yaml-hell that crossplane is either.

But as a Terraform replacement systeminit.com is still the strongest looking contender.

jonasdegendt

> A better Helm would be nice.

Consider CDK8s (Typescript or Go) or Jsonnet. We evaluated Cue and the two aforementioned options and ended up with CDK8s using Typescript and it's incredibly powerful.

danw1979

It’s just a dunk on terraform to promote yet another K8s provisioning thing.

beacon294

> If you really do think that Terraform is code, then go try and make multiple DNS records for each random instance ID based on a dynamic number of instances. Correct me if I'm wrong, but I don't think you can do that in Terraform.

It's possible a few ways. I prefer modules, and this LLM answer describes an older way with count and for_each.

It's always possible that incantation of the problem space has a gotcha that needs a work around, but I doubt it would be a blocker.

https://www.perplexity.ai/search/if-you-really-do-think-that...

thayne

> This is not code. This is configuration.

I don't think those two things are mutually exclusive.

IMO hcl is absolutely code. As is html, and css, json, and yaml.

It isn't a full programming language, and I often wish it was, but I wouldn't say it isn't code.

voidnap

JSON YAML are file formats for data. Is XML code? Is SVG code? Is a GIF code? Is a BMP code?

iliec

This seems like a great approach that sits between using the sdk directly and a dsl/yaml. My experience has been that most of the people configuring these systems don’t know how to code, and configuration languages is their gateway. Most never venture past configuration which is why yaml is so used and difficult to get any traction outside of it. I think terraform adopted some of the patterns which have been around since a long time ( remember the chef va puppet discussion from a decade ago) and it massively helped with adoption. Cue seems a step up from terraform ( you can use cue vet for type checking, even if CRDs are not yet supported all the way) but tracking seems to be low as it’s hard for non-programmers to grasp. Maybe Claude will help to move all people that don’t want to manage these systems with code to something even more simpler than yaml and open the door for real infra as code for the rest.

solatic

> My experience has been that most of the people configuring these systems don’t know how to code, and configuration languages is their gateway

I don't really disagree but this is such a pessimistic, NIH-syndrome viewpoint. Feel free to look at the code for any of the major Terraform providers. There's a lot of production-hardened, battle-tested Go code that's dealing with the idiosyncrasies of the different cloud APIs. They are an incredibly deep abstraction. Terraform also implicitly builds a DAG to run operations in the right order. Comparing writing HCL to writing straight Go code with the AWS SDK, the HCL code has something like an order of magnitude fewer lines of code. It absolutely makes sense to use Terraform / HCL instead of writing straight Go code.

sepositus

Yeah, don’t really understand the sentiment here. I’ve been programming for 20 years and actively use Terraform and CUE at work. I actually write a lot of Go code for our platform, but I’ve never once thought it’d be a good idea to just start calling APIs directly.

Stranger43

But doesn't the codeless "infrastructure as code" kind of smell like cargo cult practices, i mean there might be places where having your infrastructure defined as data is a really good thing, but at least in my work i keep hitting roadblocks where i really wish i was writing actual logic in a modern scripting language rather then trying to make data look like code and code look like data, which is what a lot of devops tutorials seem to be teaching.

iliec

> traction seems to be low when referring to cue. Autocorect issue

solatic

> If you're using a language like Go, you need to have either the Go compiler toolchain installed or prebuild binaries for every permutation of CPU architecture and OS that you want to run your infrastructure on. This doesn't scale well.

This is exactly the approach that Terraform takes. Both Terraform and its providers are written in Go, which is a great language for this purpose because of GoReleaser and the ease of compiling to different architectures and OSes. It scales just fine.

Did the author talk to any senior Terraform practicioners before building this?

davidmdm91

Hi. I think the article was just showing the example that IaC tools use configuration languages instead of code. Yoke is not a terraform replacement, and does not mention terraform anywhere its documentation.

It does sit at the same level as helm & timoni. It just takes a code-based approach to managing your cluster (which in turn can manage your infra but that wasn't the larger point).

supriyo-biswas

I feel that writing out infrastructure templates through a "proper programming language" (for the lack of a better term) comes with some sharp tradeoffs that many don't recognize.

A big feature of most IaC tools is that they are relatively logic-less and therefore can be easily understood at a glance, allowing for easier reasoning about what resources can be created, and this ability is diminished by introducing logic, and debugging issues in them becomes a nightmare. A large company I used to work for had a system just like that, and while I thankfully never had to work with said system, hearing statements like you can "debug your templates with pry[1]" being touted as a feature is something I hope to never hear again.

[1] https://github.com/pry/pry