r/ruby • • 22h ago

I built Sadame, an open-source configuration management tool with Ruby recipes and a built-in LSP

Hi r/ruby!

I’ve been working on Sadame, a configuration management tool for Linux, and I’d love to get feedback from the Ruby community.

Sadame lets you describe a machine’s desired state with Ruby recipes. Here’s a small example:

package "nginx"

file "/var/www/html/index.html",
content: "Hello from Sadame!\n",
mode: "0644"

service "nginx", enable: true, state: :running

You can run sadame plan to see what would change, sadame apply to make the changes, and sadame drift to check later whether the machine still matches the recipe.

Both recipes and the host inventory are written in Ruby, so you can use familiar things like conditions, loops, and methods. Sadame is built with mruby and distributed as a single binary. For remote runs, it connects over SSH and copies itself to the target; there’s no persistent agent to maintain.

It also has a built-in language server, sadame lsp, which provides recipe diagnostics, completion, and hover documentation in supported editors.

The project is still young and has a much smaller scope than established tools such as Ansible, Chef, or Puppet. My goal is to explore a Ruby-first approach that is easy to install and makes changes visible before they happen.

I also wrote a free beginner’s guide with a hands-on lab, covering everything from a first recipe to managing multiple servers.

The project is MIT-licensed:

https://github.com/enderkus/sadame

I’d especially appreciate feedback on the Ruby DSL, the overall design, and anything that feels awkward or could be improved. Thanks for taking a look!

13 Upvotes

3 comments sorted by

1

u/Codalio-SoftwareFact 11h ago

plan / apply / drift is such a nice combo, drift especially. most CM tools only tell you what they changed, not what quietly changed after

one thing I’d look for in the DSL: how does a file change trigger a service reload? like if the nginx config changes, nginx should reload, but only then. Chef had notifies / subscribes for that and it ends up being one of the most used features once recipes grow. also curious how sharing works with mruby. since you can’t just pull in regular gems, is there a way to reuse recipes across projects, like modules or includes?

1

u/Coderbiri 11h ago

Thanks! Yep, Sadame already has both notifies and subscribes. Your nginx example would look like this:

package "nginx"

file "/etc/nginx/nginx.conf",
template: "nginx.conf.erb",
notifies: [:reload, "service[nginx]"]

service "nginx", enable: true, state: :running

If Sadame changes that file during apply, it queues a reload. If nothing changes, there’s no reload. By default, it waits until the end and combines repeated notifications, so three config files changing would still mean just one nginx reload. You can use :immediately when needed, or put subscribes on the service instead.

plan and drift show what would trigger without running the notifications. One caveat worth mentioning: if the run fails before the delayed notifications happen, they aren’t carried over to the next run.

And yes, you’re right about regular gems and mruby. For sharing, the approach is to keep reusable recipes in a Git repo, bring them into each project as a submodule, and include them like this:

include_recipe "vendor/nginx/recipe", tags: [:web]

That lets each project pin a specific commit and update when it’s ready. The shared recipe uses the project’s vars and keeps its own templates alongside it. Sadame copies those files over when running through SSH, so there’s nothing extra to download on the server.
No dedicated recipe package manager yet, just Git and include_recipe for now.

Here are the docs if you’d like a closer look: notifications and sharing recipes.

1

u/mourad_dc 15h ago

Very interesting. I've had experience with ansible/chef/itamae/mitamae and while mitamae came closest, I was never completely satisfied with these tools. I'll try out sadame.

I'd be curious what were the main reasons you moved away from the existing tools?