Thursday, 28 May 2020

Install Ansible Semaphore on CentOS/Rocky Linux 8


In this article, you will learn how to install Ansible Semaphore on CentOS/Rocky Linux 8. We will also create our first project by using the Semaphore web interface.


This Article Provides:


What is Ansible? :

Ansible is a free and open source software provisioning, configuration management and application deployment tool. Ansible is developed by Red Hat and available in free and commercial editions.

Ansible is agent-less and it uses the SSH and Python to apply operating system configurations on Ansible managed nodes.

Ansible is also daemon-less and we do not required to configure a server for it. Instead, we need to configure a machine as Ansible Control Node, to store the Ansible software and inventory.

Ansible has a powerful command set that let the administrators to perform all server orchestration tasks from command line. But for the administrators who prefer Graphical user interface (GUI), we have some free web interfaces available such as AWX and Semaphore.

AWX is the free and open source upstream version of Ansible Tower and we have already explored how to install Ansible AWX on CentOS.


What is Ansible Semaphore? :

Ansible Semaphore is another open source alternative to Ansible Tower. Semaphore is available in both Community (free) and Enterprise (commercial) editions.

Semaphore is written in Golang (backend) and AngularJS (frontend) and distributed under MIT license. Semaphore supports LDAP authentication, REST API, Email and Telegram alerts.


Ansible Semaphore Prerequisites:

Ansible Semaphore has following three prerequisites.

  • MySQL >= 5.6.4/MariaDB >= 5.3
  • ansible in $PATH
  • git >= 2.x in $PATH


Environment Specification:

We are using a minimal CentOS 8 KVM virtual machine with following specifications.

  • CPU - 3.4 Ghz (2 cores)
  • Memory - 4 GB
  • Storage - 40 GB
  • Operating System - CentOS 8.1
  • Hostname –
  • IP Address - /24


Update CentOS 8 Software Packages:

Connect with as root user by using a SSH tool.

Use dnf command to update CentOS 8 software packages.

# dnf update -y
Last metadata expiration check: 0:00:16 ago on Wed 27 May 2020 12:20:39 AM PKT.
Dependencies resolved.
Nothing to do.

Our CentOS machine is already up-to-date. Therefore, dnf has nothing to update this time.


Install MariaDB Server on CentOS 8:

Ansible Semaphore requires a MySQL database to create its data repository. Therefore, we are installing MariaDB 10.3 server on CentOS 8 by using dnf command.

# dnf install -y mariadb-server

Enable and start mariadb.service.

# systemctl enable --now mariadb.service
Created symlink /etc/systemd/system/mysql.service â /usr/lib/systemd/system/mariadb.service.
Created symlink /etc/systemd/system/mysqld.service â /usr/lib/systemd/system/mariadb.service.
Created symlink /etc/systemd/system/ â /usr/lib/systemd/system/mariadb.service.

Configure MariaDB server and set root user password.

# mysql_secure_installation


In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] Y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

MariaDB 10.3 Server has been installed.


Install Ansible on CentOS 8:

There are different ways to install Ansible on CentOS 8, but we are installing it from EPEL yum repository.

Because Ansible is not available in default yum repositories. Therefore, we need to install EPEL (Extra Packages for Enterprise Linux) yum repository.

# dnf install -y epel-release

Build cache for EPEL yum repository.

# dnf makecache
CentOS-8 - AppStream                             12 kB/s | 4.3 kB     00:00
CentOS-8 - Base                                 1.2 kB/s | 3.9 kB     00:03
CentOS-8 - Extras                               4.2 kB/s | 1.5 kB     00:00
Extra Packages for Enterprise Linux Modular 8 -  25 kB/s | 118 kB     00:04
Extra Packages for Enterprise Linux 8 - x86_64  606 kB/s | 6.8 MB     00:11
Metadata cache created.

Now, we can install Ansible from EPEL yum repository.

# dnf install -y ansible

Verify that the ansible command is available in $PATH (as required by the Semaphore).

# ansible --version
ansible 2.9.9
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Nov 21 2019, 19:31:34) [GCC 8.3.1 20190507 (Red Hat 8.3.1-4)]

Ansible has been installed on CentOS 8.


Install Git on CentOS 8:

Ansible Semaphore also requires git.

git is available in default yum repository, therefore, we can easily install git on CentOS it using a dnf command.

# dnf install -y git

Verify that git is available in $PATH (as required by the Semaphore).

# git --version
git version 2.18.2

git has been installed on CentOS 8


Install Ansible Semaphore on CentOS 8:

Ansible Semaphore downloads are available at GitHub. Copy the URL of installation package according to your requirements and then use wget command to download it.

# wget
--2020-05-27 00:52:07--
Resolving (
Connecting to (||:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 4749991 (4.5M) [application/octet-stream]
Saving to: âsemaphore_2.5.1_linux_amd64.rpmâ

semaphore_2.5.1_lin 100%[===================>]   4.53M  1016KB/s    in 5.0s

2020-05-27 00:52:13 (921 KB/s) - âsemaphore_2.5.1_linux_amd64.rpmâ saved [4749991/4749991]

Now, install the Semaphore package by using dnf command.

# dnf install -y semaphore_2.5.1_linux_amd64.rpm

Verify the installation of Ansible Semaphore by checking its version.

# semaphore -version

Ansible Semaphore has been installed on CentOS 8.


Configure Ansible Semaphore on CentOS 8:

To configure Sempahore web UI, execute the following command and provide the required parameters as follows.

# semaphore -setup

 Hello! You will now be guided through a setup to:

 1. Set up configuration for a MySQL/MariaDB database
 2. Set up a path for your playbooks (auto-created)
 3. Run database Migrations
 4. Set up initial semaphore user & password

 > DB Hostname (default
 > DB User (default root): root
 > DB Password: 123
 > DB Name (default semaphore): semaphore
 > Playbook path (default /tmp/semaphore): /opt/semaphore
 > Web root URL (optional, example http://localhost:8010/): http://localhost:8010/
 > Enable email alerts (y/n, default n): n
 > Enable telegram alerts (y/n, default n): n
 > Enable LDAP authentication (y/n, default n): n

 Generated configuration:
        "mysql": {
                "host": "",
                "user": "root",
                "pass": "123",
                "name": "semaphore"
        "port": "",
        "tmp_path": "/opt/semaphore",
        "cookie_hash": "amackrz6Wq4yQCTPPZFJOdPn5ZXrlwW9q5nFDrdz7bU=",
        "cookie_encryption": "+kh28Q3TZw7TFMTUj7JSQPsJg6TiueaM3MlQ0Y/quZ4=",
        "email_sender": "",
        "email_host": "",
        "email_port": "",
        "web_host": "http://localhost:8010/",
        "ldap_binddn": "",
        "ldap_bindpassword": "",
        "ldap_server": "",
        "ldap_searchdn": "",
        "ldap_searchfilter": "",
        "ldap_mappings": {
                "dn": "",
                "mail": "",
                "uid": "",
                "cn": ""
        "telegram_chat": "",
        "telegram_token": "",
        "concurrency_mode": "",
        "max_parallel_tasks": 0,
        "email_alert": false,
        "telegram_alert": false,
        "ldap_enable": false,
        "ldap_needtls": false

 > Is this correct? (yes/no): yes
 > Config output directory (default /root): /etc/semaphore
 Running: mkdir -p /etc/semaphore..
 Configuration written to /etc/semaphore/config.json..
 Pinging db..

 Running DB Migrations..
Checking DB migrations
Creating migrations table
Executing migration v0.0.0 (at 2020-05-27 12:27:24.45158697 +0500 PKT m=+106.357625439)...
Executing migration v1.0.0 (at 2020-05-27 12:27:24.546940933 +0500 PKT m=+106.452979414)...
Executing migration v1.1.0 (at 2020-05-27 12:27:24.6319435 +0500 PKT m=+106.537981967)...
Executing migration v1.2.0 (at 2020-05-27 12:27:24.64419921 +0500 PKT m=+106.550237674)...
Executing migration v1.3.0 (at 2020-05-27 12:27:24.649860391 +0500 PKT m=+106.555898875)...
Executing migration v1.4.0 (at 2020-05-27 12:27:24.657201716 +0500 PKT m=+106.563240171)...
Executing migration v1.5.0 (at 2020-05-27 12:27:24.665959955 +0500 PKT m=+106.571998419)...
Executing migration v0.1.0 (at 2020-05-27 12:27:24.672315103 +0500 PKT m=+106.578353568)...
Executing migration v1.6.0 (at 2020-05-27 12:27:24.688564215 +0500 PKT m=+106.594602697)...
Executing migration v1.7.0 (at 2020-05-27 12:27:24.698647135 +0500 PKT m=+106.604685611)...
Executing migration v1.8.0 (at 2020-05-27 12:27:24.708400388 +0500 PKT m=+106.614438870)...
Executing migration v1.9.0 (at 2020-05-27 12:27:24.717120752 +0500 PKT m=+106.623159225)...
Executing migration v2.2.1 (at 2020-05-27 12:27:24.72921036 +0500 PKT m=+106.635248822)...
Executing migration v2.3.0 (at 2020-05-27 12:27:24.746290078 +0500 PKT m=+106.652328536)...
Executing migration v2.3.1 (at 2020-05-27 12:27:24.760803184 +0500 PKT m=+106.666841662)...
Executing migration v2.3.2 (at 2020-05-27 12:27:24.763959613 +0500 PKT m=+106.669998075)...
Executing migration v2.4.0 (at 2020-05-27 12:27:24.76662111 +0500 PKT m=+106.672659571)...
Executing migration v2.5.0 (at 2020-05-27 12:27:24.769857459 +0500 PKT m=+106.675895917)...
Migrations Finished

 > Username: centlinux
 > Email:
WARN[0126] sql: no rows in result set                    level=Warn
 > Your name: CentLinux
 > Password: 123

 You are all setup CentLinux!
 Re-launch this program pointing to the configuration file

./semaphore -config /etc/semaphore/config.json

 To run as daemon:

nohup ./semaphore -config /etc/semaphore/config.json &

 You can login with or centlinux.


Create Semaphore Service on CentOS 8:

To configure autostart of Ansible Semaphore, we have to create a systemd unit for Semaphore service.

# vi /usr/lib/systemd/system/semaphore.service

Add following directives in this file.

Description=Semaphore Ansible UI

ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/bin/semaphore -config /etc/semaphore/config.json


Enable and start semaphore.service.

# systemctl enable --now semaphore.service
Created symlink /etc/systemd/system/ â /usr/lib/systemd/system/semaphore.service.

Allow Semaphore default service port in CentOS firewall.

# firewall-cmd --permanent --add-port=3000/tcp
# firewall-cmd --reload

Semaphore uses plain text http protocol. Therefore, it is advisable to configure a https reverse proxy server by using Caddy or Nginx for enhanced security. We are not reproducing the steps here, but you can follow our previous articles to configure reverse proxy using Nginx or Caddy on CentOS.


Access Ansible Semaphore Web UI:

To access Semaphore web interface, browse URL in Google Chrome.


We are at the login page of the Ansible Semaphore. Login by using the user/password that we have created during configuration of Semaphore.


After successful login, we are now at the dashboard of Semaphore. Since, it is a new server and we didn't yet configure anything, therefore it is empty.

Click on + button after Projects to add a new project.


Provide a Project name and click on Create button.


We are again at the dashboard of the Semaphore. Click on the newly added project to open it.


Our Ansible Semaphore server has been installed on CentOS/Rocky Linux 8. Before using Semaphore web interface, you should refer to Semaphore Documentation to build the necessary understanding about its usage.

If you find this article useful? Don't you mind support us by Buy Me A Coffee

No comments:

Post a Comment

© 2022 CentLinux. All Rights Reserved.