So, you have a hundred VMs you need to manage, and you have ... Ansible ? I should stop here, as this is a tool that is standard in configuration management nowadays, but I'd dare to continue and say there is a better alternative to it.
But before we get into it, why am I so frustrated with Ansible? Here are my points:
YAML based declarative DSL really stinks on complex tasks as it lacks the flexibility that imperative languages have.
YAML is not even a programming language, and you gonna pay the price very soon.
To keep ansible code clean and simple, extra efforts are required, one need to refactor out all the complexity from YAML to python modules and this feels like "why I even start using YAML DSL"?
Ansible reports are frustrating as I always need to add these debug tasks to show real STDOUT/STDERR emitted from commands, where it should just work out of the box.
Ansible ties me to the idea of "running on a host," where sometimes I need to run tasks not tied to hosts, yes, you can still use "ansible_connection=local" but this feels awkward.
Meet Sparky
So, meet Sparky - elegant, efficient and all-battery included automation tool. It's written on powerful and modern Raku language, with bulma css frontend and web sockets.
To install Sparky - install Rakudo first and then install Sparky itself as a Raku module:
curl https://rakubrew.org/install-on-perl.sh | sh
eval "$(~/.rakubrew/bin/rakubrew init Bash)"
rakubrew download moar-2024.05
git clone https://github.com/melezhik/sparky.git
cd sparky/
# install Sparky and it's dependencies
zef install --/test .
# init sparky sqlite database
raku db-init.raku
# run sparky job runner
nohup sparkyd >~/.sparkyd.log < /dev/null &
# run sparky web console
cro run
This simple scenario gets it up and running; if you go to http://127.0.0.1:4000 you'll see a nice Sparky web console. We use the console to run sparky jobs.
Show me the design
So we have a control plane that would manage many hosts over ssh, using push mode:
---------------
| CP , Sparky |
---------------
[ssh]
/ / | \ \
host host host host host
This is pretty much what ansible does ...
Show me the code
Now say, we have 5 NGINX servers we need to restart, let's drop a simple Sparky job to do this in pure Raku language:
use Sparky::JobApi;
class Pipeline does Sparky::JobApi::Role {
method stage-main {
for 1..5 -> $i {
my $j = self.new-job :workers<5>;
$j.queue: %(
sparrowdo => %(
bootstrap => true,
host => "nginx_{$i}.local.domain"
),
tags => %(
stage => "child",
i => $i
)
);
}
}
method stage-child {
service-restart "nginx"
}
}
In this scenario, Sparky will run five parallel jobs that restart nginx on five hosts. Simple and elegant.
Moreover those five jobs will appear as five separate reports in Sparky UI …
Got interested?
Of course, this is only a quick glance at Sparky architecture and features, things to cover further:
- Job orchestration (DAGs)
- Core DSL (pure Raku)
- Custom UIs
- Authentication (oauth2) and security access list
- Writing more sophisticated scenarios
- Extending Sparky with plugins by using many programming languages
- Installing Sparky with MySQL/Postgresql database storage (instead of sqlite)
- Using Sparky as CI server (SCM triggering and cron jobs)
Links
Sparky project - https://github.com/melezhik/sparky
Top comments (0)