작업 디버깅하기
작업 디버깅하기 (Debugging tasks)
플레이북을 실행하다 작업이 실패하면, 플레이북을 고쳐서 다시 실행해 보는 대신 실패 원인을 실행 중에 바로 고칠 수 있다면 훨씬 편리할 거예요. Ansible의 작업 디버거는 바로 이 역할을 합니다. 변숫값을 확인하거나 수정하고, 모듈 인자를 바꾸고, 새 값으로 작업을 다시 실행해 볼 수 있어요.
출처: 문서
본문
Ansible은 작업 디버거를 제공해요. 그래서 플레이북을 편집하고 변경이 동작하는지 다시 실행하는 대신, 실행 중에 오류를 고칠 수 있습니다. 작업의 컨텍스트에서 디버거의 모든 기능에 접근할 수 있어요. 변수의 값을 확인하거나 설정하고, 모듈 인자를 업데이트하고, 새 변수와 인자로 작업을 다시 실행할 수 있습니다. 디버거는 실패의 원인을 해결하고 플레이북 실행을 계속하게 해줍니다.
디버거 활성화하기 (Enabling the debugger)
디버거는 기본적으로 활성화되어 있지 않아요. 플레이북 실행 중에 디버거를 호출하려면 먼저 활성화해야 합니다.
디버거를 활성화하는 세 가지 방법 중 하나를 사용하세요:
debugger키워드 사용.- 구성(configuration) 또는 환경 변수에서.
- 전략(strategy)으로서.
debugger 키워드로 디버거 활성화하기 (Enabling the debugger with the debugger keyword)
버전 2.5에서 추가되었어요.
debugger 키워드로 특정 play, role, block, task에 대해 디버거를 활성화(또는 비활성화)할 수 있어요. 이 옵션은 플레이북, 플레이, 롤을 개발하거나 확장할 때 특히 유용합니다. 새 작업이나 업데이트된 작업에 디버거를 활성화하고, 실패하면 효율적으로 오류를 고칠 수 있어요. debugger 키워드는 다섯 가지 값을 받습니다:
| 값 | 결과 |
|---|---|
| always | 결과와 무관하게 항상 디버거 호출 |
| never | 결과와 무관하게 절대 디버거 호출 |
| on_failed | 작업이 실패할 때만 디버거 호출 |
| on_unreachable | 호스트에 도달할 수 없을 때만 디버거 호출 |
| on_skipped | 작업이 건너뛰어질 때만 디버거 호출 |
debugger 키워드를 사용할 때 지정한 값은 디버거를 활성화하거나 비활성화하는 전역 구성을 덮어씁니다. debugger를 여러 레벨(예: 롤과 작업)에서 정의하면 Ansible은 가장 세분화된 정의를 따릅니다. play나 role 레벨의 정의는 다른 값을 지정하지 않는 한 그 play나 role 안의 모든 block과 task에 적용돼요. block 레벨의 정의는 play나 role 레벨의 정의를 덮어쓰고, 다른 값을 지정하지 않는 한 그 block 안의 모든 task에 적용됩니다. task 레벨의 정의는 항상 그 작업에 적용되며, block, play, role 레벨의 정의를 덮어씁니다.
debugger 키워드 사용 예시
작업에 debugger 키워드를 설정하는 예시:
- name: Execute a command
ansible.builtin.command: "false"
debugger: on_failed
플레이에 debugger 키워드를 설정하는 예시:
- name: My play
hosts: all
debugger: on_skipped
tasks:
- name: Execute a command
ansible.builtin.command: "true"
when: False
여러 레벨에서 debugger 키워드를 설정하는 예시:
- name: Play
hosts: all
debugger: never
tasks:
- name: Execute a command
ansible.builtin.command: "false"
debugger: on_failed
이 예시에서 디버거는 play 레벨에서 never, task 레벨에서 on_failed로 설정돼요. 작업이 실패하면 Ansible은 디버거를 호출합니다. 그 이유는 작업의 정의가 부모 플레이의 정의를 덮어쓰기 때문입니다.
구성 또는 환경 변수에서 디버거 활성화하기 (Enabling the debugger in configuration or an environment variable)
버전 2.5에서 추가되었어요.
ansible.cfg의 설정이나 환경 변수로 작업 디버거를 전역적으로 활성화할 수 있어요. 옵션은 True 또는 False뿐입니다. 구성 옵션이나 환경 변수를 True로 설정하면 Ansible은 실패한 작업에서 기본적으로 디버거를 실행합니다.
ansible.cfg에서 작업 디버거를 활성화하려면 [defaults] 섹션에 이 설정을 추가하세요:
[defaults]
enable_task_debugger = True
환경 변수로 작업 디버거를 활성화하려면 플레이북을 실행할 때 변수를 전달하세요:
ANSIBLE_ENABLE_TASK_DEBUGGER=True ansible-playbook -i hosts site.yml
디버거를 전역적으로 활성화하면 role, play, block, task가 디버거를 명시적으로 비활성화하지 않는 한 모든 실패한 작업이 디버거를 호출해요. 디버거를 트리거하는 조건을 더 세밀하게 제어해야 한다면 debugger 키워드를 사용하세요.
전략으로서 디버거 활성화하기 (Enabling the debugger as a strategy)
레거시 플레이북이나 롤을 실행하고 있다면 디버거가 전략(strategy)으로 활성화된 것을 볼 수 있어요. play 레벨, ansible.cfg, 또는 환경 변수 ANSIBLE_STRATEGY=debug로 설정할 수 있습니다. 예를 들면:
- hosts: test
strategy: debug
tasks:
- name: Example task
debug:
msg: "This is a debug message"
또는 ansible.cfg에서:
[defaults]
strategy = debug
참고 (Note)
2.5 이전의 Ansible 버전과 일치하는 이 하위 호환 방식은 향후 릴리스에서 제거될 수 있어요.
디버거에서 오류 해결하기 (Resolving errors in the debugger)
Ansible이 디버거를 호출한 후, 일곱 개의 디버거 명령을 사용해 Ansible이 마주친 오류를 해결할 수 있어요. var1 변수를 정의하지만 작업에서 실수로 정의되지 않은 wrong_var 변수를 사용하는 다음 예시 플레이북을 생각해 봅시다.
- hosts: test
debugger: on_failed
gather_facts: false
vars:
var1: value1
tasks:
- name: Use a wrong variable
ansible.builtin.ping: data={{ wrong_var }}
이 플레이북을 실행하면 작업이 실패할 때 Ansible이 디버거를 호출해요. 디버그 프롬프트에서 모듈 인자나 변수를 바꾸고 작업을 다시 실행할 수 있습니다.
PLAY ***************************************************************************
TASK [wrong variable] **********************************************************
fatal: [192.0.2.10]: FAILED! => {"failed": true, "msg": "ERROR! 'wrong_var' is undefined"}
Debugger invoked
[192.0.2.10] TASK: wrong variable (debug)> p result._result
{'failed': True,
'msg': 'The task includes an option with an undefined variable. The error '
"was: 'wrong_var' is undefined\n"
'\n'
'The error appears to have been in '
"'playbooks/debugger.yml': line 7, "
'column 7, but may\n'
'be elsewhere in the file depending on the exact syntax problem.\n'
'\n'
'The offending line appears to be:\n'
'\n'
' tasks:\n'
' - name: wrong variable\n'
' ^ here\n'}
[192.0.2.10] TASK: wrong variable (debug)> p task.args
{u'data': u'{{ wrong_var }}'}
[192.0.2.10] TASK: wrong variable (debug)> task.args['data'] = '{{ var1 }}'
[192.0.2.10] TASK: wrong variable (debug)> p task.args
{u'data': '{{ var1 }}'}
[192.0.2.10] TASK: wrong variable (debug)> redo
ok: [192.0.2.10]
PLAY RECAP *********************************************************************
192.0.2.10 : ok=1 changed=0 unreachable=0 failed=0
디버거에서 작업 인자를 wrong_var 대신 var1을 사용하도록 바꾸면 작업이 성공적으로 실행됩니다.
사용 가능한 디버그 명령 (Available debug commands)
디버그 프롬프트에서 다음 일곱 가지 명령을 사용할 수 있어요:
| 명령 | 단축키 | 동작 |
|---|---|---|
| p | 작업에 대한 정보 출력 | |
| task.args[key] = value | 없음 | 모듈 인자 업데이트 |
| task_vars[key] = value | 없음 | 작업 변수 업데이트 (다음에 update_task 필요) |
| update_task | u | 업데이트된 작업 변수로 작업 재생성 |
| redo | r | 작업 다시 실행 |
| continue | c | 다음 작업부터 실행 계속 |
| quit | q | 디버거 종료 |
자세한 내용은 아래의 개별 설명과 예시를 참고하세요.
print 명령 (Print command)
print *task/task.args/task_vars/host/result*는 작업에 대한 정보를 출력합니다.
[192.0.2.10] TASK: install package (debug)> p task
TASK: install package
[192.0.2.10] TASK: install package (debug)> p task.args
{u'name': u'{{ pkg_name }}'}
[192.0.2.10] TASK: install package (debug)> p task_vars
{u'ansible_all_ipv4_addresses': [u'192.0.2.10'],
u'ansible_architecture': u'x86_64',
...
}
[192.0.2.10] TASK: install package (debug)> p task_vars['pkg_name']
u'bash'
[192.0.2.10] TASK: install package (debug)> p host
192.0.2.10
[192.0.2.10] TASK: install package (debug)> p result._result
{'_ansible_no_log': False,
'changed': False,
u'failed': True,
...
u'msg': u"No package matching 'not_exist' is available"}
인자 업데이트 명령 (Update args command)
task.args[*key*] = *value*는 모듈 인자를 업데이트해요. 다음 샘플 플레이북은 유효하지 않은 패키지 이름을 가집니다.
- hosts: test
strategy: debug
gather_facts: true
vars:
pkg_name: not_exist
tasks:
- name: Install a package
ansible.builtin.apt: name={{ pkg_name }}
플레이북을 실행하면 유효하지 않은 패키지 이름이 오류를 트리거하고 Ansible이 디버거를 호출해요. 모듈 인자를 보고 나서 업데이트해 패키지 이름을 고칠 수 있습니다.
[192.0.2.10] TASK: install package (debug)> p task.args
{u'name': u'{{ pkg_name }}'}
[192.0.2.10] TASK: install package (debug)> task.args['name'] = 'bash'
[192.0.2.10] TASK: install package (debug)> p task.args
{u'name': 'bash'}
[192.0.2.10] TASK: install package (debug)> redo
모듈 인자를 업데이트한 후 redo를 사용해 새 인자로 작업을 다시 실행하세요.
변수 업데이트 명령 (Update vars command)
task_vars[*key*] = *value*는 task_vars를 업데이트해요. 모듈 인자 대신 작업 변수를 보고 나서 업데이트해 위의 플레이북을 고칠 수 있습니다.
[192.0.2.10] TASK: install package (debug)> p task_vars['pkg_name']
u'not_exist'
[192.0.2.10] TASK: install package (debug)> task_vars['pkg_name'] = 'bash'
[192.0.2.10] TASK: install package (debug)> p task_vars['pkg_name']
'bash'
[192.0.2.10] TASK: install package (debug)> update_task
[192.0.2.10] TASK: install package (debug)> redo
작업 변수를 업데이트한 후 redo로 다시 실행하기 전에 반드시 update_task를 사용해 새 변수를 로드해야 합니다.
참고 (Note)
2.5에서 python 함수
vars()와의 충돌을 피하기 위해vars에서task_vars로 변경되었어요.
작업 업데이트 명령 (Update task command)
버전 2.8에서 추가되었어요.
u 또는 update_task는 원래 작업 데이터 구조에서 작업을 재생성하고 업데이트된 작업 변수로 템플릿팅합니다. 사용 예시는 "변수 업데이트 명령(Update vars command)" 항목을 참고하세요.
redo 명령 (Redo command)
r 또는 redo는 작업을 다시 실행합니다.
continue 명령 (Continue command)
c 또는 continue는 다음 작업부터 실행을 계속합니다.
quit 명령 (Quit command)
q 또는 quit는 디버거를 종료합니다. 플레이북 실행은 중단됩니다.
디버거가 free 전략과 상호작용하는 방식 (How the debugger interacts with the free strategy)
기본 linear 전략이 활성화된 상태에서는 디버거가 활성화된 동안 Ansible이 실행을 중지하고, redo 명령을 입력하면 즉시 디버그된 작업을 실행해요. 하지만 free 전략이 활성화되면 Ansible은 모든 호스트를 기다리지 않으며, 한 호스트에서 작업이 실패하기 전에 다른 호스트의 이후 작업을 큐에 넣을 수 있습니다. free 전략에서 Ansible은 디버거가 활성화된 동안 어떤 작업도 큐에 넣거나 실행하지 않아요. 하지만 큐에 있는 모든 작업은 큐에 남아 있으며 디버거를 종료하는 즉시 실행됩니다. 디버거에서 redo로 작업을 다시 예약하면, 다른 큐에 있는 작업이 재예약된 작업보다 먼저 실행될 수 있습니다. 전략에 대한 자세한 내용은 "플레이북 실행 제어: 전략과 그 외"를 참고하세요.
더 보기 (See also)
- 문제 해결을 위한 플레이북 실행 — 디버깅하거나 테스트하는 동안 플레이북 실행하기.
- Ansible 플레이북 — 플레이북 소개.
- 커뮤니케이션 — 질문이나 도움이 필요하거나 아이디어를 나누고 싶다면 Ansible 커뮤니케이션 안내서를 참고하세요.
더 알아보기 (Learn more)
- 디버거와 함께 쓰는 전략의 동작 방식은 "플레이북 실행 제어: 전략과 그 외(playbooks_strategies)" 페이지에서 확인할 수 있어요.