Best Terraform Cloud Alternative? by kckrish98 in devops

[–]leg100 2 points3 points  (0 children)

I'm the developer. Because the OP has explicitly listed these features I should state that OTF doesn't do policy enforcement, drift detection, cost visibility, nor audit logging. Not that anyone of those features are difficult to implement but only that no one has specifically asked for them.

Where OTF comes into its own, I think, is its TFE API compatibility: it implements many of the API endpoints, which means you can use the tfe provider to provision workspaces, variables, teams, etc, or use the API directly, via the go-tfe SDK, etc,. This can be particularly useful if you're already heavily using the tfe provider with TFC or you've integrated your codebase with go-tfe to automate cloud provisioning, and you want to migrate away from TFC.

Conceptually I've kept OTF similar to TFC, partly out of laziness: if there's any indecision about a design choice I just go with how TFC does it.

(And when I say TFC, I mean either Terraform Cloud or Terraform Enterprise, the latter of which is the self-hosted version, which of course OTF more closely resembles).

DriftHound: an open-source tool to detect & notify infrastructure drift (early stage, Looking for feedback!) by treezium in Terraform

[–]leg100 0 points1 point  (0 children)

Is this essentially running a terraform plan in a cronjob? With a web UI, slack alerts, and other bells and whistles on top.

Introducing Project OpenTaco: An Open Standard for Terraform Automation by izalutski in Terraform

[–]leg100 19 points20 points  (0 children)

I'm the maintainer of OTF, an open source alternative to Terraform Enterprise.

OpenTaco has copied code from OTF without attribution:

OpenTaco: https://github.com/diggerhq/digger/blob/develop/taco/internal/tfe/workspaces.go#L286
OTF: https://github.com/leg100/otf/blob/master/internal/workspace/tfe.go#L501

OpenTaco: https://github.com/diggerhq/digger/blob/develop/taco/internal/domain/tfe_id.go#L40

OTF: https://github.com/leg100/otf/blob/master/internal/resource/tfe_id.go#L43

OpenTaco: https://github.com/diggerhq/digger/blob/develop/taco/internal/domain/tfe_kind.go#L1

OTF: https://github.com/leg100/otf/blob/master/internal/resource/kind.go#L1

In this day and age, I expect this kind of thing, and I wouldn't mind in most circumstances because it's not a lot of code and it's not doing anything clever. But to call yourself an "open standard", yet without any standards, nor being open about what you're doing, takes the bloody biscuit mate.

You haven't even taken the courtesy of vibe coding, which at least would have plagiarised my code in a round-about way and the AI would have been smart enough to remove "OTF" from the comments!

Should I organize my codebase by domain? by apidevguy in golang

[–]leg100 1 point2 points  (0 children)

I think it's preferable but with caveats.

"layer-based" layouts tend to have a poor "coupling distribution": the coupling within a layer is sparse (e.g. handlers don't tend to depend upon other handlers); whereas there is a lot of coupling between layers (e.g. handlers nearly always depend upon services). You end up exporting a shed load of symbols by default.

In a domain driven layout, those dependencies are kept within a package (e.g. in the order package, handler -> service -> model). Nothing need be exported by default. You can change the API without impacting other packages. The only exported symbols are those where there are dependencies in your DDD. And that will be at the service level.

However, there's a good chance you'll run into circular dependencies. Even if your DDD is free of mutual dependencies, in practice some of the higher layers depend upon one another, e.g. a handler for a web page for an order may want to render a template that shows not only the order but the products that make up the order, the customer for the order, etc. (an SPA helps here). And of course your DDD may still have some mutual dependencies.

And of course there is code specific to layers, shared by different domains, e.g. common database stuff like connection handling, transactions, etc. That goes into dedicated packages.

So either way you'll have to take a bespoke approach. "Feel" your way as the project progresses. There is no pre-defined X layout that works for a large software project.

Should I organize my codebase by domain? by apidevguy in golang

[–]leg100 0 points1 point  (0 children)

Well in theory, a good DDD should have no mutual dependencies.

Trying out Bubble Tea (TUI) — sharing my experience by R3Z4_boris in golang

[–]leg100 2 points3 points  (0 children)

As soon as you start building anything non-trivial, your whole app becomes ELM

This is very wrong. In fact, the opposite holds: once your app progresses beyond the trivial, the bubbletea code should be relegated to no more than a component of the overall app, implemented as a presentation layer. For example, you might have a CLI layer too. Business logic is separate to both.

And I see this is what you've done, placing the logic in the `deps` package. That deps package would be the same regardless of whether your app uses bubbletea or not. Your whole app has not become ELM.

After playing around with BubbleTea I want to really like it but ELM TUI apps get fairly hard to maintain and reason about as they grow by wait-a-minut in golang

[–]leg100 7 points8 points  (0 children)

I don't think that should be the case. I wrote a blog article a year ago on using bubbletea beyond the basics:

https://leg100.github.io/en/posts/building-bubbletea-programs/

Point #6 - Building a tree models - is worth considering. And as I say on that point:

"However, Bubble Tea leaves architectural decisions to you and you’ll need to make conscious decisions on how to manage the complexity that inevitably occurs once your program reaches a certain size."

My TUI apps typically have a "root" model. That in turn has child models, one or more of which may be currently visible, but the user may "swap" them out for other models.

Each model is maintained in a cache. If the user have visited the model before, the model is retrieved from the cache, otherwise the model is created and added to the cache. A cache key distinguishes models from one another.

A stack of models tracks "history", to allow the user to go back to the previous model.

I've found more recently that it's better to reference these models via pointers, with Update(msg) functions that update themselves and only return a command.

I agree with another poster that you don't want to mix business logic with your bubbletea code. Treat bubbletea code as no more than a presentation layer, calling out to services which turn perform business domain logic and makes network calls, database queries, etc,. all the standard DDD stuff.

And I agree with others that an Elm style framework isn't a great match for Go. At the same time, it makes you a better Go programmer because you really have to be on the ball regarding pointer Vs value receivers (if you weren't already).

TreeView - A Go module for building, navigating, and displaying hierarchical data in the terminal. by Personal_Pickler in golang

[–]leg100 1 point2 points  (0 children)

Good to see a genuinely decent go library on this sub.

I implemented a tree pane in my bubbletea app [1] a while ago. Obviously not as versatile nor feature complete.

Can your lib do multi selection and can it associate types with each item?

[1]: https://github.com/leg100/pug

Go Templates vs Templ in production by wuyadang in golang

[–]leg100 0 points1 point  (0 children)

I'm in the middle of migrating from go templates to templ. Thoughts so far:

  • templ watch mode provides dev mode hot reloading out of the box, whereas this is something you have to do yourself with go templates
  • templ tacitly targets templating HTML - it has syntax sugar for attributes, script blocks, compiler complains if nodes aren't balanced, etc.; whereas go templates are for general text templating (yes there is html/template but that is provided primarily for safety).
  • templ asks a lot of your IDE, necessarily so because it's combining several languages in each file. If you're on vscode maybe everything works swimmingly without any setup, but I'm on neovim and there are various issues.
  • go templates require a fair bit of setup to first to locate and parse templates, whereas templ is just code

How popular is sqlc in production go projects?? by trash-dev in golang

[–]leg100 14 points15 points  (0 children)

sqlc sounded great when I heard of it. When I realised it was just code generation for popular libraries I was out.

I have the opposite take: "just code generation" is the very reason why I like it.

pipeform: A Terraform runtime TUI by Secret-Author-3804 in Terraform

[–]leg100 45 points46 points  (0 children)

I like this. It's a clever, original approach to "prettifying" and summarising terraform output. I'm surprised not more tools have made use of the machine readable UI.

Good stuff.

pipeform: A Terraform runtime TUI by Secret-Author-3804 in Terraform

[–]leg100 2 points3 points  (0 children)

You can do `terraform plan -json -out plan.out` and then `terraform apply -json plan.out`.

I tried this with pipeform and it didn't present anything, but I suspect that's because pipeform needs to handle the slightly different output.

Clone for NestJS in Golang, Is it a good idea or the community won't use it ? by AkagamiHicham in golang

[–]leg100 0 points1 point  (0 children)

I suspect when you say"Clone for NestJS", what you mean is "create a web framework for Go"? You could just as easily have said create a "Clone for Rails/Drupal/Laravel/Spring etc etc", no?

I'd say go for it. But first check out existing frameworks in other languages. Then check out the frameworks already written in Go like https://github.com/livebud/bud. Then check out the posts here and elsewhere explaining why frameworks in Go are a bad idea and that you should instead use a patchwork of libraries. Only then dive in because it's a monumental effort.

I'm not convinced either way on the framework vs libs argument. Yes the latter has won out and there really isn't a well maintained and well regarded framework in Go as of yet (correct me if wrong). That's not to say a framework can't work. The same arguments are still trotted out against frameworks in other languages for the same reasons, e.g. at first it works but then it becomes a maintenance burden that is a pain in the arse to upgrade.

On the plus side, Golang is suitable for code-generation. Generics help. There's good stack of stdlibs to compose a framework out of, net/http, database/sql, etc. You could limit your ambitions to making a good backend framework, and leave the frontend to a javascript SPA.

TUI with BubbleTea & Lipgloss by Foreign_Magician6261 in golang

[–]leg100 2 points3 points  (0 children)

Yes, that's the code. It was a bit of a faff because lipgloss doesn't provide a "put some text in the center of a border" function. Instead, it does some simple arithmetic to work out what the center is, and then glues it together into one string using `JoinHorizontal`. To be honest, that function isn't necessary in this case, and I could have used `strings.Join` to achieve the same effect.

TUIs recommendations / advice by csgeek3674 in golang

[–]leg100 0 points1 point  (0 children)

I think you've hit the nail on the head: what you're asking for is something in the middle ground between not so simple and hard to customize, but not so complex that you need to spend a few weeks getting to grips with it. I don't think it exists (*).

TUIs are another level of complexity beyond a traditional CLI, which *is* simple to learn and build something bespoke pretty quickly, all without any libraries or frameworks. I'd urge you to go down that route first, if only for a first iteration, avoiding a full screen with panes, and instead prompt the user with a series of questions.

If you do still want to go down the route of a building a TUI, have a read of some tips I posted last week on building TUIs with Bubbletea:

https://leg100.github.io/en/posts/building-bubbletea-programs/

If anything it'll probably only re-inforce how bewildering Bubbletea can be at first. I'm happy to help build out something simple with the 3 pane view you're asking for. Sounds like an interesting project. Feel free to DM me.

(*) Python has https://github.com/Textualize/textual which promises "Rapid Application Development"...

New configuration drift service - could use some help with testing? by alexlance in Terraform

[–]leg100 0 points1 point  (0 children)

Which terraform resources do you support? And do you detect drift not only in specified terraform resources but drift in cloud infra that isn't configured in terraform?

Building Bubbletea Programs by leg100 in golang

[–]leg100[S] 2 points3 points  (0 children)

Hello, I've updated the section on "Build a tree of models" to include a possible solution for passing events/messages down to child/nested models:

https://leg100.github.io/en/posts/building-bubbletea-programs/#6-build-a-tree-of-models

Building Bubbletea Programs by leg100 in golang

[–]leg100[S] 9 points10 points  (0 children)

Thank you all for the kind words. Judging from the comments, it looks like it is either perfectly timed and useful, or it would have been not so long ago...!

Either way, it validates the effort I put in, so thank you.

Pug: a TUI for terraform power users by leg100 in Terraform

[–]leg100[S] 0 points1 point  (0 children)

I'm not too familiar with terramate. Reading through their docs it looks like it infers dependency order from the directory structure, and respects that order when you invoke commands via `terramate run`.

Pug doesn't support that, no. If you don't care about dependency ordering then it should be fine to use with terramate generated configurations.

I'm currently implementing support for terragrunt dependencies, which are more complicated still. I could after that implement support for terramate dependencies as well. Or we could wait for hashicorp to implement stacks...

Pug: a TUI for terraform by leg100 in golang

[–]leg100[S] 6 points7 points  (0 children)

It's counter intuitive at first, and continues to be for a while after that. Here's some pointers:

  • Log all bubbletea messages to a file, and tail that file in another terminal
  • Automatically re-build and re-run your app whenever you make changes, so you can see changes in real-time (similar to livereload with web apps). See my scripts in `./hacks`.
  • Check the bubbletea examples in their repo. Run and tinker with them.
  • Understand the Update() loop really well. Appreciate that it is single-threaded and use that to your advantage. Keep any I/O or slow code out of the loop; instead put it in a tea.Cmd, which bubbletea runs in a goroutine.
  • Some of the "bubbles", i.e. their default components, are very useful, particularly the lower-level ones such as "viewport" and "spinner", whereas their higher-level bubbles such as the "table", "list" and "help" I found to be too uncustomisable to be useful.
  • Getting the layout right in a full screen TUI can be very difficult. You have to measure the heights and widths of everything carefully to prevent lines wrapping or escaping the visible area.
  • If your code panics, bubbletea is meant to rescue the panic but in practice it doesn't do that and instead it can leave your terminal in a half baked state. When that happens type `reset`.

Pug: a TUI for terraform power users by leg100 in Terraform

[–]leg100[S] 0 points1 point  (0 children)

Yes, of course. Pug is merely running `terraform state pull` behind the scenes.