용어

본격적으로 들어가기 전에, 짚고 넘어갈 만한 용어가 몇 가지 있습니다.

  • Ansible Collection — 롤, 모듈, 플러그인을 담을 수 있는 자동화 묶음입니다. 대부분의 모듈은 Python(리눅스 서버와 네트워크 장비용) 또는 PowerShell(윈도우용)로 작성됩니다.
  • Ansible Role — 미리 정의된 작업 모음으로, 변수, 템플릿, 파일, 핸들러를 포함할 수 있습니다. 롤은 컬렉션 안에 포함될 수도 있고 독립적으로 존재할 수도 있습니다.
  • Config as Code (CaC) — 설정을 코드로 정의하고 관리하는 방식으로, 수동 설정 대신 자동화와 재사용, 버전 관리를 가능하게 합니다.

소개

저는 Kristian이고, Semaphore UI 설치 환경을 코드로 관리하는 Ansible Collection인 ebdruplab.semaphoreui의 작성자입니다.

어떻게 시작되었나

이 프로젝트는 Ansible을 더 깊이 이해하기 위한 방법으로 시작되었습니다. 그때까지 저는 주로 다른 사람이 만든 컬렉션과 롤을 가져다 쓰거나, ansible.builtin.cmd와 register, Jinja2 템플릿을 엮어서 일을 처리하곤 했습니다.

호기심에 처음 불이 붙은 건 다소 생소한 네트워크 장비를 자동화해야 했던 때였습니다. 구체적으로는 데이터베이스의 시리얼 번호가 올바르게 설정되었는지 검증하는 일이었죠. 그 프로젝트가 끝난 뒤에는 늘 하던 PowerShell 작업으로 돌아갔지만, 새로운 컨설팅 업무가 저를 다시 Ansible로 이끌었습니다. 그 업무에는 패치 관리부터 Ansible 노드 구축 지원, 모범 사례 자문, Red Hat Single Sign-On 설치용 콘텐츠 제작까지 모든 것이 포함되어 있었습니다.

Ansible과 함께한 지 7년이 되었습니다. CLI로 시작해 Ansible Automation Platform(AAP) v2로 넘어갔다가 결국 그것에서 멀어졌습니다. 왜냐고요? AAP는 강력하지만 무거운 제품이고, 대기업을 위해 만들어졌습니다. OpenShift 밖에서 구축하기가 고통스럽고, 라이선스 비용도 그에 걸맞습니다.

왜 Semaphore UI인가

Semaphore UI는 단순함으로 저를 사로잡았습니다. 패키지 하나, 서버 한 대(엔터프라이즈 규모가 필요하지 않다면)면 충분합니다. 열 개의 포트로 열 가지 방식으로 통신하는 여섯 대의 VM은 필요 없습니다.

물론 AAP의 execution environments는 우아합니다. 하지만 그것을 유지 관리하는 일은 또 다른 이야기입니다. Semaphore UI는 패치도 쉽고 운영도 쉬우며, 반응이 빠르고 직관적인 인터페이스를 제공합니다. 고급 기능이 일부 빠져 있는 것은 사실이지만, 제 사용 사례에서는 기능과 비용의 균형이 딱 알맞습니다.

Semaphore는 홈랩 커뮤니티에서 처음 들었고, 직접 써보기 전까지는 별로 신경 쓰지 않았습니다. 그러다 Ansible Galaxy를 확인해 보니 관련 컬렉션이 없었고, 결정은 쉬웠습니다. 이것을 제 학습 프로젝트로 삼기로 한 것이죠. 코드를 전부 제가 직접 썼냐고요? 아닙니다. 처음부터 끝까지 AI의 도움을 받았습니다. 하지만 프로젝트는 조금씩 형태를 갖춰 갔습니다. 여기서 30분, 저기서 한 시간. 얼마 지나지 않아 Semaphore API 전체를 Python 모듈로 옮겨 놓았습니다.

무엇을 할 수 있나

ebdruplab.semaphoreui로 무엇을 할 수 있는지는 Ansible Galaxy에 예제가 있습니다. 여기서도 몇 가지 소개합니다.

프로젝트 생성과 관리 — Semaphore 프로젝트를 코드로 정의하고 반복 가능하게 배포합니다

- name: Create project with token and custom settings
  ebdruplab.semaphoreui.project_create:
    host: http://localhost
    port: 3000
    api_token: "{{ semaphore_token }}"
    name: "My Project"
    alert: true
    alert_chat: "#alerts"
    max_parallel_tasks: 5
    demo: false

인벤토리 구성 — 정적·동적 인벤토리를 프로그래밍 방식으로 관리합니다

- name: Create static inventory
  ebdruplab.semaphoreui.project_inventory_create:
    host: http://localhost
    port: 3000
    session_cookie: "{{ login_result.session_cookie }}"
    project_id: 1
    inventory:
      name: "Local Static Inventory"
      type: "static"
      inventory: "localhost ansible_connection=local"
      ssh_key_id: 42
      become_key_id: 7

작업 템플릿 설정 — UI를 건드리지 않고 템플릿을 만들고 업데이트합니다

- name: Create template with UI-style override flags
  ebdruplab.semaphoreui.project_template_create:
    host: http://localhost
    port: 3000
    api_token: "{{ semaphore_token }}"
    project_id: 1
    template:
      name: "ff"
      playbook: "f"
      repository_id: 1
      inventory_id: 1
      environment_id: 1
      type: ""
      arguments: "[]"
      task_params:
        allow_override_tags: true
        allow_override_limit: true
        tags: ["t"]
        limit: ["t"]

사용자 관리 — 사용자 생성과 프로젝트 배정을 자동화합니다

- name: Create a new user
  ebdruplab.semaphoreui.user_create:
    host: http://localhost
    port: 3000
    session_cookie: "{{ login_result.session_cookie }}"
    name: "Jane Smith"
    username: "jsmith"
    email: "[email protected]"
    password: "supersecure123"
    admin: true
    alert: true

기존 프로젝트 백업 — 운영 중인 프로젝트를 YAML로 내보내 버전 관리에 넣습니다

- hosts: localhost
  gather_facts: false
  roles:
    - role: ebdruplab.semaphoreui.project_backup
      vars:
        project_backup_semaphore_host: "https://semaphore.example.com"
        project_backup_semaphore_api_token: "{{ lookup('env', 'SEMAPHORE_TOKEN') }}"
        project_backup_project_name: "My Project"

복원 또는 마이그레이션 — YAML 정의로부터 프로젝트 전체 구성을 몇 초 만에 다시 배포합니다.

- hosts: localhost
  gather_facts: false
  vars_files:
    - vars/project.yml
  roles:
    - role: ebdruplab.semaphoreui.project_deploy

Config as Code — ebdruplab.project_deploy

모듈 하나가 둘이 되었고, 둘이 열이 되었습니다. 결국 컬렉션은 프로젝트, 템플릿, 인벤토리를 비롯한 여러 영역을 아우르는 92개 모듈에 이르렀습니다.

어느 시점에 한 사용자가 이 모든 모듈을 이어 줄 접착제 역할의 롤을 요청했습니다. 그렇게 만들어진 롤이 ebdruplab.project_deploy입니다. Semaphore UI 프로젝트가 어떤 모습이어야 하는지 정확히 정의한 다음, Ansible을 통해 선언적으로 생성할 수 있습니다.

최소한의 프로젝트 정의는 다음과 같습니다.

project_deploy_config:
  project:
    name: "My Project"
    alert: false
    alert_chat: ""
    max_parallel_tasks: 0
    demo: false

  users_access:
    - username: "admin"
      role: "Owner"

  keys:
    repo_login:
      name: "Git Login"
      type: login_password
      login_password:
        login: "git-user"
        password: "{{ vault_git_password }}"

  repositories:
    - name: "Example Repo"
      git_url: "https://github.com/example/repo.git"
      git_branch: "main"
      key_name: "Git Login"

  views:
    main:
      title: "Main"
      position: 0

  inventories:
    local_inventory:
      name: "Local Inventory"
      type: "static"
      inventory: "localhost ansible_connection=local"

  environments:
    default_env:
      name: "Default Environment"
      env:
        APP_ENV: "prod"

  templates:
    deploy_job:
      name: "Deploy"
      type: "job"
      repository_name: "Example Repo"
      inventory_name: "Local Inventory"
      environment_name: "Default Environment"
      view_title: "Main"
      playbook: "playbooks/site.yml"

  schedules: {}
  integrations: {}

문서는 Ansible Galaxy에서 볼 수 있고, GitHub 저장소의 project_deployproject_backup 안에는 시작에 도움이 되는 examples/test/ 폴더가 들어 있습니다.

Config as Code 변환기 — ebdruplab.project_backup

project_deploy를 만든 뒤 또 다른 생각이 들었습니다. 코드로 만들어지지 않은 기존 Semaphore 프로젝트는 어떻게 할 것인가? 바로 그 문제를 풀기 위해 ebdruplab.project_backup을 만들었습니다. 기존 프로젝트를 가져와 project_deploy와 호환되는 YAML 변수 파일로 내보내 줍니다. 이로써 순환이 완성됩니다. 처음부터 시작하든 기존 환경을 옮기든, 모든 것을 버전 관리 아래 둘 수 있습니다.

시작하기

명령 하나로 컬렉션을 설치할 수 있습니다.

ansible-galaxy collection install ebdruplab.semaphoreui

그다음 Ansible Galaxy의 전체 문서를 확인하거나 GitHub의 예제를 살펴보세요.

오류를 발견했거나 아이디어가 있다면 주저하지 말고 issue/feature/question을 남겨 주세요 — https://github.com/Ebdruplab/ansible-collection_ebdruplab/issues. 그 밖에는 보통 Semaphore UI Discord 서버 근처에 있습니다 — TrimmerWolf7.

이 컬렉션이 도움이 되기를 바랍니다.

You might also like