Ansible 태그 기능 활용 가이드

시나리오

Ansible을 활용한 대규모 서버 배포 자동화를 진행할 때, 한 개의 Role 내에서 다양한 작업을 수행해야 하는 경우가 있습니다. 예를 들어, 다수의 호스트에 프로그램을 배포하고, 특정 시점에 따라 서비스를 시작하거나 중지해야 할 수 있습니다. 이러한 요구사항을 해결하는 방법 중 하나가 바로 Ansible의 태그(Tags) 기능입니다.

실습 환경

구성 요소 버전
Ansible 2.9.4
Python 2.7.5
CentOS 7

태그가 필요한 이유

대용량의 Ansible 플레이북을 작성하다 보면, 전체 스크립트 중 특정 부분만 독립적으로 실행해야 하는 상황이 생깁니다. 이때 Ansible에서 제공하는 태그 기능을 사용하면 특정 작업만 선택적으로 실행할 수 있습니다. 공식 문서에서 playbooks_tags 관련 정보를 확인하실 수 있습니다.

실습 진행

Role 스크립트 작성

테스트를 위해 deployRole이라는 이름의 Role을 생성했습니다. 프로젝트 구조는 다음과 같습니다:
deployRole
├── tasks
│   ├── init.yml
│   ├── service.yml
│   └── main.yml
각 파일의 상세 내용입니다:
[root@master01 tasks]# cat init.yml
- name: initialize
  shell: echo init_start
  tags:
      - start

- name: setup
  shell: echo setup_process
  tags:
      - stop
[root@master01 tasks]# cat service.yml
- name: initialize
  shell: echo init_service
  tags:
      - start

- name: verify
  shell: echo verify_status
  tags:
      - restart
[root@master01 tasks]# cat main.yml
- import_tasks: init.yml
  when: ansible_os_family == "RedHat"
- import_tasks: service.yml
  when: ansible_os_family == "RedHat"
  tags:
      - start
[root@master01 tasks]# pwd
/etc/ansible/roles/deployRole/tasks

태그별 실행 테스트

1. start 태그로 실행

[root@master01 ansible-scripts]# ansible-playbook -i hosts_prod --tags start deploy.yml --verbose
실행 결과:
Using /etc/ansible/ansible.cfg as config file

PLAY [production] **********************************************************************

TASK [Gathering Facts] *****************************************************************
ok: [172.168.63.59]
ok: [172.168.63.61]
ok: [172.168.63.60]

TASK [deployRole : initialize] ********************************************************
changed: [172.168.63.59] => {"changed": true, "cmd": "echo init_start", ...}
changed: [172.168.63.61] => {"changed": true, "cmd": "echo init_start", ...}
changed: [172.168.63.60] => {"changed": true, "cmd": "echo init_start", ...}

TASK [deployRole : initialize] ********************************************************
changed: [172.168.63.59] => {"changed": true, "cmd": "echo init_service", ...}
changed: [172.168.63.61] => {"changed": true, "cmd": "echo init_service", ...}
changed: [172.168.63.60] => {"changed": true, "cmd": "echo init_service", ...}

TASK [deployRole : verify] ************************************************************
changed: [172.168.63.59] => {"changed": true, "cmd": "echo verify_status", ...}
changed: [172.168.63.61] => {"changed": true, "cmd": "echo verify_status", ...}
changed: [172.168.63.60] => {"changed": true, "cmd": "echo verify_status", ...}

PLAY RECAP ****************************************************************************
172.168.63.59              : ok=4    changed=3    unreachable=0    failed=0
172.168.63.60              : ok=4    changed=3    unreachable=0    failed=0
172.168.63.61              : ok=4    changed=3    unreachable=0    failed=0

2. stop 태그로 실행

[root@master01 ansible-scripts]# ansible-playbook -i hosts_prod --tags stop deploy.yml --verbose
실행 결과:
Using /etc/ansible/ansible.cfg as config file

PLAY [production] **********************************************************************

TASK [Gathering Facts] *****************************************************************
ok: [172.168.63.61]
ok: [172.168.63.59]
ok: [172.168.63.60]

TASK [deployRole : setup] *************************************************************
changed: [172.168.63.59] => {"changed": true, "cmd": "echo setup_process", ...}
changed: [172.168.63.61] => {"changed": true, "cmd": "echo setup_process", ...}
changed: [172.168.63.60] => {"changed": true, "cmd": "echo setup_process", ...}

PLAY RECAP ****************************************************************************
172.168.63.59              : ok=2    changed=1    unreachable=0    failed=0
172.168.63.60              : ok=2    changed=1    unreachable=0    failed=0
172.168.63.61              : ok=2    changed=1    unreachable=0    failed=0

3. restart 태그로 실행

[root@master01 ansible-scripts]# ansible-playbook -i hosts_prod --tags restart deploy.yml --verbose
실행 결과:
Using /etc/ansible/ansible.cfg as config file

PLAY [production] **********************************************************************

TASK [Gathering Facts] *****************************************************************
ok: [172.168.63.59]
ok: [172.168.63.61]
ok: [172.168.63.60]

TASK [deployRole : verify] ************************************************************
changed: [172.168.63.59] => {"changed": true, "cmd": "echo verify_status", ...}
changed: [172.168.63.61] => {"changed": true, "cmd": "echo verify_status", ...}
changed: [172.168.63.60] => {"changed": true, "cmd": "echo verify_status", ...}

PLAY RECAP ****************************************************************************
172.168.63.59              : ok=2    changed=1    unreachable=0    failed=0
172.168.63.60              : ok=2    changed=1    unreachable=0    failed=0
172.168.63.61              : ok=2    changed=1    unreachable=0    failed=0

4. 태그 미지정으로 실행

[root@master01 ansible-scripts]# ansible-playbook -i hosts_prod deploy.yml --verbose
실행 결과:
Using /etc/ansible/ansible.cfg as config file

PLAY [production] **********************************************************************

TASK [Gathering Facts] *****************************************************************
ok: [172.168.63.61]
ok: [172.168.63.59]
ok: [172.168.63.60]

TASK [deployRole : initialize] ********************************************************
changed: [172.168.63.59] => {"changed": true, "cmd": "echo init_start", ...}
changed: [172.168.63.61] => {"changed": true, "cmd": "echo init_start", ...}
changed: [172.168.63.60] => {"changed": true, "cmd": "echo init_start", ...}

TASK [deployRole : setup] *************************************************************
changed: [172.168.63.59] => {"changed": true, "cmd": "echo setup_process", ...}
changed: [172.168.63.61] => {"changed": true, "cmd": "echo setup_process", ...}
changed: [172.168.63.60] => {"changed": true, "cmd": "echo setup_process", ...}

TASK [deployRole : initialize] ********************************************************
changed: [172.168.63.59] => {"changed": true, "cmd": "echo init_service", ...}
changed: [172.168.63.61] => {"changed": true, "cmd": "echo init_service", ...}
changed: [172.168.63.60] => {"changed": true, "cmd": "echo init_service", ...}

TASK [deployRole : verify] ************************************************************
changed: [172.168.63.59] => {"changed": true, "cmd": "echo verify_status", ...}
changed: [172.168.63.61] => {"changed": true, "cmd": "echo verify_status", ...}
changed: [172.168.63.60] => {"changed": true, "cmd": "echo verify_status", ...}

PLAY RECAP ****************************************************************************
172.168.63.59              : ok=5    changed=4    unreachable=0    failed=0
172.168.63.60              : ok=5    changed=4    unreachable=0    failed=0
172.168.63.61              : ok=5    changed=4    unreachable=0    failed=0

결과 분석

위 테스트를 통해 다음과 같은 핵심 사항을 파악할 수 있습니다:
  1. 개별 태그 지정: 작업 파일 내 특정 태그를 지정하고, 실행 시 해당 태그를 명시하면 태그에 매칭되는 작업만 수행됩니다.
  2. 태그 상속 및 우선순위: 상위 레벨(main.yml)에서 태그를 지정하면 하위 작업 파일의 모든 작업이 실행됩니다. 즉, 범위가 큰 태그가 작은 범위의 태그를 덮어쓰는 특성이 있습니다.
  3. 기본 동작: 실행 시 태그를 지정하지 않으면 모든 작업이 순차적으로 실행됩니다.

정리

Ansible의 태그 기능을 활용하면 대규모 배포 환경에서 유연한 작업 제어가 가능합니다. 서버 대수가 증가할수록 수동으로 개별 접속하여 작업하는 것은 비효율적이며, 태그를 적절히 활용하면 배포, 시작, 중지, 재시작 등의 작업을 하나의 플레이북으로 효율적으로 관리할 수 있습니다. 관련 공식 문서에서 더 자세한 내용을 확인하시기 바랍니다.

태그: Ansible automation DevOps configuration-management tags

7월 24일 07:14에 게시됨