Complete Ansible Semaphore Tutorial: From Installation to Automation

Semaphore is very easy to set up and use, and can be a great asset to those of you that are currently using Ansible. And even if you’re not an Ansible user, you might become one if you spend time with Semaphore. Ansible is the leading configuration management solution, and Semaphore makes Ansible easier than it already was.

Also, Semaphore is free, so you can set it up right now if you want to, with no sales reps or company’s to deal with. It’s an open source application written in Go, so you can skip all the red tape and get it deployed.

So in this video, what I’ll do is show you the process of installing Semaphore, and then I’ll show you around the UI. After that, I’ll give you an example playbook you can run.

YouTube player

If you want to follow along with me, then I recommend two VMs. The first will be used for Semaphore itself, and will act as our Semaphore server. The second VM will be used as an example server we want to configure with Semaphore.

Now, let’s get started and dive in to Semaphore!

Setting up a Semaphore User

Note: Debian 12 was used to test all the commands used in the video and this article. If you use a different version of Debian or another distro entirely, these steps may not work the same way.

It’s better to have Semaphore run as its own user, rather than as root. To set that up, let’s create that user:

sudo adduser --system --group --home /home/semaphore semaphore

Building the Database

For this build, we’ll use MariaDB to provide our database layer. To install it, we’ll install the mariadb-server package:

sudo apt install mariadb-server

Next, we’ll run the mysql_secure_installation command. This command doesn’t actually make our database server secure though, but it does provide a bit of minimum security so at least that’s something.

sudo mysql_secure_installation

Now that we’ve done that, we’ll need to access the MariaDB shell in order to set up the database that we’ll use for Semaphore. One quick method of accessing the MariaDB shell is to run the following command:

sudo mariadb

Once inside the MariaDB shell, we can use it to create the semaphore_db database:

CREATE DATABASE semaphore_db;

Now that we’ve created the database, we’ll need to create a MariaDB user that Semaphore will use to access its database:

GRANT ALL PRIVILEGES ON semaphore_db.* TO semaphore_user@localhost IDENTIFIED BY 'randomly_generated_password_here';

Then, we’ll exit the MariaDB shell:

exit

Install Semaphore

To install Semaphore, first visit the project’s releases page. Once you find the latest version, copy the URL for its download link. We can use that URL on the server to download Semaphore:

Copy deb file address to create URL:

wget https://github.com/ansible-semaphore/semaphore/releases/download/v<VERSION>/semaphore_<VERSION>_linux_amd64.deb

Note: You must replace the above URL with a correct URL from the releases page.

Once downloaded, you can install Semaphore with apt:

sudo dpkg -i semaphore*.deb

Once installed, we’ll use the semaphore command to create Semaphore’s initial config file:

semaphore setup

To test Semaphore by running it in-place as our local user, we can run:

semaphore server --config config.json

Once the web server is running, we can access Semaphore by visiting http://ip-address:3000 in our browser.

Once we’ve verified the config file works, we can move it to a more appropriate place:

sudo mkdir /etc/semaphore
sudo mv config.json /etc/semaphore/
sudo chown -R semaphore:semaphore /etc/semaphore

Creating a Systemd service

Creating a Systemd service will faciliate setting up Semaphore to run each time the server itself restarts. To create a Systemd service file for Semaphore, we will run the following command:

sudo nano /etc/systemd/system/semaphore.service

Inside that file, we’ll add the following:

[Unit]
Description=Ansible Semaphore
Documentation=https://docs.ansible-semaphore.com/
Wants=network-online.target
After=network-online.target
ConditionPathExists=/usr/bin/semaphore
ConditionPathExists=/etc/semaphore/config.json

[Service]
ExecStart=/usr/bin/semaphore server --config /etc/semaphore/config.json
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=10s
User=semaphore
Group=semaphore

[Install]
WantedBy=multi-user.target

Next, we’ll reload Systemd:

sudo systemctl daemon-reload

And then we’ll enable Semaphore:

sudo systemctl enable semaphore.service

And to start Semaphore, we’ll run the following command:

sudo systemctl start semaphore.service

Playbook Repository

In order for us to continue with this example, you’ll need a Git repository with the following local.yml file inside:

---
- hosts: my_servers
  become: true
  tasks:
    - name: Print OS info
      ansible.builtin.package:
        name: apache2

Configure Semaphore

The following code is used to create an environment within Semaphore:

create environment

{
  "var_environment": "production"
}

In order to ensure Semaphore can run commands properly, we’ll need a line similar to the one below added to /etc/sudoers.d/semaphore on the target (the instance that our Semaphore server will be configuring). Be sure to replace semaphore in both the file name and inside the file to match the username of the user you intend to use with Semaphore.

semaphore ALL=(ALL) NOPASSWD: ALL

Other config files

The following format was used for the inventory file (be sure to change the information to match yours):

[all:vars]
ansible_ssh_common_args='-o StrictHostKeyChecking=no'

[web_servers]
172.234.197.30