Semaphore
Ansible을 여태 Linux command로만 관리했기 때문에 어떤 사람이 어떤 명령어를 수행했는지는 전적으로 Linux OS의 이력을 통해서만 확인할 수 있었다.
이런 경우 여러 명이 Ansible을 사용할 경우 이슈가 생길 때 추적이 불가능하고 관리가 어렵게 된다.
이를 해결하기 위한 방법 중 하나로 웹 GUI 도구인 Semaphore를 사용해보았다.
Semaphore 설치
sepmaphore는 여러 설치 방법(snap, package manager, binary, docker)을 제공한다.
이 중에서 개인적으로 설치, 삭제가 쉬운 docker를 통한 설치로 진행하였다.
(단순 테스트 용이기 때문에 가이드 문서에서 제공하는 yaml파일을 그대로 사용)
Docker-compose 기동을 위한 사전 준비
# web에서 여러 파일 등을 다운받기 위해 설치
apt install curl
# docker 공식 GPG 키 추가
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# docker 공식 apt 저장소 추가
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt update
# docker 설치
install docker-ce docker-ce-cli containerd.io
# docker-compose 설치
curl -L "https://github.com/docker/compose/releases/download/v2.17.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod 751 /usr/local/bin/docker-compose
# docker, docker-compose 실행 테스트
root@ersia:~/ansible/windows_build_server# docker version
Client: Docker Engine - Community
Version: 25.0.3
...
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 25.0.3
...
docker-init:
Version: 0.19.0
GitCommit: de40ad0
root@ersia:~/ansible/windows_build_server# docker-compose version
Docker Compose version v2.17.3
root@ersia:~/ansible/windows_build_server# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2024-02-11 23:24:06 KST; 1min 38s ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
root@ersia:~/ansible/windows_build_server# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:4bd78111b6914a99dbc560e6a20eab57ff6655aea4a80c50b0c5491968cbc2e6
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
For more examples and ideas, visit:
https://docs.docker.com/get-started/
Docker-compose yaml 파일 생성 및 기동
# 디렉토리 생성
mkdir -p ~/ansible/semaphore
# docker-compose yaml 생성
cat <<EOT > ~/ansible/semaphore/semaphore.yml
services:
mysql:
restart: unless-stopped
image: mysql:8.0
hostname: mysql
volumes:
- semaphore-mysql:/var/lib/mysql
environment:
MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
MYSQL_DATABASE: semaphore
MYSQL_USER: semaphore
MYSQL_PASSWORD: semaphore
semaphore:
restart: unless-stopped
ports:
- 3000:3000
image: semaphoreui/semaphore:latest
environment:
SEMAPHORE_DB_USER: semaphore
SEMAPHORE_DB_PASS: semaphore
SEMAPHORE_DB_HOST: mysql # for postgres, change to: postgres
SEMAPHORE_DB_PORT: 3306 # change to 5432 for postgres
SEMAPHORE_DB_DIALECT: mysql # for postgres, change to: postgres
SEMAPHORE_DB: semaphore
SEMAPHORE_PLAYBOOK_PATH: /tmp/semaphore/
SEMAPHORE_ADMIN_PASSWORD: changeme
SEMAPHORE_ADMIN_NAME: admin
SEMAPHORE_ADMIN_EMAIL: admin@localhost
SEMAPHORE_ADMIN: admin
SEMAPHORE_ACCESS_KEY_ENCRYPTION: gs72mPntFATGJs9qK0pQ0rKtfidlexiMjYCH9gWKhTU=
SEMAPHORE_LDAP_ACTIVATED: 'no' # if you wish to use ldap, set to: 'yes'
SEMAPHORE_LDAP_HOST: dc01.local.example.com
SEMAPHORE_LDAP_PORT: '636'
SEMAPHORE_LDAP_NEEDTLS: 'yes'
SEMAPHORE_LDAP_DN_BIND: 'uid=bind_user,cn=users,cn=accounts,dc=local,dc=shiftsystems,dc=net'
SEMAPHORE_LDAP_PASSWORD: 'ldap_bind_account_password'
SEMAPHORE_LDAP_DN_SEARCH: 'dc=local,dc=example,dc=com'
SEMAPHORE_LDAP_SEARCH_FILTER: "(\u0026(uid=%s)(memberOf=cn=ipausers,cn=groups,cn=accounts,dc=local,dc=example,dc=com))"
depends_on:
- mysql # for postgres, change to: postgres
volumes:
semaphore-mysql: # to use postgres, switch to: semaphore-postgres
EOT
# docker-compose로 기동
cd ~/ansible/semaphore
docker-compose -f semaphore.yml up -d
# 기동 확인
root@ersia:~/ansible/semaphore# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d0f5fd228d1b semaphoreui/semaphore:latest "/sbin/tini -- /usr/…" 13 seconds ago Up 12 seconds 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp semaphore-semaphore-1
6686e3114c19 mysql:8.0 "docker-entrypoint.s…" 14 seconds ago Up 12 seconds 3306/tcp, 33060/tcp semaphore-mysql-1
출처 : https://docs.semui.co/administration-guide/installation#docker
Web 접속은 semaphore가 설치된 서버의 3000번 port이며, 초기 계정은 yaml에 정의한대로면 admin/changme 로 접속할 수 있다.
기존 ansible command에서는 디렉토리로 나누어서 별도의 작업을 분리했는데,
semaphore에서는 프로젝트라는 개념을 통해서 작업 분리를 지원한다.
Semaphore 간단한 실습
이전 Windows 빌드 서버 구성 테스트에 사용한 win_shell 모듈을 사용해 간단한 접속 테스트 ansible을 실습해보자.
Git Repositoy에 yml을 사용하기 위해 Azure Devops Repository를 사용하였다.
Azure Devops Repository 및 PAT 생성
생성한 Repository에 test.yml 파일을 commit한다.
기존에 테스트한 yml파일로 단순 접속 후 get-host powershell 명령을 수행해 결과를 출력한다.
# test.yml
- hosts: windows
vars:
ansible_connection: ssh
ansible_port: 22
ansible_shell_type: cmd
tasks:
- name: test powershell
win_shell: |
get-host
register: result_get_host
- name: display result_get_host
debug:
var: result_get_host
해당 Azure Devops Repository에 접근하기 위한 임시 PAT를 생성한다.
Semaphore 설정
Key Store 설정
1) Azure Devops Repository 접근용으로 생성한 PAT를 등록한다.
임의의 Key Name을 입력하고 Login with password 타입을 선택하고 Password란에 PAT를 입력하고 생성한다.
2) Windows 빌드 서버에서 사용할 Credential 정보도 등록한다.
Repository 설정
test.yml을 commit한 저장소의 Git URL과 Branch, 그리고 접근할 Key정보를 선택해준다.
여기서 주의해야할 점은 Azure Devops Repository에서 제공하는 자동 URL을 그대로 쓰면 안된다는 점이다.
- https://<--->@dev.azure.com/<organization>/<project>/_git/<repo>
그대로 HTTPS URL을 복사만 하면 위와 같은 형태로 제공하는데 @앞부분 제거하고 아래와 같은 URL형태로 수정해서 입력해야한다.
Environment 설정
실행에 필요한 vars를 여기서 설정해준다.
JSON 형태로만 입력가능하며, 굳이 설정할 vars가 없다면 {} 를 입력해 빈 JSON을 넣어준다.
Inventory 설정
ansible에서 사용했던 Inventory 설정을 그대로 입력해준다.
기존에 사용했던 INI(Static) 방식뿐아니라 YAML(Static YAML)도 지원하며 파일 경로를 제공해 파일로 읽어들일 수도 있다.
Semaphore를 통한 Ansible 수행
Task Templates 탭에서 새로운 Task를 생성할 수 있으며, Cron을 통해 스케줄링 작업을 수행할 수도 있다.
Templates는 3가지 타입을 제공하는데
- Task는 기존에 우리가 사용하던 임의의 작업이며
- Build는 빌드를 통해서 결과물(Artifacts)을 만들어내는데 사용하고
- Deploy는 생성된 결과물(Artifacts)을 특정 서버나 대상에 배포하는데 사용한다.
생성 후 좌측 Actions란의 RUN을 클릭하면 Ansible이 수행된다.
CLI에서 제공하는 debug와 dry run 설정도 제공한다.
여기서는 Repository와 연동했으므로 최초에는 git clone을 통해 Repository를 다운받고 명시한 test.yml을 읽어서 사용하게 된다.
(추가) SSH 접속 에러 발생 시
여기서 주의사항으로 아래와 같이 fingerprint 에러 메시지가 발생하는 경우가 있다.
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
ssh 접속이 처음이기 때문에 믿을 수 있는 host인지 확인하기 위해 발생하는 에러인데
- 해결책으로 작업 대상 서버로 ssh를 한번 접속 수행해서 known_hosts를 등록하거나
- ssh-keyscan -t ecdsa <host_name or IP>명령어를 통해 생성된 값을 ~/.ssh/known_hosts파일에 등록해주면 된다.
- 또는 시도해보진 않았지만 export ANSIBLE_HOST_KEY_CHECKING=False 환경 변수나 ansible.cfg의 host_key_checking = False 추가를 통해 회피할 수 있다고 한다.
현재 테스트 환경은 docker이므로 당연히 docker로 접속해서 위의 작업을 수행해 줘야 한다.
root@ersia:~/ansible/test# docker exec -it semaphore-semaphore-1 /bin/sh
~ $ ssh user@192.168.0.18
The authenticity of host '192.168.0.18 (192.168.0.18)' can't be established.
ED25519 key fingerprint is SHA256:z87Cy1zkm+4PTs+5b9YEyceYBxm6OB0nVcPXifGNzfI.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.0.18' (ED25519) to the list of known hosts.
user@192.168.0.18's password:
~ $ cat ~/.ssh/known_hosts
192.168.0.18 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIqQl1XP3gC0sbAWNEDED3VZCSZBDsRz5nbzz/RQI14y
실행 결과 및 이력 확인
아래와 같이 Ansible 수행 내역을 Web GUI에서 확인할 수 있다.
또한 이런 작업을 누가 언제 수행했는지 이력도 한눈에 확인할 수 있다.
참고자료
- Cannot clone git from Azure DevOps using PAT : https://stackoverflow.com/questions/53106546/cannot-clone-git-from-azure-devops-using-pat
- [Ansible] 자동으로 known_hosts에 등록하기 : https://iamjjanga.tistory.com/9
- [Ansible] playbook error : SSH password instand of ... 해결방법 : https://musclebear.tistory.com/166