Для своего времени Semaphore был неплох.
Однако, Semaphore больше не поддерживается и сейчас стал бесплатным upstream Ansible Tower - AWX. Установить его можно вот так: Установка AWX на Ubuntu или в кластер Kubernetes
По сути Semaphore - бледное подобие Ansible Tower.
https://github.com/ansible-semaphore/semaphore/wiki/Installation
sudo apt-get update && sudo apt-get -y upgrade sudo apt-get install -y software-properties-common sudo apt-add-repository -y universe sudo add-apt-repository -y ppa:ansible/ansible sudo apt-get install -y git ansible mysql-server nginx wget https://github.com/ansible-semaphore/semaphore/releases/download/v2.5.1/semaphore_2.5.1_linux_amd64.deb sudo dpkg -i ./semaphore_2.5.1_linux_amd64.deb
Создаем базу данных:
sudo mysql mysql> CREATE DATABASE semaphore; Query OK, 1 row affected (0.04 sec) mysql> CREATE USER 'semaphore'@'localhost' IDENTIFIED BY 'superpassword'; Query OK, 0 rows affected (0.06 sec) mysql> GRANT ALL PRIVILEGES ON semaphore.* TO 'semaphore'@'localhost'; Query OK, 0 rows affected (0.01 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.03 sec) mysql> exit
Создаем файл конфигурации:
sudo semaphore -setup
При первичной настройке не стоит включать LDAP-аутентификацию, потому что при ее включении скрипт не предлагает добавить локального пользователя.
Включить LDAP можно и в дальнейшем, просто добавив нужные параметры в файл конфигурации.
Для аутентификации пользователей из AD нужно включить LDAP. Эта часть конфига должна выглядеть так:
"ldap_binddn": "semaphore", "ldap_bindpassword": "semaphore_password", "ldap_server": "dc.local:389", "ldap_searchdn": "OU=Users,DC=domain,DC=local", "ldap_searchfilter": "(sAMAccountName=%s)", "ldap_mappings": { "dn": "dn", "mail": "mail", "uid": "sAMAccountName", "cn": "cn" }, "ldap_enable": true, "ldap_needtls": false
С начала я пытался сконфигурировать параметр “ldap_binddn” в виде CN=semaphore,OU=Users,DC=domain,DC=local, однако это приводило к ошибкам вида:
time="2018-09-26T08:48:22Z" level=info msg="LDAP Result Code 49 "Invalid Credentials": 80090308: LdapErr: DSID-0C09042A, comment: AcceptSecurityContext error, data 52e, v3839"
в таком случае, стоит попробывать в качестве “ldap_binddn” использовать просто логин (sAMAccountname или UserPrincipalName а не distinguished name) пользователя, который будет обращаться к LDAP.
Также, вместо uid нужно использовать sAMAccountName. В противном случае можно увидеть такую ошибку:
time="2018-09-26T13:45:35Z" level=info msg="User does not exist or too many entries returned"
Копируем конфиг semaphore в /etc/ansible/:
cp ./config.json /etc/ansible/semaphore_config.json
И конфигурируем сервис: /etc/systemd/system/semaphore.service
[Unit] Description=Ansible Semaphore After=syslog.service Before=nginx.service Requires=network.target [Service] Type=forking EnvironmentFile=-/etc/default/ansible-semaphore ExecStart=/bin/sh -c "/usr/bin/semaphore -config ${SEMAPHORE_CONFIG} >> ${SEMAPHORE_LOGS} 2>&1 &" Restart=always RestartSec=10s [Install] WantedBy=multi-user.target
/etc/default/ansible-semaphore
#Ansible Semaphore Defaults SEMAPHORE_CONFIG=/etc/ansible/semaphore_config.json SEMAPHORE_LOGS=/var/log/semaphore.log
Включаем и запускаем сервис:
systemctl enable semaphore.service service semaphore start
/etc/nginx/nginx.conf
user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 1024; use epoll; multi_accept on; } http { tcp_nodelay on; keepalive_timeout 600; types_hash_max_size 2048; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
/etc/nginx/sites-enabled/default
server { listen 80; root /var/www/; #Enable access to acme files location ~ /\.well-known/acme-challenge/ { allow all; access_log off; log_not_found off; } return 301 https://$host$request_uri; } upstream semaphore { server 127.0.0.1:3000; } server { listen 443 ssl http2; server_name server.domain.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/letsencrypt/live/server.domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/server.domain.com/privkey.pem; # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_protocols TLSv1.1 TLSv1.2; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; # disable any limits to avoid HTTP 413 for large image uploads client_max_body_size 0; # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) chunked_transfer_encoding on; location / { proxy_pass http://semaphore/; 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://semaphore/api/ws; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Origin ""; } }