I used to bootstrap a lot of VMs in development using shell scripts [1]. At a certain point Bash scripts become unmanageable. Ansible, Chef, Puppet have stricter syntax, battle-tested modules, large communities, proper multi-OS support, etc. Investing time to learn any of those tools certainly pays off in the long run.<p>Bash is great for a quick setup or a one-off instance. However it requires discipline for anything more. You are also dealing with the underlying OS yourself (e.g., Nginx is packaged and configured differently in Ubuntu, Debian, Cent OS & Arch; networking is configured differently in Ubuntu depending on whether systemd is installed, etc.).<p>[1] <a href="https://github.com/StanAngeloff/vagrant-shell-scripts" rel="nofollow">https://github.com/StanAngeloff/vagrant-shell-scripts</a>
Here is a declarative bash DSL I ran across a few months ago:<p><a href="https://github.com/mattly/bork" rel="nofollow">https://github.com/mattly/bork</a><p>and here is an example from their README:<p><pre><code> ok brew # presence and updatedness of Homebrew
ok brew git # presence and updatedness of Homebrew git package
ok directory $HOME/code # presence of the ~/code directory
ok github $HOME/code/dotfiles mattly/dotfiles # presence, drift of git repository in ~/code/dotfiles
cd $HOME
for file in $HOME/code/dotfiles/configs/*
do # for each file in ~/code/dotfiles/configs,
ok symlink ".$(basename $file)" $file # presense of a symlink to file in ~ with a leading dot
done</code></pre>
This is just plain a bad idea. Bash is the worst possible language. Yes, it can do it, but the syntax is awful. The problem of single quotes in double quotes in escaped double quotes.<p>I replaced a home grown, written by someone else, bash configuration management tool with Salt. The difference was huge.<p>Configuration management tools give you built-in logging, state checking, return codes, template libraries, and access to very mature models to access things like the AWS api.<p>I realize people don't like the steep learning curve, but there is a reason for it.
Honestly, I find ansible quite simple and straight forward. You don't have to use third party playbooks and using 'autoenv' I achieved a very straight forward, simple, dynamic setup.
Author claims all 90% of the time all they need is a single shell script. Then shows an example directory structure that mostly reminds me of Ansible.<p>How is Welder different from Ansible, except bash vs python?
I came from setup shell scripts (especially running in the postinstall step of debian-installer) to Ansible, and I think the big win with Ansible is at least the ideal of idempotency.<p>That's a lot harder to achieve with plain shell scripts, unless you're pretty disciplined about only performing mutations to your system that are themselves idempotent (like a package install).
I created something similar for Arch Linux:<p><a href="https://github.com/CyberShadow/aconfmgr" rel="nofollow">https://github.com/CyberShadow/aconfmgr</a><p>It has a few crucial differences from typical configuration managers, though, as it allows transcribing the system state back into your configuration.
Basically, this is SaltStack's salt-ssh re-implemented using bash instead of python... That too is just YML + Templates + Bash + SSH, with the exception that you can use Python too and the templates are JINJA.
If you don't like all the directories that Ansible playbooks require you can use the simple style of a single YAML file that describes the actions to take. Check out <a href="https://serversforhackers.com/an-ansible-tutorial" rel="nofollow">https://serversforhackers.com/an-ansible-tutorial</a>, the first introduction walks you through setting up just 2 files.
I did something Similar, but fully based in shell scripts with no dependencies -> <a href="https://gist.github.com/mariocesar/8e674ec40dad6b94114d2a44d9151e23" rel="nofollow">https://gist.github.com/mariocesar/8e674ec40dad6b94114d2a44d...</a><p>I completely agree with OP when Ansible is overkill for must cases, and even slower than a plain smart shell script.<p>For my solution, simple create a bash function:<p><pre><code> function play ()
local remote=${2}
local script=${1}
local directory=$(dirname ${script})
tar cpf - ${directory}/ | ssh -t ${remote} "
tar xpf - -C /tmp &&
cd /tmp/${dirname} &&
bash /tmp/${script} &&
rm -rf /tmp/${dirname} "
}
</code></pre>
and later just call it like.<p><pre><code> play provision/bootstrap.sh ubuntu@10.0.0.1
</code></pre>
Where provision is a directory, and bootstrap.sh is the main shell script.
Reminds me of <a href="https://github.com/brandonhilkert/fucking_shell_scripts/blob/master/README.md" rel="nofollow">https://github.com/brandonhilkert/fucking_shell_scripts/blob...</a>
I was really excited until I saw "Welder requires rsync, ruby and liquid" --- why do I need Ruby and all its dependencies here?<p>I tried <a href="https://github.com/myplaceonline/posixcube" rel="nofollow">https://github.com/myplaceonline/posixcube</a> and it has zero dependencies , just bash itself, and it is nice.
On the subject of non-approved sysadmin/devops tools,<p>I wrote a little 'tarball compiler' framework in mostly PMake some time ago to "DevOps" like it's 19[89]9 ... basically it will build per-host file overlay trees, rdist them out to target hosts, and then optionally run user defined start/stop/restart hook scripts when needed.<p><a href="https://github.com/ixcat/admmk/blob/master/doc/admmk.rst" rel="nofollow">https://github.com/ixcat/admmk/blob/master/doc/admmk.rst</a><p>unfortunately, though it will do per-host targets, I didn't get around to per-service targets.. should be feasable however.<p>Definitely a bit hairy, but hey, thats what quasi-functional symbolic makefile programming is all about my friends..<p>ps: if you think this is bad, try rewriting it in gnumake if that's even possible.. PMake! Woo!
There is really not much you can't do using HashiCorp's Packer[1] and Terraform[2].<p>Packer can generate base images and roles based on shell scripts and transferring files. Terraform manages the creation of infrastructure on clouds and can bootstrap instances with shell scripts as well.<p>[1] - <a href="https://terraform.io" rel="nofollow">https://terraform.io</a>
[2] - <a href="https://packer.io" rel="nofollow">https://packer.io</a>
Sup also works well<p><a href="https://github.com/pressly/sup" rel="nofollow">https://github.com/pressly/sup</a>
Similar tool: <a href="https://github.com/myplaceonline/posixcube" rel="nofollow">https://github.com/myplaceonline/posixcube</a>