SemaphoreUI: Command Automation UI for Ansible, Terraform, OpenTofu, Bash,Pulumi

Alot of Members in this community as Server and System Administrators, Who spend large amount of time automating servers, and building Automation scripts for their Infrastructures.

For those of You Using Nethserver, as well as managing Ansible, Terraform and other scopes of Serves, am happy to Announce you can use SempahoreUI in your Nethserver to help you with that.

The Documentation is on Github

Installing
Install our Repo through https://forge.genius.ke/)

Once Installed and Enabled, locate Semaphore from the UI

Once installed, Access the UI

Todo
Add Ldap Support
Add OIDC Support

For OpenID, i can see Authentik is Supported, IF someone can help test that, let me know i can implement and you test with our Authentik App in NS8

Alot more Options are supported as well. Configuration | Semaphore Docs (semaphoreui.com)

Let me know what more you might require, @giacomo and @dnutan i saw you were interested in AWX here

Hopefully this might help more

Edit: Video on the Solution It does Terraform now? (not just Ansible!) // Semaphore UI (youtube.com)

Thanks in Advance for testing and Feedback

4 Likes

Tnx for you work! - Is it stable or testing Repository?

It is testing repository, however, Most factors have been considered and upgrade after final release should be ok, I would suggest though wait till it reaches RC on the repo before putting to prodcution use. Am not sure how the ldap/OIDC impelemntations might affect things…

1 Like

I had saved this a while back, and today it came back to my attention.
dev-sec/ansible-collection-hardening: This Ansible collection provides battle tested hardening for Linux, SSH, nginx, MySQL (github.com)

i think it woud be a wonderful default addon into the SemaphoreUI

This is a really nice tool to manage ansible, please provide an upgrade if possible, they’re at 2.15 now, see Docker Container Configuration for version 2.15 - Semaphore UI

It would also be nice to have a volume to be able to save the files locally instead of online repos.

Ok, let work on the Updates…

EDIT:
could you help me Mapp out these for NS8?

1 Like

I have just Pushed an Update
Install with

add-module ghcr.io/geniusdynamics/semaphoreui:dev 1

Update with

api-cli run update-module --data '{"module_url":"ghcr.io//geniusdynamics/semaphoreui:dev","instances":["semaphoreui1"],"force":true}'

I have also Updated ReaDme as well as Added Additional Env variable si find might be useful

Make sure to test Backup Restore as Well.

1 Like

Thanks for the update, it’s working! :+1:

You could change the placeholders to show something helpful instead of “s”

The data isn’t shown correctly in the UI.
The variables in configure-module (ns8-semaphoreui/imageroot/actions/configure-module/10configure_environment_vars at main · geniusdynamics/ns8-semaphoreui · GitHub) need to be defined in get-configuration (ns8-semaphoreui/imageroot/actions/get-configuration/20read at main · geniusdynamics/ns8-semaphoreui · GitHub) too.

The backup didn’t work, maybe you need to add the right env file to ns8-semaphoreui/imageroot/bin/module-dump-state at main · geniusdynamics/ns8-semaphoreui · GitHub

Where can I find those settings?

Usually you need to set --network=slirp4netns:allow_host_loopback=true, see User domains | NS8 dev manual and for example ns8-guacamole/imageroot/systemd/user/guacamole.service at aa5d4216f0b2ba4cd6e14cc9725c5cf2079daab2 · mrmarkuz/ns8-guacamole · GitHub

The LDAP server is 10.0.2.2. Here is an example for setting the variables: ns8-guacamole/imageroot/actions/configure-module/10configure_environment_vars at aa5d4216f0b2ba4cd6e14cc9725c5cf2079daab2 · mrmarkuz/ns8-guacamole · GitHub

YEah, i saw and Noticed that when testing…

Also i saw a semaphore scripts repo, Please Do share More USeful Ones, We could Benefit Alot from them.

Kindly help me test backup restore, i beleive its fully implemented, so that if it works, we release this fully for UI installs and Updates

1 Like

I tested it, It didn’t work due to wrong mariadb credentials.

Seen the culprit, Kindly Update with the same commands above form dev branch

HAppy to Announce Backup and Restore has been implemented and tested to be working.

We have also released the App, and now installable and updateable through the Software Centre: Release 1.0.0 · geniusdynamics/ns8-semaphoreui

1 Like

trying to implement ldap support, getting error

Traceback (most recent call last):
  File "/home/semaphoreui3/.config/actions/configure-module/10configure_environment_vars", line 95, in <module>
    agent.bind_user_domains([])
  File "/usr/local/agent/pypkg/agent/__init__.py", line 604, in bind_user_domains
    response = agent.tasks.run(
               ^^^^^^^^^^^^^^^^
  File "/usr/local/agent/pypkg/agent/tasks/run.py", line 39, in run
    results = runp([taskrq], **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/agent/pypkg/agent/tasks/run.py", line 50, in runp
    return asyncio.run(_runp(tasks, **kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/usr/local/agent/pypkg/agent/tasks/run.py", line 120, in _runp
    return await asyncio.gather(*runners, return_exceptions=(len(tasks) > 1))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/agent/pypkg/agent/tasks/run.py", line 129, in _run_with_protocol
    return await run_apiclient(taskrq, **pconn)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/agent/pypkg/agent/tasks/apiclient.py", line 47, in run_apiclient
    taskctx['status_path'] = await _retry_request(_apost_task, taskrq, client=client, theaders=theaders, **kwargs)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/agent/pypkg/agent/tasks/apiclient.py", line 191, in _retry_request
    raise exhttp
  File "/usr/local/agent/pypkg/agent/tasks/apiclient.py", line 166, in _retry_request
    retval = await request_procedure(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/agent/pypkg/agent/tasks/apiclient.py", line 246, in _apost_task
    async with client.post(
  File "/usr/local/agent/pyenv/lib/python3.11/site-packages/aiohttp/client.py", line 1141, in __aenter__
    self._resp = await self._coro
                 ^^^^^^^^^^^^^^^^
  File "/usr/local/agent/pyenv/lib/python3.11/site-packages/aiohttp/client.py", line 643, in _request
    resp.raise_for_status()
  File "/usr/local/agent/pyenv/lib/python3.11/site-packages/aiohttp/client_reqrep.py", line 1005, in raise_for_status
    raise ClientResponseError(
aiohttp.client_exceptions.ClientResponseError: 403, message='Forbidden', url=URL('http://cluster-leader:9311/api/cluster/tasks')

I think the authorization is missing, see User domains | NS8 dev manual

In ns8-semaphoreui/build-images.sh at main · geniusdynamics/ns8-semaphoreui · GitHub you’d need:

org.nethserver.authorizations=cluster:accountconsumer

How Foolish of Me, I must have forgotten that Part About Ldap Implementation, whoosh, i hope i have not refactored too much to break what might actually have been working, let me fix this.

1 Like

HElp me checkout the current SempahoreUI version on dev branch.

I have implemented Ldap however i a unable to login when connected, we get the error

2025-07-15T13:49:18+03:00 [1:semaphoreui5:semaphoreui-app] time="2025-07-15T10:49:18Z" level=warning msg="LDAP Result Code 200 \"Network Error\": dial tcp: missing address"
2025-07-15T13:49:28+03:00 [1:semaphoreui5:semaphoreui-app] time="2025-07-15T10:49:28Z" level=warning msg="LDAP Result Code 200 \"Network Error\": dial tcp: missing address"

Without Choosing Ldap, should Work as well, however for some reasons, unless cache issues, i am getting invalid password.

below is runagent env output, weired

root@node:~# runagent -m semaphoreui env
runagent: [FATAL] Cannot find module semaphoreui in the local node
root@node:~#  runagent -m semaphoreui6 env
SHELL=/usr/bin/env
PATH=/home/semaphoreui6/.config/bin:/var/lib/nethserver/node/bin:/usr/local/agent/pyenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/agent/bin
HOME=/home/semaphoreui6
USER=semaphoreui6
LOGNAME=semaphoreui6
TERM=xterm
XDG_RUNTIME_DIR=/run/user/1008
LC_CTYPE=C.UTF-8
REGISTRY_AUTH_FILE=/etc/nethserver/registry.json
AGENT_BASEACTIONS_DIR=/usr/local/agent/actions
REDIS_ADDRESS=cluster-leader:6379
REDIS_REPLICA_ADDRESS=127.0.0.1:6379
REDIS_USER=module/semaphoreui6
REDIS_PASSWORD=effd9e4e-6474-4d83-8418-116dd4cb1e0a
PYTHONPATH=/home/semaphoreui6/.config/pypkg
IMAGE_DIGEST=sha256:9e7d8a87cbfce2d09e199651c2a3f4fc05e10fe5209c2b89b6a8a3240a525309
IMAGE_ID=e5e88dac772acffe2552589262bfbe9a5fca05deb06dd4947e6bffa2e46e75c5
IMAGE_REOPODIGEST=ghcr.io/geniusdynamics/semaphoreui@sha256:9e7d8a87cbfce2d09e199651c2a3f4fc05e10fe5209c2b89b6a8a3240a525309
IMAGE_URL=ghcr.io/geniusdynamics/semaphoreui:dev
LDAP_DOMAIN=
MARIADB_IMAGE=docker.io/mariadb:10.11.5
MODULE_ID=semaphoreui6
MODULE_UUID=b5529b33-ad13-4f57-8404-93d7ad6f8078
NODE_ID=1
SEMAPHORE_IMAGE=docker.io/semaphoreui/semaphore:v2.15.0
TCP_PORT=20003
TCP_PORTS=20003
TRAEFIK_HOST=app1.genius.mrmarkuz.ddnss.eu
TRAEFIK_HTTP2HTTPS=True
TRAEFIK_LETS_ENCRYPT=True
AGENT_INSTALL_DIR=/home/semaphoreui6/.config
AGENT_STATE_DIR=/home/semaphoreui6/.config/state
AGENT_ID=module/semaphoreui6

It’s now running here without ldap. The LDAP proxy is at 10.0.2.2 instead of
127.0.0.1.

What I did:

Comment MARIADB_AUTO_UPGRADE in database.env and check the passwords.

#MARIADB_AUTO_UPGRADE=1
MARIADB_DATABASE=semaphore
MARIADB_PASSWORD=Nethesis@1234
MARIADB_ROOT_PASSWORD=Nethesis@1234
MARIADB_USER=semaphore
SEMAPHORE_DB_HOST=mariadb-app

Check that passwords are the same in your used *.env files for mariadb-app and semaphoreui-app.

app-db.env:

SEMAPHORE_ACCESS_KEY_ENCRYPTION=+ouy6amBzvB248cvsEkWahg5Nbezxs+C0DnZw/1+egY=
SEMAPHORE_DB=semaphore
SEMAPHORE_DB_DIALECT=mysql
SEMAPHORE_DB_HOST=mariadb-app
SEMAPHORE_DB_PASS=Nethesis@1234
SEMAPHORE_DB_PORT=3306
SEMAPHORE_DB_USER=semaphore

MOst of the Issues, as well as volumes etc, have been resolved and fixed, the App should now be ain a stable State.

We have Implemented ldap, and hiddend it in the Advanced sections, however its its Functional yet, and choosing it might break, Unless you need to test and provide feedback.

We tried adding adn forcing 10.0.22 however for reasons best know to software, we still get 127.0.0 errors, and the login breaks when enabled…

Ill focus on the Other Apps and Tools, and get back to the ldap Issue on this One later…

1 Like