✔️ 작업 재사용
[vagrant@controller 09_artifact_tasks]$ ansible-doc -l | grep include_
include_vars Load variables from files, dynamically within a task
include_role Load and execute a role
include_tasks Dynamically include a task list
[vagrant@controller 09_artifact_tasks]$ ansible-doc -l | grep import_
import_playbook Import a playbook
import_role Import a role into a play
import_tasks Import a task list
- include_vars : 변수 가져오기
- include_role : 역할 가져오기
- include_tasks : 작업 가져오기
- import_playbook : 플레이북 가져오기
- import_role : 역할 가져오기
- import_tasks : 작업 가져오기
✔️ include vs import 모듈의 차이
Type of re-use : 재사용 형식
include와 import 방식의 가장 큰 차이점은 include(dynamic) vs import(static) 이다.
include는 작업이 실행될 때 해당되는 모듈에 가서 해당되는 내용을 읽는다.
import는 import 되어있는 항목을 미리 읽어서 사전에 플레이북을 만든다.
예제
[vagrant@controller 09_artifact_tasks]$ code include.yaml
[vagrant@controller 09_artifact_tasks]$ cat include.yaml
- hosts: 192.168.100.11
tasks:
- debug:
msg: in play
- include_tasks:
file: task.yaml
- debug:
msg: in play
[vagrant@controller 09_artifact_tasks]$ code task.yaml
[vagrant@controller 09_artifact_tasks]$ cat task.yaml
- debug:
msg: inner module 1
- debug:
msg: inner module 2
[vagrant@controller 09_artifact_tasks]$ ansible-playbook include.yaml --list-tasks
playbook: include.yaml
play #1 (192.168.100.11): 192.168.100.11 TAGS: []
tasks:
debug TAGS: []
include_tasks TAGS: []
debug TAGS: []
test.yaml 파일 안에 있는 내용을 아직 모른다.
include_tasks를 만나야 뭐가 있는지 알게되고 그제서야 실행한다.
[vagrant@controller 09_artifact_tasks]$ code import.yaml
[vagrant@controller 09_artifact_tasks]$ cat import.yaml
- hosts: 192.168.100.11
tasks:
- debug:
msg: in play
- import_tasks:
file: task.yaml
- debug:
msg: in play
[vagrant@controller 09_artifact_tasks]$ ansible-playbook include.yaml --list-tasks
playbook: include.yaml
play #1 (192.168.100.11): 192.168.100.11 TAGS: []
tasks:
debug TAGS: []
include_tasks TAGS: []
debug TAGS: []
[vagrant@controller 09_artifact_tasks]$ ansible-playbook import.yaml --list-tasks
playbook: import.yaml
play #1 (192.168.100.11): 192.168.100.11 TAGS: []
tasks:
debug TAGS: []
debug TAGS: []
debug TAGS: []
debug TAGS: []
사전에 task.yaml 파일을 미리 읽어서 대치를 해버리고 작업을 순서대로 실행한다.
debug 실행 → include → debug 실행(inner module1) → debug 실행(inner module2) → debug 실행(in play)
[vagrant@controller 09_artifact_tasks]$ ansible-playbook include.yaml
PLAY [192.168.100.11] ***********************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11]
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "in play"
}
TASK [include_tasks] ************************************************************************************************************************************************************************************************************************************************
included: /home/vagrant/code/09_artifact_tasks/task.yaml for 192.168.100.11
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 1"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 2"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "in play"
}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************************
192.168.100.11 : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
import를 하게되면
debug 실행 → debug 실행 → debug 실행 → debug 실행 순서로 진행된다.
[vagrant@controller 09_artifact_tasks]$ ansible-playbook import.yaml
PLAY [192.168.100.11] ***********************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11]
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "in play"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 1"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 2"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "in play"
}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************************
192.168.100.11 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
작업을 Dynamic, Static으로 가져오는 것에 따라서 주요한 기능상의 차이가 발생한다.
중요하게 봐야 할 항목은 Calling from loops 이다.
단순히 사전 처리가 되느냐 아니냐 문제를 넘어 loop를 호출할 수 있느냐가 include와 import 차이점의 핵심이다.
결론부터 말하자면 include는 loop를 사용 가능 vs import는 loop를 사용 불가하다.
import 먼저 예제를 보자
task.yaml
- debug:
msg: inner module 1
- debug:
msg: inner module 2
with_sequence: start=1 end=3
해당 코드는 3번의 반복이 일어난다.
[vagrant@controller 09_artifact_tasks]$ code import.yaml
[vagrant@controller 09_artifact_tasks]$ code task.yaml
[vagrant@controller 09_artifact_tasks]$ ansible-playbook import.yaml
...
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "in play"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 1"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => (item=1) => {
"msg": "inner module 2"
}
ok: [192.168.100.11] => (item=2) => {
"msg": "inner module 2"
}
ok: [192.168.100.11] => (item=3) => {
"msg": "inner module 2"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "in play"
}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************************
192.168.100.11 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
문제 없이 실행된다.
task.yaml에서 loop를 지우고 import.yaml 파일에 직접 loop 코드를 넣어보자
task.yaml
- debug:
msg: inner module 1
- debug:
msg: inner module 2
#with_sequence: start=1 end=3
import.yaml
- hosts: 192.168.100.11
tasks:
- debug:
msg: in play
- import_tasks:
file: task.yaml
with_sequence: start=1 end=3
- debug:
msg: in play
[vagrant@controller 09_artifact_tasks]$ ansible-playbook import.yaml
ERROR! You cannot use loops on 'import_tasks' statements. You should use 'include_tasks' instead.
The error appears to be in '/home/vagrant/code/09_artifact_tasks/import.yaml': line 5, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
msg: in play
- import_tasks:
^ here
You cannot use loops on 'import_tasks' statements 라는 오류가 뜨며 실행되지 않는다.
import_tasks 같은 경우 loop를 사용할 수 없다. 에러 구문에서도 import_tasks 대신 include_tasks를 사용하라고 한다.
물론, include의 경우 playbook에서 loop처리, 외부 파일에서 loop 처리 둘 다 가능하다.
[vagrant@controller 09_artifact_tasks]$ ansible-playbook include.yaml
PLAY [192.168.100.11] ***********************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11]
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "in play"
}
TASK [include_tasks] ************************************************************************************************************************************************************************************************************************************************
included: /home/vagrant/code/09_artifact_tasks/task.yaml for 192.168.100.11
included: /home/vagrant/code/09_artifact_tasks/task.yaml for 192.168.100.11
included: /home/vagrant/code/09_artifact_tasks/task.yaml for 192.168.100.11
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 1"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 2"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 1"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 2"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 1"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 2"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "in play"
}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************************
192.168.100.11 : ok=12 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[vagrant@controller 09_artifact_tasks]$
include 내의 loop 코드를 주석처리하고 task.yaml에 loop문을 살리면 잘 된다.
[vagrant@controller 09_artifact_tasks]$ ansible-playbook include.yaml
PLAY [192.168.100.11] ***********************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11]
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "in play"
}
TASK [include_tasks] ************************************************************************************************************************************************************************************************************************************************
included: /home/vagrant/code/09_artifact_tasks/task.yaml for 192.168.100.11
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "inner module 1"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => (item=1) => {
"msg": "inner module 2"
}
ok: [192.168.100.11] => (item=2) => {
"msg": "inner module 2"
}
ok: [192.168.100.11] => (item=3) => {
"msg": "inner module 2"
}
TASK [debug] ********************************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "in play"
}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************************
192.168.100.11 : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
정리하자면 include는 모듈 자체에 붙이나 외부에 붙이나 상관없지만 import는 모듈 자체에 붙이는 것이 안된다.
✔️ import에서 loop 불가능
해당 코드는 불가능한 코드이다.
- hosts: 192.168.100.11
tasks:
- debug:
msg: in play
- import_tasks:
file: task.yaml
with_sequence: start=1 end=3 # 안된다.
- debug:
msg: in play
✔️ 해결 방법
- hosts: 192.168.100.11
tasks:
- debug:
msg: in play
- import_tasks:
file: task.yaml
- debug:
msg: in play
task.yaml
- debug:
with_sequence: start=1 end=3
Using --list-tasks
Using --list-tags
리스트에 보이지 않는다 → 파일을 읽는 방식이 Dynamic 하므로 사전처리가 되지 않기 때문이다.
실제로 가져오는 파일 내부의 task 또는 tag를 볼 수 없다.
Using -start-at-task
Notifying handlers
마찬가지로 include는 안되고 import는 된다.
예시include.yaml
- hosts: 192.168.100.11
tasks:
- command: hostname # command task는 항상 change
notify:
- hello notify
handlers:
- include_tasks: task.yaml
import.yaml
- hosts: 192.168.100.11
tasks:
- command: hostname
notify:
- hello notify
handlers:
- import_tasks: task.yaml
task.yaml
- name: hello notify
debug:
msg: hello notify
두 파일 모두 알림을 받을 name이 task.yaml 내부에 선언되어 있다.
결과
[vagrant@controller 09_artifact_tasks]$ ansible-playbook import.yaml
PLAY [192.168.100.11] ***********************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11]
TASK [command] ******************************************************************************************************************************************************************************************************************************************************
changed: [192.168.100.11]
RUNNING HANDLER [hello notify] **************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "hello notify"
}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************************
192.168.100.11 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
import.yaml을 실행하면 핸들러가 정상적으로 실행된다.
import는 정적으로 처리가 되기 때문에 알림이 전송된다.
그러나 include는 include_tasks에서 해당 파일의 이름을 읽은뒤 그제서야 task.yaml 파일의 name을 읽어오게 된다.
따라서 handlers 전에 hello notify에 대한 정보를 찾지 못한다.
✔️ include에서 핸들러 호출 불가능
[vagrant@controller 09_artifact_tasks]$ ansible-playbook include.yaml
PLAY [192.168.100.11] ***********************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11]
TASK [command] ******************************************************************************************************************************************************************************************************************************************************
ERROR! The requested handler 'hello notify' was not found in either the main handlers list nor in the listening handlers list
✔️ 해결 방법
이름을 붙이면 된다.include.yaml
- hosts: 192.168.100.11
tasks:
- command: hostname
notify:
- hello notify
handlers:
- name: hello notify
include_tasks: task.yaml
[vagrant@controller 09_artifact_tasks]$ ansible-playbook include.yaml
PLAY [192.168.100.11] ***********************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11]
TASK [command] ******************************************************************************************************************************************************************************************************************************************************
changed: [192.168.100.11]
RUNNING HANDLER [hello notify] **************************************************************************************************************************************************************************************************************************************
included: /home/vagrant/code/09_artifact_tasks/task.yaml for 192.168.100.11
RUNNING HANDLER [hello notify] **************************************************************************************************************************************************************************************************************************************
ok: [192.168.100.11] => {
"msg": "hello notify"
}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************************************
192.168.100.11 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=
이 경우는 우선 task.yaml을 읽어오기 이전에 hello notify를 호출한다고 되어있기 때문에
실제 실행은 나중에 task.yaml을 가져와서 실행한다.
'DevOps > Ansible' 카테고리의 다른 글
[Ansible] 플레이 레벨에서 작업 실행 순서 (0) | 2022.04.21 |
---|---|
[Ansible] artifact 재사용 - 역할(roles) (0) | 2022.04.21 |
[Ansible] artifact 재사용 - 파일 재사용 (1) (0) | 2022.04.20 |
[Ansible] 작업 제어 (Task Controll) (0) | 2022.04.20 |
[Ansible] 태그 (Tag) (0) | 2022.04.20 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!