Ansible 역할 및 종속성 구성을 위한 필수 모범 사례

재사용, 명확한 변수, 신뢰할 수 있는 종속성, 그리고 실제 프로젝트에서의 유지보수 용이성을 위해 Ansible 역할을 구성하세요.

Ansible 역할 및 종속성 구성을 위한 필수 모범 사례

Ansible 역할은 자동화를 재사용 가능하게 유지하지만, 숨겨진 변수와 역할 종속성의 얽힘으로 변할 수도 있습니다. 플레이북을 읽기 어렵거나 모든 배포에 부족한 지식 체크리스트가 필요하다면, 역할 구조에 주의가 필요할 수 있습니다.

좋은 역할 구성은 각 역할을 더 쉽게 테스트하고, 재사용하며, 디버깅할 수 있게 만듭니다. 목표는 간단합니다: 팀원이 역할을 열어서 무엇을 담당하는지 이해하고, 재정의할 수 있는 변수를 확인하며, 어떤 다른 역할에 의존하는지 알 수 있어야 합니다.

Ansible 역할 이해하기

Ansible 역할은 독립적으로 재사용 가능하도록 설계된 변수, 작업, 파일, 템플릿 및 핸들러의 사전 정의된 모음입니다. 역할은 복잡한 구성을 논리적 단위로 추상화하여 플레이북을 더 깔끔하고 이해하기 쉽게 만듭니다. 일반적인 역할 디렉터리 구조는 다음과 같습니다:

my_role/
├── defaults/
│   └── main.yml
├── files/
├── handlers/
│   └── main.yml
├── meta/
│   └── main.yml
├── tasks/
│   └── main.yml
├── templates/
├── vars/
│   └── main.yml
└── README.md
  • defaults/main.yml: 역할의 기본 변수입니다.
  • files/: 관리 노드에 복사할 수 있는 정적 파일입니다.
  • handlers/main.yml: 핸들러는 다른 작업에 의해 트리거되고 플레이 끝에 한 번만 실행되는 작업입니다.
  • meta/main.yml: 작성자, 설명 및 종속성을 포함한 역할에 대한 메타데이터를 포함합니다.
  • tasks/main.yml: 역할이 실행할 주요 작업 목록입니다.
  • templates/: 관리 노드에 배포할 수 있는 Jinja2 템플릿입니다.
  • vars/main.yml: 역할별 변수(기본값보다 우선순위가 높음).
  • README.md: 역할에 대한 문서입니다.

역할 구성 및 재사용성을 위한 모범 사례

효과적인 역할 구성은 유지보수성과 확장성에 매우 중요합니다. 다음 모범 사례를 준수하면 역할을 쉽게 이해하고, 사용하고, 확장할 수 있습니다.

1. 단일 책임 원칙

각 역할은 이상적으로 단일하고 잘 정의된 기능을 수행해야 합니다. 예를 들어, Nginx를 설치하고 구성하는 역할은 PostgreSQL 데이터베이스를 설정하는 역할을 동시에 수행해서는 안 됩니다. 이 원칙은 역할을:

  • 이해하기 쉽게 만듭니다: 개발자가 역할의 목적을 빠르게 파악할 수 있습니다.
  • 더 재사용 가능하게 만듭니다: 집중된 역할은 더 많은 컨텍스트에서 적용될 수 있습니다.
  • 테스트하기 간단하게 만듭니다: 기능을 분리하면 테스트가 더 간단해집니다.
  • 충돌 가능성을 줄입니다: 변수나 작업이 다른 역할과 간섭할 가능성을 줄입니다.

2. 일관된 명명 규칙

역할에 대해 명확하고 설명적이며 일관된 명명 규칙을 사용하세요. 이는 역할 디렉터리 이름과 역할 내 파일 이름 모두에 적용됩니다. 일반적인 규칙은 소문자 단어를 밑줄로 구분하는 것입니다.

예시:

  • nginx
  • apache2
  • mysql_server
  • common_utilities

너무 일반적인 이름이나 너무 길고 다루기 힘든 이름은 피하세요.

3. 기본값과 변수를 효과적으로 활용하기

재정의될 가능성이 있는 변수에는 defaults/main.yml을 사용하세요. 이는 사용자가 역할의 핵심 작업을 수정하지 않고도 쉽게 사용자 정의할 수 있는 기본 구성을 제공합니다. vars/main.yml에 정의된 변수는 변경 가능성이 낮거나 역할의 내부 로직에 중요한 값에 사용해야 합니다. Ansible 변수 우선순위는 최종적으로 어떤 값이 사용되는지 결정한다는 점을 기억하세요. 기본값은 가장 낮은 우선순위를 가지므로 사용자 정의 변수가 쉽게 재정의할 수 있습니다.

예시 (nginx 역할의 defaults/main.yml):

nginx_package_name: nginx
nginx_service_name: nginx
nginx_port: 80
nginx_conf_dir: /etc/nginx

4. 포괄적인 문서 작성 (README.md)

모든 역할은 다음을 명확히 설명하는 README.md 파일을 가져야 합니다:

  • 역할의 목적.
  • 종속성(있는 경우).
  • 사용 방법(예: 플레이북 예제 스니펫).
  • 사용 가능한 변수와 기본값.
  • 대상 호스트에 필요한 모든 필수 조건.

좋은 문서는 역할을 다른 사람(그리고 미래의 자신!)이 접근하고 유지보수할 수 있게 만드는 데 중요합니다.

meta/main.yml로 역할 종속성 관리하기

자동화 복잡성이 증가함에 따라 역할은 종종 다른 역할에 의존합니다. 예를 들어, 웹 애플리케이션 역할은 데이터베이스 역할과 웹 서버 역할에 의존할 수 있습니다. Ansible은 역할 내 meta/main.yml 파일을 사용하여 이러한 종속성을 관리하는 강력한 메커니즘을 제공합니다.

meta/main.yml 구조

meta/main.yml 파일은 역할에 대한 메타데이터를 포함합니다. 종속성 관리를 위한 주요 섹션은 dependencies 키입니다.

web_app 역할의 예시 meta/main.yml:

---
galaxy_info:
  author: Your Name
  description: Installs and configures a web application.
  company: Your Company
  license: MIT
  min_ansible_version: '2.9'

  platforms:
    - name: Ubuntu
      versions:
        - focal
        - bionic
    - name: Debian
      versions:
        - buster

  galaxy_tags:
    - web
    - application
    - python

dependencies:
  # 로컬 종속성 (동일한 저장소의 역할)
  - role: common_setup

  # Galaxy 관리 종속성
  - role: geerlingguy.nginx
    vars:
      nginx_port: 8080

외부 역할은 meta/main.yml 내부가 아닌 requirements.yml에 고정하세요:

---
roles:
  - name: geerlingguy.postgresql
    version: 3.5.0

종속성 유형

  1. 로컬 역할: 동일한 Ansible 프로젝트 저장소 또는 정의된 roles_path 내에 위치한 역할입니다. 역할 이름으로 간단히 지정됩니다.

    dependencies:
      - role: common_setup
    
  2. Galaxy 역할: Ansible Galaxy에서 다운로드한 역할입니다. 네임스페이스를 포함한 역할 이름으로 지정됩니다(예: geerlingguy.nginx).

    dependencies:
      - role: geerlingguy.nginx
    
  3. 종속성에 변수 전달하기: meta/main.yml 파일 내에서 종속 역할에 직접 변수를 전달할 수 있습니다. 이는 종속 역할 자체를 수정하지 않고 종속성 구성을 사용자 정의하는 데 매우 강력합니다.

    dependencies:
      - role: geerlingguy.nginx
        vars:
          nginx_port: 8080
          nginx_server_root: /var/www/my_app/public
    
  4. 버전 고정: 설치를 반복 가능하게 하려면 requirements.yml에 Galaxy 역할을 고정하세요. meta/main.yml은 런타임 시 역할 종속성을 설명하고, requirements.yml은 다운로드할 외부 역할을 설명합니다.

    roles:
      - name: geerlingguy.postgresql
        version: 3.5.0
    

종속성 해결 방법

Ansible이 meta/main.yml에 정의된 종속성이 있는 역할을 사용하는 플레이북을 실행할 때, 이러한 종속성을 재귀적으로 처리합니다. 즉, role_Arole_B에 의존하고 role_Brole_C에 의존하는 경우, Ansible은 role_Crole_B보다 먼저 적용되고, role_Brole_A보다 먼저 적용되도록 합니다. 종속 역할의 실행 순서는 일반적으로 가장 "깊은" 종속성에서 플레이북에서 직접 호출된 역할까지입니다.

종속성 관리 팁

  • 종속성 집중 유지: 역할 자체와 마찬가지로 종속성도 단일 책임을 가져야 합니다.
  • 변수 사용 문서화: 종속 역할에서 재정의할 수 있는 변수와 그 목적을 명확히 문서화하세요.
  • 버전 고정 사용: 중요한 프로덕션 환경에서는 안정성을 보장하고 예기치 않은 변경을 방지하기 위해 종속성을 특정 버전이나 커밋 해시로 고정하는 것을 고려하세요.
  • 순환 종속성 피하기: 역할 종속성이 루프를 형성하지 않도록 하세요(예: 역할 A가 역할 B에 의존하고 역할 B가 역할 A에 의존). Ansible은 일반적으로 이를 감지하면 오류를 발생시킵니다.

Ansible 프로젝트 구조화하기

개별 역할 외에도 Ansible 프로젝트의 전체 구조가 중요합니다. 인프라 문제를 분리하는 구조를 채택하는 것을 고려하세요.

ansible-project/
├── inventory/
│   ├── production
│   └── staging
├── group_vars/
│   ├── all.yml
│   ├── webservers.yml
│   └── dbservers.yml
├── host_vars/
│   └── hostname.yml
├── playbooks/
│   ├── deploy_app.yml
│   └── setup_infrastructure.yml
├── roles/
│   ├── common_setup/        # 로컬 역할
│   ├── web_app/           # 종속성이 있는 로컬 역할
│   ├── nginx/             # 로컬 역할
│   └── postgresql/        # 로컬 역할
├── requirements.yml       # Galaxy 종속성용
└── ansible.cfg
  • inventory/: 호스트 인벤토리 파일을 포함합니다.
  • group_vars/host_vars/: 변수 관리용입니다.
  • playbooks/: 역할을 조정하는 최상위 플레이북입니다.
  • roles/: 사용자 정의 로컬 역할을 포함합니다.
  • requirements.yml: 외부(Galaxy) 역할 종속성을 관리하는 파일입니다. ansible-galaxy install -r requirements.yml을 사용하여 설치할 수 있습니다.

meta/main.yml이 역할 종속성을 처리하는 반면, requirements.yml은 프로젝트가 전체적으로 사용하는 외부 역할 모음을 관리하기 위한 것입니다.

핵심 요점

역할을 작게 유지하고, 재정의하기 쉬운 값을 defaults/main.yml에 넣고, 공개 변수를 문서화하며, 다운로드한 역할을 requirements.yml에 고정하세요. 역할이 한 문장으로 자신의 작업을 설명할 수 없다면, 아마 너무 많은 일을 하고 있는 것입니다.