Automation tools are some of the best QoL services I’ve deployed in my home lab, though they can require a little bit of finesse to master. This holds especially true for DevOps and sysadmin-centric utilities, as they often require tons of scripts and terminal commands. Ansible is one such tool, and it’s perfect for configuring virtual machines and containers en-masse. Unfortunately, its CLI-heavy nature can make it rather complex and clunky to use, especially once you create as many Ansible documents as I do.

That’s when I ran into Semaphore, a companion app for Ansible that provides a sleek UI for managing (and executing) config files. Now that I’ve been using it for a while, I must admit that it’s a must-have tool for Ansible enthusiasts.

Why should you bother hosting Semaphore?

All your Ansible documents, accessible from a neat UI

Ansible executes automation workflows using playbooks, which are akin to blueprints outlining tasks and their execution procedures. While playbooks are pretty easy to create once you get the hang of them, running them is a bit tedious if you use Ansible extensively in your home lab.

For example, I’ve got separate playbooks for updating packages, adding users, monitoring services, managing files, and modifying network settings. Since most VM distros in my home lab have separate package managers, I’ve made multiple playbooks to arm freshly-configured apps with my favorite distros. That’s before you include the variable files, inventory config, host documents, and other artifacts required by Ansible to execute automation chains. Since Ansible mainly relies on terminal commands, I have to constantly switch directories when deploying tasks from my library of playbooks.

Semaphore solves this issue by offering a sleek interface for all my Ansible documents, including inventory files for hosts, key stores for credentials, and project repos. Many of these, like the config files containing the host IP addresses and the key store documents containing the user credentials, can be interlinked even when they are in entirely different project directories. That’s a huge benefit when your Ansible setup is as chaotic as mine, and you can even connect GitHub repos to Semaphore and pull your playbooks from there.

Semaphore can run (and schedule) your playbooks

While the ability to organize Ansible files is indeed helpful, the ability to execute playbooks from a centralized web interface is the best aspect of Semaphore. The Task Templates section lets you create reusable (or rather re-runnable) templates out of pre-existing Ansible playbooks, inventory configs, credential vaults, and other artifacts.

For folks who want to fine-tune their automation flows even further, Semaphore also lets you add tags, branch details, survey variables, CLI arguments, and a couple of other parameters to the template. Plus, Semaphore lets you schedule the execution tasks for templates, and you can even run parallel tasks if you want to configure multiple virtual guests simultaneously.

Built-in alerts and troubleshooting provisions

Troubleshooting is one of the most important aspects of automation, as it’s easy to make mistakes even when you’re an Ansible veteran. Fortunately, Semaphore has some tricks up its sleeve to help you diagnose faulty config files. Similar to the command-line interface you’d use with a barebones setup, Semaphore provides detailed logs if things go wrong when running a Playbook, and you can add the -v argument inside a template to get verbose details about the errors.

Likewise, the Activity tab lists all the operations during an automation flow, so you can narrow down the steps where the execution chain went south. It even has a built-in notification facility, so you can get alerts when Semaphore can’t run your playbook tasks. Telegram is available on the Semaphore UI by default, though you can modify the config.json file for the platform to add support for emails, Slack, and (my favorite) Gotify.

Setting up Semaphore

Plenty of ways to get it up and running

Semaphore, like other developer-centric tools, can be deployed in a variety of ways. I’m a fan of containerized setups, especially since installing the binary package and configuring a database server separately seems like a lot of hassle. While there are dedicated Docker Compose files for Semaphore out there, I went with a good ol’ Proxmox-powered LXC instead.

Thanks to the amazing Proxmox VE Helper-Scripts repository, deploying Semaphore was as simple as running the bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/semaphore.sh)" command inside the Shell tab of my PVE node. After choosing the Default settings and waiting for Proxmox to work its magic, I headed into the Semaphore LXC’s Console menu and typed cat ~/semaphore.creds to grab the password. Switching to the Semaphore container’s web UI, I entered admin as the Username alongside the Password I copied earlier. With that, it was time to create and deploy some playbooks.

You’ll have to add multiple files to the server though

One of my favorite aspects of the Semaphore LXC is that it not only configures the database for the app, but it also installs Ansible, so I don’t need to set up the automation platform separately. Unfortunately, Ansible requires a couple of other documents besides playbooks, so I had to set those up first.

I started things off with the inventory file, which is responsible for pointing Ansible automations to the client IP addresses. Although I could’ve created a file on the Semaphore LXC and linked to it, I made a static file inside the Inventory tab and added the following code to it.

[ayushs-server]
192.168.0.94

Next, I had to create a project repo, which is essentially a folder containing my playbooks. So, I went back to the Semaphore LXC tab on my Proxmox node and used the mkdir command to create a path inside the home folder. Then, I added this location to the Repository tab on Semaphore’s web UI. I also had to add the user credentials for this virtual machine, or else I wouldn’t be able to execute automation scripts on it. I did that by opening the Key Store tab and adding a Username and Password.

Finally, it was time to create a playbook for my VM. I headed back to the Semaphore LXC inside Proxmox’s interface and used the nano editor to create a new file that ends with the .yml extension. To keep things simple, I created a test playbook that installs Krita on the VM by adding the following code to it (with the right indentation, of course).

--
- hosts: all
become: true
tasks:
- name: Krita setup
apt:
name: krita
state: latest
update_cache: true

With all artifacts set up, I navigated to Task Templates inside Semaphore’s web UI and chose Ansible Playbook as the task I wished to create. Then, I added the LXC directory of the playbook as the Path and chose the Inventory and Repository options I’d set up earlier. I left the Variable Group empty and added the credentials from earlier under the Vault option before pressing the Create button. As a test, I ran the newly-created template, and within a few minutes, my Semaphore-powered Ansible instance had successfully installed Krita on my Debian VM.

Semaphore is quite a powerful tool for automation lovers

I’ve spent the last weekend messing around with Semaphore’s options, and it’s a powerhouse if you’re into hardcore home lab/DevOps experiments. I’ve created a handful of Ansible documents spread across multiple directories, and the ability to choose them when creating a template is a game-changer for my disorganized setup. Besides Ansible, Semaphore also supports Terraform, and I’m already itching to get my hands dirty with some VM-provisioning automations – especially since I use Terraform and Ansible with my Proxmox cluster to train my sysadmin skills.