Tags
Tags
Ansible 태그(tags)를 쓰면 큰 플레이북 전체를 실행하는 대신 원하는 부분만 골라 실행하거나 건너뛸 수 있어요. 태그를 작업에 붙여두고, 플레이북을 실행할 때 특정 태그만 선택하거나 제외하는 방식으로 동작해요. 규모가 큰 자동화에서 재사용성과 실행 제어를 높이는 핵심 기능이에요.
출처: 문서
본문
플레이북이 커지면 전체를 실행하는 대신 일부만 실행하고 싶을 때가 있어요. 이럴 때 Ansible 태그를 사용하면 됩니다. 태그로 선택한 작업만 실행하거나 건너뛰는 과정은 두 단계로 이루어져요.
- 작업에 태그를 추가한다. 개별적으로 추가하거나, 블록·플레이·롤·임포트로부터 태그 상속을 받을 수 있어요.
- 플레이북을 실행할 때 실행하거나 건너뛸 태그를 선택한다.
Note
tags키워드는 플레이북의 '전처리' 단계에 속하며, 실행할 작업을 결정할 때 높은 우선순위를 가져요.
tags 키워드로 태그 추가하기
단일 작업이나 include에 태그를 추가할 수 있어요. 블록, 플레이, 롤, 임포트 수준에서 정의하면 여러 작업에 동시에 태그를 추가할 수도 있어요. tags 키워드는 항상 태그를 정의해 작업에 더하는 역할만 하며, 실행할 작업을 선택하거나 건너뛰는 역할은 하지 않아요. 실행 여부 선택은 플레이북을 실행할 때 커맨드 라인에서 태그를 기준으로만 가능해요.
개별 작업에 태그 추가하기
가장 단순한 형태로, 개별 작업에 하나 이상의 태그를 적용할 수 있어요. 플레이북, 작업 파일, 롤 안 어디서든 작업에 태그를 달 수 있어요. 다음은 두 작업에 서로 다른 태그를 단 예시예요.
tasks:
- name: Install the servers
ansible.builtin.yum:
name:
- httpd
- memcached
state: present
tags:
- packages
- webservers
- name: Configure the service
ansible.builtin.template:
src: templates/src.j2
dest: /etc/foo.conf
tags:
- configuration
같은 태그를 여러 개별 작업에 적용할 수도 있어요. 다음은 여러 작업에 같은 "ntp" 태그를 건 예시예요.
---
# file: roles/common/tasks/main.yml
- name: Install ntp
ansible.builtin.yum:
name: ntp
state: present
tags: ntp
- name: Configure ntp
ansible.builtin.template:
src: ntp.conf.j2
dest: /etc/ntp.conf
notify:
- restart ntpd
tags: ntp
- name: Enable and run ntpd
ansible.builtin.service:
name: ntpd
state: started
enabled: true
tags: ntp
- name: Install NFS utils
ansible.builtin.yum:
name:
- nfs-utils
- nfs-util-lib
state: present
tags: filesharing
이 네 작업을 --tags ntp 로 실행하면, ntp 태그가 붙은 작업 세 개는 실행되고 태그가 없는 파일 공유 작업은 건너뛰어요.
핸들러(handlers)는 알림을 받았을 때만 실행되는 특수한 작업이라, 모든 태그를 무시하고 태그 기준으로 선택하거나 제외할 수 없어요.
플레이 안의 일부(전부는 아닌) 작업에 태그를 붙이려면 블록을 쓰고 그 수준에서 태그를 정의하면 돼요. 위 NTP 예시를 블록으로 바꾸면 다음과 같아요.
# myrole/tasks/main.yml
- name: ntp tasks
tags: ntp
block:
- name: Install ntp
ansible.builtin.yum:
name: ntp
state: present
- name: Configure ntp
ansible.builtin.template:
src: ntp.conf.j2
dest: /etc/ntp.conf
notify:
- restart ntpd
- name: Enable and run ntpd
ansible.builtin.service:
name: ntpd
state: started
enabled: true
- name: Install NFS utils
ansible.builtin.yum:
name:
- nfs-utils
- nfs-util-lib
state: present
tags: filesharing
태그 선택이 블록 오류 처리 등 대부분의 다른 로직보다 우선한다는 점에 주의하세요. 블록의 작업에만 태그를 붙이고 rescue나 always 섹션에는 붙이지 않으면, 태그 선택이 해당 섹션의 작업을 포함하지 않을 때 그들이 실행되지 않을 수 있어요.
- block:
- debug: msg=run with tag, but always fail
failed_when: true
tags: example
rescue:
- debug: msg=I always run because the block always fails, except if you select to only run 'example' tag
always:
- debug: msg=I always run, except if you select to only run 'example' tag
이 예시는 --tags 없이 실행하면 세 작업이 모두 실행되지만, --tags example로 실행하면 첫 번째 작업만 실행돼요.
플레이의 모든 작업에 같은 태그를 붙이려면 플레이 수준에서 태그를 정의하면 돼요. NTP 작업만 있는 플레이에 전체 태그를 붙이려면:
- hosts: all
tags: ntp
tasks:
- name: Install ntp
ansible.builtin.yum:
name: ntp
state: present
- name: Configure ntp
ansible.builtin.template:
src: ntp.conf.j2
dest: /etc/ntp.conf
notify:
- restart ntpd
- name: Enable and run ntpd
ansible.builtin.service:
name: ntpd
state: started
enabled: true
- hosts: fileservers
tags: filesharing
tasks:
# ...
Note
태그가 붙은 작업에는 롤에서 추가된 작업뿐 아니라 팩트 수집 같은 암묵적 작업도 모두 포함돼요.
롤에 태그를 추가하는 방법은 세 가지예요.
roles아래에서 태그를 설정해 롤의 모든 작업에 같은 태그를 붙인다.- 플레이북의 정적
import_role에 태그를 설정해 롤의 모든 작업에 같은 태그를 붙인다. - 롤 내부의 개별 작업이나 블록에 태그를 붙인다. 이 방법만이 롤 안의 일부 작업을 선택하거나 건너뛰는 유일한 방법이에요. 롤 안의 작업을 선택·건너뛰려면 개별 작업이나 블록에 태그를 설정하고, 플레이북에서 동적
include_role을 쓰며, include에 같은 태그를 붙여야 해요. 이 방식으로--tags foo실행 시 include 자체와 롤 안에서 foo 태그가 있는 작업이 모두 실행돼요.
roles 키워드로 플레이북에서 롤을 정적으로 포함하면, 정의한 태그가 롤의 모든 작업에 붙어요. 예:
roles:
- role: webserver
vars:
port: 5000
tags: [ web, foo ]
또는:
---
- hosts: webservers
roles:
- role: foo
tags:
- bar
- baz
# using YAML shorthand, this is equivalent to:
# - { role: foo, tags: ["bar", "baz"] }
Note
롤 수준에 태그를 추가하면 모든 작업에 태그가 붙을 뿐 아니라, 롤의 의존성(dependencies) 작업에도 태그가 붙어요.
플레이북에서 동적 include에 태그를 적용할 수 있어요. 개별 작업의 태그와 마찬가지로, include_* 작업의 태그는 include 자체에만 적용되며 포함된 파일이나 롤 안의 작업에는 적용되지 않아요. 동적 include에 mytag를 붙이고 --tags mytag로 실행하면, include 자체와 포함된 파일·롤 안에서 mytag가 붙은 작업을 실행하고, 그 태그가 없는 작업은 건너뛰어요.
---
# file: roles/common/tasks/main.yml
- name: Dynamic reuse of database tasks
include_tasks: db.yml
tags: db
롤의 동적 include에만 태그를 붙일 수도 있어요. 아래 예시에서 foo 태그는 bar 롤 안의 작업에는 적용되지 않아요.
---
- hosts: webservers
tasks:
- name: Include the bar role
include_role:
name: bar
tags:
- foo
정적 import_role과 import_tasks가 임포트하는 모든 작업에도 태그를 붙일 수 있어요.
---
- hosts: webservers
tasks:
- name: Import the foo role
import_role:
name: foo
tags:
- bar
- baz
- name: Import tasks from foo.yml
import_tasks: foo.yml
tags: [ web, foo ]
기본적으로 Ansible은 include_role·include_tasks로 하는 동적 재사용에는 태그 상속을 적용하지 않아요. include에 태그를 붙이면 그 태그는 include 자체에만 적용되고, 포함된 파일이나 롤의 작업에는 적용되지 않아요. 그래서 롤이나 작업 파일 안의 선택된 작업만 실행할 수 있어요.
태그 상속이 필요하다면 임포트(import)를 쓰는 게 좋아요. 다만 한 플레이북에서 include와 import를 함께 쓰면 진단하기 어려운 버그가 생길 수 있어요. include로 롤·작업을 재사용하면서 특정 include에만 태그 상속이 필요하다면 두 가지 방법을 쓸 수 있어요. apply 키워드:
- name: Apply the db tag to the include and to all tasks in db.yml
include_tasks:
file: db.yml
# adds 'db' tag to tasks within db.yml
apply:
tags: db
# adds 'db' tag to this 'include_tasks' itself
tags: db
또는 블록:
- block:
- name: Include tasks from db.yml
include_tasks: db.yml
tags: db
특수 태그(Special tags)
Ansible은 특별한 동작을 위해 몇 가지 태그 이름을 예약하고 있어요: always, never, tagged, untagged, all. always와 never는 주로 작업 자체에 태그를 다는 데 쓰이고, 나머지 세 개는 실행하거나 건너뛸 태그를 선택할 때 사용해요.
always와 never
작업이나 플레이에 always 태그를 붙이면, 명시적으로 건너뛰지(--skip-tags always) 않는 한 Ansible은 항상 그 작업·플레이를 실행해요.
tasks:
- name: Print a message
ansible.builtin.debug:
msg: "Always runs"
tags:
- always
- name: Print a message
ansible.builtin.debug:
msg: "runs when you use specify tag1, all(default) or tagged"
tags:
- tag1
- name: Print a message
ansible.builtin.debug:
msg: "always runs unless you explicitly skip, like if you use ``--skip-tags tag2``"
tags:
- always
- tag2
Warning
내부 팩트 수집 작업은 기본적으로 'always' 태그가 붙어 있어요. 하지만 플레이에 태그를 붙이고 직접 건너뛰거나(
--skip-tags),--tags사용 시 포함하지 않으면 간접적으로 건너뛸 수 있어요.
Warning
롤 인수 스펙 검증(role argument specification validation) 작업도 기본적으로 'always' 태그가 붙어 있어요.
--skip-tags always를 쓰면 이 검증이 건너뛰어져요.
(버전 2.5에 추가됨)
작업이나 플레이에 never 태그를 붙이면, 명시적으로 요청하지 않는 한(--tags never 또는 해당 작업에 정의된 다른 태그) Ansible은 그 작업·플레이를 건너뛰어요.
tasks:
- name: Run the rarely-used debug task, either with ``--tags debug`` or ``--tags never``
ansible.builtin.debug:
msg: '{{ showmevar }}'
tags: [ never, debug ]
위 예시의 거의 쓰이지 않는 debug 작업은 debug나 never 태그를 명시적으로 요청할 때만 실행돼요.
플레이북을 실행할 때 태그 선택 또는 건너뛰기
작업, include, 블록, 플레이, 롤, 임포트에 태그를 추가했다면, ansible-playbook 실행 시 태그를 기준으로 작업을 선택적으로 실행·건너뛸 수 있어요. Ansible은 커맨드 라인에서 전달한 태그와 일치하는 태그가 있는 모든 작업을 실행하거나 건너뛰어요. 블록·플레이 수준에서 또는 roles, 임포트로 태그를 추가하면 그 태그는 블록, 플레이, 롤, 임포트된 롤·파일 안의 모든 작업에 적용돼요.
ansible-playbook은 다섯 가지 태그 관련 커맨드 라인 옵션을 제공해요:
--tags all— never가 아닌 한 태그 있는·없는 모든 작업 실행(기본 동작).--tags tag1,tag2— tag1 또는 tag2 태그가 있는 작업만 실행(always 태그도 포함).--skip-tags tag3,tag4— tag3 또는 tag4 또는 never 태그가 있는 작업 제외한 모든 작업 실행.--tags tagged— 태그가 하나 이상 있는 작업만 실행(never가 우선).--tags untagged— 태그가 없는 작업만 실행(always가 우선).
예를 들어 아주 긴 플레이북에서 configuration 또는 packages 태그가 붙은 작업과 블록만 실행하려면:
ansible-playbook example.yml --tags "configuration,packages"
packages 태그가 붙은 작업을 제외한 모든 작업을 실행하려면:
ansible-playbook example.yml --skip-tags "packages"
never 태그로 제외된 작업까지 포함해 모든 작업을 실행하려면:
ansible-playbook example.yml --tags "all,never"
tag1 또는 tag3이 있는 작업을 실행하되 tag4도 가진 작업은 건너뛰려면:
ansible-playbook example.yml --tags "tag1,tag3" --skip-tags "tag4"
태그 우선순위
건너뛰기(skipping)가 명시적 태그보다 항상 우선해요. 예를 들어 --tags와 --skip-tags를 함께 지정하면 후자가 우선해요. --tags tag1,tag3,tag4 --skip-tags tag3은 tag1이나 tag4 태그가 있는 작업만 실행하고, 다른 태그가 있더라도 tag3이 있는 작업은 실행하지 않아요.
태그 사용 결과 미리 보기
롤이나 플레이북을 실행할 때 어떤 작업에 어떤 태그가 있는지, 또는 어떤 태그가 존재하는지 모를 수 있어요. Ansible은 두 가지 커맨드 라인 플래그를 제공해요:
--list-tags— 사용 가능한 태그 목록 생성.--list-tasks—--tags tagname또는--skip-tags tagname과 함께 쓰면 태그된 작업 미리보기 생성.
예를 들어 configuration 작업의 태그가 config인지 conf인지 모른다면, 아무 작업도 실행하지 않고 사용 가능한 태그를 모두 표시할 수 있어요:
ansible-playbook example.yml --list-tags
configuration과 packages 태그가 있는 작업이 뭔지 모른다면, 그 태그를 전달하고 --list-tasks를 추가하면 됩니다. Ansible은 작업을 나열만 하고 실행하지는 않아요.
ansible-playbook example.yml --tags "configuration,packages" --list-tasks
이 커맨드 라인 플래그는 동적으로 포함된 파일이나 롤 안의 태그·작업은 표시하지 못하는 제한이 있어요.
재사용 파일에서 태그된 작업 선택 실행
작업·블록 수준에서 태그가 정의된 롤이나 작업 파일이 있다면, 정적 임포트 대신 동적 include를 쓰면 플레이북에서 그 태그된 작업을 선택적으로 실행하거나 건너뛸 수 있어요. 포함된 작업과 include 문에 같은 태그를 써야 해요. 예를 들어 태그가 있는 작업과 없는 작업이 섞인 파일을 만들 수 있어요:
# mixed.yml
tasks:
- name: Run the task with no tags
ansible.builtin.debug:
msg: this task has no tags
- name: Run the tagged task
ansible.builtin.debug:
msg: this task is tagged with mytag
tags: mytag
- block:
- name: Run the first block task with mytag
# ...
- name: Run the second block task with mytag
# ...
tags:
- mytag
그리고 플레이북에서 위 작업 파일을 include할 수 있어요:
# myplaybook.yml
- hosts: all
tasks:
- name: Run tasks from mixed.yml
include_tasks:
name: mixed.yml
tags: mytag
ansible-playbook -i hosts myplaybook.yml --tags "mytag"로 실행하면, 태그가 없는 작업은 건너뛰고, 태그된 개별 작업과 블록의 두 작업을 실행해요. 팩트 수집(암묵적 작업)은 always 태그가 있어 실행될 수도 있어요.
태그 상속: 여러 작업에 태그 추가
모든 작업에 tags 줄을 넣지 않고 여러 작업에 같은 태그를 적용하고 싶다면, 플레이·블록 수준에서 또는 롤·파일 임포트 시 태그를 정의하면 돼요. Ansible은 의존성 체인을 따라 모든 하위 작업에 태그를 적용해요. 롤·임포트에서는 roles 섹션·임포트가 설정한 태그를 롤·임포트된 파일 안의 개별 작업·블록 태그에 덧붙여요. 이를 태그 상속이라 해요. 모든 작업에 태그를 일일이 달지 않아도 되므로 편리해요.
플레이, 블록, role 키워드, 정적 임포트에서는 태그 상속이 적용되어 정의한 태그가 플레이·블록·롤·임포트된 파일 안의 모든 작업에 더해져요. 하지만 태그 상속은 include_role·include_tasks로 하는 동적 재사용에는 적용되지 않아요. 동적 재사용(include)에서는 정의한 태그가 include 자체에만 적용돼요. 태그 상속이 필요하면 정적 임포트를 쓰세요. 나머지 플레이북이 include를 쓰기 때문에 임포트를 쓸 수 없다면, 앞서 설명한 블록이나 apply 키워드 방법으로 우회할 수 있어요.
전역적으로 태그 구성하기
특정 태그를 기본적으로 실행하거나 건너뛰려면 Ansible 구성의 TAGS_RUN과 TAGS_SKIP 옵션으로 기본값을 설정할 수 있어요.