This mini How-To guide describes how to install Semaphore UI 2.8.75 in addition to Ansible 8.5 on Linux Debian 12 (Bookworm). Semaphore provides a modern and responsive webUI for running Ansible playbooks as an alternative to Ansible AWX (Tower) and the new Automation Platform. Semaphore is an open-source project written in GoLang and easy to use, install & to maintain. MySQL/MariaDB, PostgreSQL and BoltDB are supported as backend DBs. Within this HowTo MariaDB is used. Please also see the official docs here.
Features:
* Build, deploy & rollback
* Group playbooks to projects
* Manage environments, inventories, repositories and access keys
* Run playbooks from the browser
* Responsive UI allows the use of Semaphore on mobile devices
* Run playbooks by schedule
* View detailed logs of any playbook runs, at any time
* Delegate other users the running of playbooks
* Get notifications about playbook runs
Prerequisites: In order to install Ansible Semaphore on a Debian based system, additional packages need to be installed. This also includes the MardiaDB server. Next to this, a dedicated semaphore user is created and the needed systemd units are being enabled. apt-get install useradd python3-pip wget git sudo nginx mariadb-server useradd -m semaphore systemctl enable mariadb systemctl start mariadb systemctl enable nginx systemctl start nginx /usr/bin/mysql_secure_installation
Semaphore Versions:
Semaphore provides ready to use packages for Debian/Ubuntu and CentOS/RedHat based Linux distributions for AMD64 and ARM64 hardware architecture. Please select the corresponding version for your hardware architecture to proceed.
# Debian/Ubuntu ARM64
wget https://github.com/ansible-semaphore/semaphore/releases/download/v2.8.75/semaphore_2.8.75_linux_arm64.deb
# Debian/Ubuntu AMD64
wget https://github.com/ansible-semaphore/semaphore/releases/download/v2.8.75/semaphore_2.8.75_linux_amd64.deb
# CentOS/RedHat ARM64
wget https://github.com/ansible-semaphore/semaphore/releases/download/v2.8.75/semaphore_2.8.75_linux_arm64.rpm
# CentOS/RedHat AMD64
wget https://github.com/ansible-semaphore/semaphore/releases/download/v2.8.75/semaphore_2.8.75_linux_amd64.rpm
Installation:
Afterwards, the installation procedure can start. Therefore, this is done by the newly created user semaphore.
su --login semaphoreA requirements.txt file for additional PiP modules will be created in /home/semaphore/requirements.txt containing the following modules:
ansible netaddr jmespath pywinrm passlib requests dockerA requirements.yaml file for additional Ansible modules will be created in /home/semaphore/requirements.yaml containing the following modules:
--- collections: - 'community.general' - 'ansible.posix' - 'community.mysql' - 'community.crypto'In order to install the modules for PiP and Ansible, the following commands are executed. Afterwards, the semaphore package can be installed.
python3 -m pip install --user --upgrade -r /home/semaphore/requirements.txt ansible-galaxy collection install --upgrade -r /home/semaphore/requirements.yaml ansible-galaxy role install --force -r /home/semaphore/requirements.yaml dpkg -i semaphore*.debSemaphore setup can be executed and configured to your needs. The created config.json must be copied to /etc/semaphore after creation to match the systemd unit file.
semaphore setup sudo mkdir /etc/semaphore sudo chown semaphore:semaphore /etc/semaphore sudo cp /home/semaphore/config.json /etc/semaphoreNow, the semaphore systemd unit file can be created in /etc/systemd/system/semaphore.service with the following content:
[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] User=semaphore Group=semaphore ExecStart=/usr/bin/semaphore service --config /etc/semaphore/config.json ExecReload=/bin/kill -HUP $MAINPID Restart=always RestartSec=10s Environment=LANG="en_US.UTF-8" Environment=LC_ALL="en_US.UTF-8" [Install] WantedBy=multi-user.targetThe newly created service should be started
systemctl daemon-reload systemctl enable semaphore systemctl start semaphoreValidate that the service is up and running.
systemctl status semaphore.service ● semaphore.service - Ansible Semaphore Loaded: loaded (/etc/systemd/system/semaphore.service; enabled; preset: enabled) Active: active (running) since Sat 2023-11-04 17:45:49 EDT; 18min ago Docs: https://docs.ansible-semaphore.com/ Main PID: 4521 (semaphore) Tasks: 5 (limit: 6991) Memory: 38.9M CPU: 515ms CGroup: /system.slice/semaphore.service └─4521 /usr/bin/semaphore service --config /etc/semaphore/config.json Nov 04 17:45:49 ansible-semaphore-srv01 systemd[1]: Started semaphore.service - Ansible Semaphore. Nov 04 17:45:49 ansible-semaphore-srv01 semaphore[4521]: MySQL semaphore@127.0.0.1:3306 semaphore Nov 04 17:45:49 ansible-semaphore-srv01 semaphore[4521]: Tmp Path (projects home) /tmp/semaphore Nov 04 17:45:49 ansible-semaphore-srv01 semaphore[4521]: Semaphore v2.8.75 Nov 04 17:45:49 ansible-semaphore-srv01 semaphore[4521]: Interface Nov 04 17:45:49 ansible-semaphore-srv01 semaphore[4521]: Port :3000 Nov 04 17:45:49 ansible-semaphore-srv01 semaphore[4521]: Server is runningSemaphore is now running on port tcp/3000. Keep in mind, that this in an unencrypted connection endpoint which should be secured by a reverse-proxy.
Security
Semaphore doesn’t provide transport encryption by default. Therefore, a reverse-proxy should be used for securing the webUI and API. Attached, you can find the next steps to create a self-signed certificate and a reverse-proxy host configuration for nginx. If needed, self-signed certificates and a DH key will be generated. Other certificates can of course also be used (e.g. Let’s encrypt, etc.). cd /etc/nginx/pki openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout semaphore.example.com.crt.key -out semaphore.example.com.crt openssl dhparam -out dhparam.pem 4096
An example vhost configuration for nginx as a reverse-proxy could look like the following one, serving as semaphore.example.com:
server { listen 443 ssl; server_name semaphore.example.com; # add Strict-Transport-Security to prevent man in the middle attacks add_header Strict-Transport-Security "max-age=31536000" always; # SSL ssl_certificate /etc/nginx/pki/semaphore.example.com.crt; ssl_certificate_key /etc/nginx/pki/semaphore.example.com.key; # Recommendations from # https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_dhparam /etc/nginx/dhparam.pem; ssl_protocols TLSv1.3; ssl_ciphers EECDH+AESGCM:EDH+AESGCM; ssl_ecdh_curve secp384r1; ssl_session_timeout 10m; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # required to avoid HTTP 411: see Issue #1486 # (https://github.com/docker/docker/issues/1486) chunked_transfer_encoding on; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; proxy_request_buffering off; } location /api/ws { proxy_pass http://127.0.0.1:3000/api/ws; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Origin ""; } }API:
Semaphore provides a great API for further automation which is described in detail. The details can be found here.
Resources:
Vagrant: gyptazy/debian12-semaphore-webui-ansible-server-arm64
Docker: semaphoreui/semaphore
Snap: snapcraft.io/semaphore