[K8S Deploy Study by Gasida] - Ansible 기초 -도전과제
1. 생성된 user를 ansible.builtin.user 모듈을 통해서 제거하기
- playbook(
example.yaml)에 그룹(test-admin)을 생성하고 유저(testuser) 를 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
- hosts: desktop-linux
tasks:
- name: 리눅스 내에서 그룹 'test-admin'을 생성
ansible.builtin.group:
name: test-admin
state: present
- name: 리눅스 내에서 사용자 'testuser' 생성 후 특정 uid와 주 그룹을 'test-admin'으로 설정
ansible.builtin.user:
name: testuser
comment: Test User
uid: 1040
group: test-admin
1
2
3
4
5
# 플레이북 실행
ansible-playbook ./example.yaml
# 다른 터미널에서 모니터링
watch -d "ssh desktop-linux tail -n 3 /etc/passwd"
- 추가한 유저(
testuser) 삭제하기
1
2
3
4
5
6
7
8
9
---
- hosts: desktop-linux
tasks:
- name: 리눅스 내에서 사용자 'testuser'를 삭제
ansible.builtin.user:
name: testuser
state: absent
remove: yes
- 유저가 삭제 되었는지 확인
2. 관리 대상 uptime 을 ansible.builtin.debug 모듈을 통해 가져오기
1
2
3
4
5
6
7
8
9
10
11
---
- hosts: desktop-linux
tasks:
- name: uptime 정보 가져오기
ansible.builtin.shell: /usr/bin/uptime
register: result
- name: 이전 태스크로부터 리턴된 결과를 출력
ansible.builtin.debug:
var: result.stdout_lines
3. 팩트를 사용하여 3개의 VM의 ‘커널 버전’과 ‘운영체제 종류’를 출력
facts-challenge3.yml
1
2
3
4
5
6
7
---
- hosts: all
tasks:
- name: 커널 버전’과 ‘운영체제 종류’를 출력
ansible.builtin.debug:
msg: "The Kernel version of is and the OS is "
실행 하기
1
ansible-playbook facts-challenge3.yml
결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
PLAY [all] ******************************************************************************************
TASK [Gathering Facts] ******************************************************************************
ok: [tnode1]
ok: [tnode2]
ok: [tnode3]
TASK [커널 버전’과 ‘운영체제 종류’를 출력] **********************************************************
ok: [tnode1] => {
"msg": "The Kernel version of tnode1 is 6.8.0-86-generic and the OS is Debian"
}
ok: [tnode2] => {
"msg": "The Kernel version of tnode2 is 6.8.0-86-generic and the OS is Debian"
}
ok: [tnode3] => {
"msg": "The Kernel version of tnode3 is 5.14.0-570.52.1.el9_6.aarch64 and the OS is RedHat"
}
PLAY RECAP ******************************************************************************************
tnode1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode3 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4. 반복문으로 대량의 유저 생성하고 삭제해보기
testuser1~10의 유저를 추가 하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---
- hosts: desktop-linux
tasks:
- name: 리눅스 내에서 사용자 'testuser1~10' 생성
ansible.builtin.user:
name: testuser
loop: ""
- name: 생성된 사용자 확인
ansible.builtin.shell: "getent passwd | grep testuser"
register: users
- name: 사용자 정보 출력
ansible.builtin.debug:
msg: ""
- name: 생성된 사용자 삭제
ansible.builtin.user:
name: testuser
state: absent
loop: ""
- 결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
PLAY [desktop-linux] ******************************************************************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************************************************************************
ok: [desktop-linux]
TASK [리눅스 내에서 사용자 'testuser1~10' 생성] ***************************************************************************************************************************************************
changed: [desktop-linux] => (item=1)
changed: [desktop-linux] => (item=2)
changed: [desktop-linux] => (item=3)
changed: [desktop-linux] => (item=4)
changed: [desktop-linux] => (item=5)
changed: [desktop-linux] => (item=6)
changed: [desktop-linux] => (item=7)
changed: [desktop-linux] => (item=8)
changed: [desktop-linux] => (item=9)
changed: [desktop-linux] => (item=10)
TASK [생성된 사용자 확인] *************************************************************************************************************************************************************************
changed: [desktop-linux]
TASK [사용자 정보 출력] ***************************************************************************************************************************************************************************
ok: [desktop-linux] => {
"msg": [
"testuser1:x:1002:1003::/home/testuser1:/bin/sh",
"testuser2:x:1003:1004::/home/testuser2:/bin/sh",
"testuser3:x:1004:1005::/home/testuser3:/bin/sh",
"testuser4:x:1005:1006::/home/testuser4:/bin/sh",
"testuser5:x:1006:1007::/home/testuser5:/bin/sh",
"testuser6:x:1007:1008::/home/testuser6:/bin/sh",
"testuser7:x:1008:1009::/home/testuser7:/bin/sh",
"testuser8:x:1009:1010::/home/testuser8:/bin/sh",
"testuser9:x:1010:1011::/home/testuser9:/bin/sh",
"testuser10:x:1011:1012::/home/testuser10:/bin/sh"
]
}
TASK [생성된 사용자 삭제] *************************************************************************************************************************************************************************
changed: [desktop-linux] => (item=1)
changed: [desktop-linux] => (item=2)
changed: [desktop-linux] => (item=3)
changed: [desktop-linux] => (item=4)
changed: [desktop-linux] => (item=5)
changed: [desktop-linux] => (item=6)
changed: [desktop-linux] => (item=7)
changed: [desktop-linux] => (item=8)
changed: [desktop-linux] => (item=9)
changed: [desktop-linux] => (item=10)
PLAY RECAP ****************************************************************************************************************************************************************************************
desktop-linux : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
5. loop 반복문 중 sequence 를 이용하여 /var/log/test1 ~ /var/log/test100 100개 파일(file 모듈)을 생성 확인 후 삭제
loop.yml 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
---
- hosts: tnode1
gather_facts: no
tasks:
- name: 100개의 테스트파일 작성 (test1 ~ test100)
ansible.builtin.file:
path: "/var/log/test"
state: touch
mode: '0644'
loop: ""
- name: 생성 확인
ansible.builtin.shell: |
ls -la /var/log/test[0-9]* | wc -l
register: file_count
- name: 파일 갯수 표시
ansible.builtin.debug:
msg: "Total files created: "
- name: 생성된 파일 리스트업
ansible.builtin.shell: ls -la /var/log/test[0-9]*
register: file_list
- name: 파일 리스트 표시
ansible.builtin.debug:
msg: ""
- name: 100개의 테스트파일 삭제 (test1 ~ test100)
ansible.builtin.file:
path: "/var/log/test"
state: absent
loop: ""
- name: 삭제 확인
ansible.builtin.shell: |
ls /var/log/test[0-9]* 2>/dev/null | wc -l || echo "0"
register: remaining_files
- name: 삭제 후에 남은 파일 갯수 표시
ansible.builtin.debug:
msg: "Remaining files: "
실행하기
1
ansible-playbook loop.yaml
결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
PLAY [tnode1] ******************************************************************
TASK [100개의 테스트파일 작성 (test1 ~ test100)] *******************************
changed: [tnode1] => (item=1)
changed: [tnode1] => (item=2)
changed: [tnode1] => (item=3)
...
changed: [tnode1] => (item=99)
changed: [tnode1] => (item=100)
TASK [생성 확인] ***************************************************************
changed: [tnode1]
TASK [파일 갯수 표시] **********************************************************
ok: [tnode1] => {
"msg": "Total files created: 100"
}
TASK [생성된 파일 리스트업] ****************************************************
changed: [tnode1]
TASK [파일 리스트 표시] *******************************************************
ok: [tnode1] => {
"msg": [
"-rw-r--r-- 1 root root 0 Jan 17 17:11 /var/log/test1",
"-rw-r--r-- 1 root root 0 Jan 17 17:11 /var/log/test10",
"-rw-r--r-- 1 root root 0 Jan 17 17:11 /var/log/test100",
....
"-rw-r--r-- 1 root root 0 Jan 17 17:11 /var/log/test98",
"-rw-r--r-- 1 root root 0 Jan 17 17:11 /var/log/test99"
]
}
TASK [100개의 테스트파일 삭제 (test1 ~ test100)] ***************************************************
changed: [tnode1] => (item=1)
changed: [tnode1] => (item=2)
...
changed: [tnode1] => (item=99)
changed: [tnode1] => (item=100)
TASK [삭제확인] *********************************************************
changed: [tnode1]
TASK [삭제 후에 남은 파일 갯수 표시] *****************************
ok: [tnode1] => {
"msg": "Remaining files: 0"
}
PLAY RECAP *********************************************************************
tnode1 : ok=8 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
6. Ubuntu OS이면서 fqdn으로 tnode1인 경우, debug 모듈을 사용하여 OS정보와 fqdn 정보를 출력해보자.
condtion.yaml
1
2
3
4
5
6
7
8
9
10
---
- hosts: all
tasks:
- name: Print OS version and FQDN for Ubuntu on tnode1
ansible.builtin.debug:
msg: >-
OS Version:
FQDN:
when: ansible_facts['distribution'] == "Ubuntu" and ansible_facts['fqdn'] == "tnode1"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PLAY [all] ***************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************
ok: [tnode2]
ok: [tnode1]
ok: [tnode3]
TASK [Print OS version and FQDN for Ubuntu on tnode1] ********************************************************************************
ok: [tnode1] => {
"msg": "OS Version: 24.04 FQDN: tnode1"
}
skipping: [tnode2]
skipping: [tnode3]
PLAY RECAP ***************************************************************************************************************************
tnode1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode2 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
tnode3 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
tnode1에 Ubuntu OS일 경우에만 FQDN 과 OS 버전 출력
7. 반복문+조건문을 함께 사용
아래의 여러 서비스들의 상태를 체크하는 시나리오를 구성한다.
- rsyslog
- ssh
- cron
- nginx
여러 서비스를 반복으로 체크하면서 Active상태와 Inactive상태의 서비스를 분류하여 출력한다.
첫번째 task에서 의 ``은 loop의 값
systemctl is-active rsyslog,systemctl is-active ssh,systemctl is-active cron,systemctl is-active nginx
두번째 이후에서의 `` 은 결과 객체 전체
item.item = "rsyslog"item.rc =0item.stdout = "active"```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
---
- hosts: all
tasks:
- name: Check multiple services status
ansible.builtin.command: systemctl is-active
register: service_result
loop:
- rsyslog
- ssh
- cron
- nginx
failed_when: false
- name: Print active services only
ansible.builtin.debug:
msg: "✓ is ACTIVE"
loop: ""
when: item.rc == 0
- name: Print inactive services only
ansible.builtin.debug:
msg: "✗ is INACTIVE"
loop: ""
when: item.rc != 0
- name: Create files for active services
ansible.builtin.file:
path: "/tmp/_active.txt"
state: touch
loop: ""
when: item.rc == 0
전체 결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
PLAY [all] *********************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************
ok: [tnode2]
ok: [tnode1]
ok: [tnode3]
TASK [Check multiple services status] ******************************************************************************************************************************************
changed: [tnode2] => (item=rsyslog)
changed: [tnode1] => (item=rsyslog)
changed: [tnode3] => (item=rsyslog)
changed: [tnode2] => (item=ssh)
changed: [tnode1] => (item=ssh)
changed: [tnode3] => (item=ssh)
changed: [tnode2] => (item=cron)
changed: [tnode1] => (item=cron)
changed: [tnode3] => (item=cron)
changed: [tnode2] => (item=nginx)
changed: [tnode1] => (item=nginx)
changed: [tnode3] => (item=nginx)
TASK [Print active services only] **********************************************************************************************************************************************
ok: [tnode1] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'rsyslog'], 'start': '2026-01-17 18:05:20.410656', 'end': '2026-01-17 18:05:20.415111', 'delta': '0:00:00.004455', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active rsyslog', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'rsyslog', 'ansible_loop_var': 'item'}) => {
"msg": "✓ rsyslog is ACTIVE"
}
ok: [tnode1] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'ssh'], 'start': '2026-01-17 18:05:20.580505', 'end': '2026-01-17 18:05:20.583767', 'delta': '0:00:00.003262', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active ssh', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'ssh', 'ansible_loop_var': 'item'}) => {
"msg": "✓ ssh is ACTIVE"
}
ok: [tnode1] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'cron'], 'start': '2026-01-17 18:05:20.744792', 'end': '2026-01-17 18:05:20.749811', 'delta': '0:00:00.005019', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active cron', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'cron', 'ansible_loop_var': 'item'}) => {
"msg": "✓ cron is ACTIVE"
}
skipping: [tnode1] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 4, 'cmd': ['systemctl', 'is-active', 'nginx'], 'start': '2026-01-17 18:05:20.928411', 'end': '2026-01-17 18:05:20.931765', 'delta': '0:00:00.003354', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active nginx', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'nginx', 'ansible_loop_var': 'item'})
ok: [tnode2] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'rsyslog'], 'start': '2026-01-17 18:05:15.666178', 'end': '2026-01-17 18:05:15.670913', 'delta': '0:00:00.004735', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active rsyslog', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'rsyslog', 'ansible_loop_var': 'item'}) => {
"msg": "✓ rsyslog is ACTIVE"
}
ok: [tnode3] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'rsyslog'], 'start': '2026-01-17 18:06:26.930817', 'end': '2026-01-17 18:06:26.936322', 'delta': '0:00:00.005505', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active rsyslog', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'rsyslog', 'ansible_loop_var': 'item'}) => {
"msg": "✓ rsyslog is ACTIVE"
}
skipping: [tnode3] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 3, 'cmd': ['systemctl', 'is-active', 'ssh'], 'start': '2026-01-17 18:06:27.119490', 'end': '2026-01-17 18:06:27.123240', 'delta': '0:00:00.003750', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active ssh', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'ssh', 'ansible_loop_var': 'item'})
ok: [tnode2] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'ssh'], 'start': '2026-01-17 18:05:15.832998', 'end': '2026-01-17 18:05:15.835944', 'delta': '0:00:00.002946', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active ssh', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'ssh', 'ansible_loop_var': 'item'}) => {
"msg": "✓ ssh is ACTIVE"
}
skipping: [tnode3] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 3, 'cmd': ['systemctl', 'is-active', 'cron'], 'start': '2026-01-17 18:06:27.297196', 'end': '2026-01-17 18:06:27.302521', 'delta': '0:00:00.005325', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active cron', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'cron', 'ansible_loop_var': 'item'})
skipping: [tnode3] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 3, 'cmd': ['systemctl', 'is-active', 'nginx'], 'start': '2026-01-17 18:06:27.490843', 'end': '2026-01-17 18:06:27.494603', 'delta': '0:00:00.003760', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active nginx', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'nginx', 'ansible_loop_var': 'item'})
ok: [tnode2] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'cron'], 'start': '2026-01-17 18:05:15.999171', 'end': '2026-01-17 18:05:16.003635', 'delta': '0:00:00.004464', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active cron', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'cron', 'ansible_loop_var': 'item'}) => {
"msg": "✓ cron is ACTIVE"
}
skipping: [tnode2] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 4, 'cmd': ['systemctl', 'is-active', 'nginx'], 'start': '2026-01-17 18:05:16.182983', 'end': '2026-01-17 18:05:16.186214', 'delta': '0:00:00.003231', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active nginx', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'nginx', 'ansible_loop_var': 'item'})
TASK [Print inactive services only] ********************************************************************************************************************************************
skipping: [tnode1] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'rsyslog'], 'start': '2026-01-17 18:05:20.410656', 'end': '2026-01-17 18:05:20.415111', 'delta': '0:00:00.004455', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active rsyslog', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'rsyslog', 'ansible_loop_var': 'item'})
skipping: [tnode1] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'ssh'], 'start': '2026-01-17 18:05:20.580505', 'end': '2026-01-17 18:05:20.583767', 'delta': '0:00:00.003262', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active ssh', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'ssh', 'ansible_loop_var': 'item'})
skipping: [tnode1] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'cron'], 'start': '2026-01-17 18:05:20.744792', 'end': '2026-01-17 18:05:20.749811', 'delta': '0:00:00.005019', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active cron', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'cron', 'ansible_loop_var': 'item'})
skipping: [tnode2] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'rsyslog'], 'start': '2026-01-17 18:05:15.666178', 'end': '2026-01-17 18:05:15.670913', 'delta': '0:00:00.004735', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active rsyslog', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'rsyslog', 'ansible_loop_var': 'item'})
skipping: [tnode2] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'ssh'], 'start': '2026-01-17 18:05:15.832998', 'end': '2026-01-17 18:05:15.835944', 'delta': '0:00:00.002946', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active ssh', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'ssh', 'ansible_loop_var': 'item'})
ok: [tnode1] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 4, 'cmd': ['systemctl', 'is-active', 'nginx'], 'start': '2026-01-17 18:05:20.928411', 'end': '2026-01-17 18:05:20.931765', 'delta': '0:00:00.003354', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active nginx', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'nginx', 'ansible_loop_var': 'item'}) => {
"msg": "✗ nginx is INACTIVE"
}
skipping: [tnode2] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'cron'], 'start': '2026-01-17 18:05:15.999171', 'end': '2026-01-17 18:05:16.003635', 'delta': '0:00:00.004464', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active cron', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'cron', 'ansible_loop_var': 'item'})
skipping: [tnode3] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'rsyslog'], 'start': '2026-01-17 18:06:26.930817', 'end': '2026-01-17 18:06:26.936322', 'delta': '0:00:00.005505', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active rsyslog', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'rsyslog', 'ansible_loop_var': 'item'})
ok: [tnode2] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 4, 'cmd': ['systemctl', 'is-active', 'nginx'], 'start': '2026-01-17 18:05:16.182983', 'end': '2026-01-17 18:05:16.186214', 'delta': '0:00:00.003231', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active nginx', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'nginx', 'ansible_loop_var': 'item'}) => {
"msg": "✗ nginx is INACTIVE"
}
ok: [tnode3] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 3, 'cmd': ['systemctl', 'is-active', 'ssh'], 'start': '2026-01-17 18:06:27.119490', 'end': '2026-01-17 18:06:27.123240', 'delta': '0:00:00.003750', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active ssh', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'ssh', 'ansible_loop_var': 'item'}) => {
"msg": "✗ ssh is INACTIVE"
}
ok: [tnode3] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 3, 'cmd': ['systemctl', 'is-active', 'cron'], 'start': '2026-01-17 18:06:27.297196', 'end': '2026-01-17 18:06:27.302521', 'delta': '0:00:00.005325', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active cron', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'cron', 'ansible_loop_var': 'item'}) => {
"msg": "✗ cron is INACTIVE"
}
ok: [tnode3] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 3, 'cmd': ['systemctl', 'is-active', 'nginx'], 'start': '2026-01-17 18:06:27.490843', 'end': '2026-01-17 18:06:27.494603', 'delta': '0:00:00.003760', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active nginx', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'nginx', 'ansible_loop_var': 'item'}) => {
"msg": "✗ nginx is INACTIVE"
}
TASK [Create files for active services] ****************************************************************************************************************************************
changed: [tnode3] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'rsyslog'], 'start': '2026-01-17 18:06:26.930817', 'end': '2026-01-17 18:06:26.936322', 'delta': '0:00:00.005505', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active rsyslog', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'rsyslog', 'ansible_loop_var': 'item'})
changed: [tnode2] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'rsyslog'], 'start': '2026-01-17 18:05:15.666178', 'end': '2026-01-17 18:05:15.670913', 'delta': '0:00:00.004735', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active rsyslog', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'rsyslog', 'ansible_loop_var': 'item'})
skipping: [tnode3] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 3, 'cmd': ['systemctl', 'is-active', 'ssh'], 'start': '2026-01-17 18:06:27.119490', 'end': '2026-01-17 18:06:27.123240', 'delta': '0:00:00.003750', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active ssh', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'ssh', 'ansible_loop_var': 'item'})
changed: [tnode1] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'rsyslog'], 'start': '2026-01-17 18:05:20.410656', 'end': '2026-01-17 18:05:20.415111', 'delta': '0:00:00.004455', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active rsyslog', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'rsyslog', 'ansible_loop_var': 'item'})
skipping: [tnode3] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 3, 'cmd': ['systemctl', 'is-active', 'cron'], 'start': '2026-01-17 18:06:27.297196', 'end': '2026-01-17 18:06:27.302521', 'delta': '0:00:00.005325', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active cron', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'cron', 'ansible_loop_var': 'item'})
skipping: [tnode3] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 3, 'cmd': ['systemctl', 'is-active', 'nginx'], 'start': '2026-01-17 18:06:27.490843', 'end': '2026-01-17 18:06:27.494603', 'delta': '0:00:00.003760', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active nginx', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'nginx', 'ansible_loop_var': 'item'})
changed: [tnode2] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'ssh'], 'start': '2026-01-17 18:05:15.832998', 'end': '2026-01-17 18:05:15.835944', 'delta': '0:00:00.002946', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active ssh', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'ssh', 'ansible_loop_var': 'item'})
changed: [tnode1] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'ssh'], 'start': '2026-01-17 18:05:20.580505', 'end': '2026-01-17 18:05:20.583767', 'delta': '0:00:00.003262', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active ssh', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'ssh', 'ansible_loop_var': 'item'})
changed: [tnode2] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'cron'], 'start': '2026-01-17 18:05:15.999171', 'end': '2026-01-17 18:05:16.003635', 'delta': '0:00:00.004464', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active cron', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'cron', 'ansible_loop_var': 'item'})
changed: [tnode1] => (item={'changed': True, 'stdout': 'active', 'stderr': '', 'rc': 0, 'cmd': ['systemctl', 'is-active', 'cron'], 'start': '2026-01-17 18:05:20.744792', 'end': '2026-01-17 18:05:20.749811', 'delta': '0:00:00.005019', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active cron', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['active'], 'stderr_lines': [], 'failed': False, 'failed_when_result': False, 'item': 'cron', 'ansible_loop_var': 'item'})
skipping: [tnode2] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 4, 'cmd': ['systemctl', 'is-active', 'nginx'], 'start': '2026-01-17 18:05:16.182983', 'end': '2026-01-17 18:05:16.186214', 'delta': '0:00:00.003231', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active nginx', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'nginx', 'ansible_loop_var': 'item'})
skipping: [tnode1] => (item={'changed': True, 'stdout': 'inactive', 'stderr': '', 'rc': 4, 'cmd': ['systemctl', 'is-active', 'nginx'], 'start': '2026-01-17 18:05:20.928411', 'end': '2026-01-17 18:05:20.931765', 'delta': '0:00:00.003354', 'failed': False, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'systemctl is-active nginx', '_uses_shell': False, 'expand_argument_vars': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'cmd': None, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['inactive'], 'stderr_lines': [], 'failed_when_result': False, 'failed_when_suppressed_exception': '(traceback unavailable)', 'item': 'nginx', 'ansible_loop_var': 'item'})
PLAY RECAP *********************************************************************************************************************************************************************
tnode1 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode2 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode3 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
8. apache2 패키지를 apt 모듈을 통해서 설치 시, 핸들러를 호출하여 service 모듈로 apache2를 재시작해보자
apt cache를 업데이트 한 후 apache2 패키지를 인스톨한다.
다만 handler의 경우 요청하는 태스크의 변화가 있을시에만 호출되므로 처음 실행에 정상적으로 인스톨이 되었다면 다음 작업부터는 이미 apache2가 정상적으로 인스톨 되어있으므로 핸들러가 호출되지 않는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---
- hosts: tnode1
tasks:
- name: Update apt cache
ansible.builtin.apt:
update_cache: yes
cache_valid_time: 3600
- name: Install apache2 package
ansible.builtin.apt:
name: apache2
state: present
notify:
- Restart Apache2
handlers:
- name: Restart Apache2
ansible.builtin.service:
name: apache2
state: restarted
enabled: yes
결과 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PLAY [tnode1] ******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [tnode1]
TASK [Update apt cache] ********************************************************
ok: [tnode1]
TASK [Install apache2 package] *************************************************
changed: [tnode1]
RUNNING HANDLER [Restart Apache2] **********************************************
changed: [tnode1]
PLAY RECAP *********************************************************************
tnode1 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
9. block rescure always 키워드를 사용한 플레이북을 작성하여 테스트
block
Print a message실행 : 정상 실행됨Force a failure실행 : 실패하였으므로rescue로 넘어감Never print this: 위의Force a failure태스크에서 실패하였으므로 절대 실행하지 않음
rescue
Print when errors실행Force a failure in middle of recovery! >:-): 실패- ‘Never print this’ : 마찬가지로 위의 태스크가 실패하였으므로 절대 실행하지 않음
always
Always do this: 위 태스크의 실패여부와 상관없이 항상 실행됨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
PLAY [tnode1] ************************************************************************************
TASK [Gathering Facts] ***************************************************************************
ok: [tnode1]
TASK [Print a message] ***************************************************************************
ok: [tnode1] => {
"msg": "I execute normally"
}
TASK [Force a failure] ***************************************************************************
[ERROR]: Task failed: Module failed: non-zero return code
Origin: /root/my-ansible/check-service.yml:11:10
9 msg: 'I execute normally'
10
11 - name: Force a failure
^ column 10
fatal: [tnode1]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.002073", "end": "2026-01-17 18:44:06.124415", "msg": "non-zero return code", "rc": 1, "start": "2026-01-17 18:44:06.122342", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
TASK [Print when errors] *************************************************************************
ok: [tnode1] => {
"msg": "I caught an error"
}
TASK [Force a failure in middle of recovery! >:-)] ***********************************************
[ERROR]: Task failed: Module failed: non-zero return code
Origin: /root/my-ansible/check-service.yml:22:10
20 msg: 'I caught an error'
21
22 - name: Force a failure in middle of recovery! >:-)
^ column 10
fatal: [tnode1]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.001170", "end": "2026-01-17 18:44:06.296525", "msg": "non-zero return code", "rc": 1, "start": "2026-01-17 18:44:06.295355", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
TASK [Always do this] ****************************************************************************
ok: [tnode1] => {
"msg": "This always executes"
}
PLAY RECAP ***************************************************************************************
tnode1 : ok=4 changed=0 unreachable=0 failed=1 skipped=0 rescued=1 ignored=0
10. 앤서블 갤럭시에서 롤을 사용하는 플레이북을 만들어서 롤을 통한 애플리케이션을 배포
레디스 롤 배포해보기
롤 가져오기 (-p 옵션으로 롤이 설치될 디렉터리 경로 지정)
1
ansible-galaxy role install -p roles geerlingguy.redis
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
tree roles
roles
└── geerlingguy.redis
├── defaults
│ └── main.yml
├── handlers
│ └── main.yml
├── LICENSE
├── meta
│ └── main.yml
├── molecule
│ └── default
│ ├── converge.yml
│ └── molecule.yml
├── README.md
├── tasks
│ ├── main.yml
│ ├── setup-Archlinux.yml
│ ├── setup-Debian.yml
│ └── setup-RedHat.yml
├── templates
│ └── redis.conf.j2
└── vars
├── Archlinux.yml
├── Debian.yml
└── RedHat.yml
10 directories, 15 files
/roles/tasks/main.yml 확인해보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
---
# Variable setup.
- name: Include OS-specific variables.
include_vars: ".yml"
- name: Define redis_package.
set_fact:
redis_package: ""
when: redis_package is not defined
- name: Ensure Redis configuration dir exists.
file:
path: ""
state: directory
mode: ""
- name: Ensure Redis is configured.
template:
src: redis.conf.j2
dest: ""
mode: ""
notify: restart redis
# Setup/install tasks.
- include_tasks: setup-RedHat.yml
when: ansible_os_family == 'RedHat'
- include_tasks: setup-Debian.yml
when: ansible_os_family == 'Debian'
- include_tasks: setup-Archlinux.yml
when: ansible_os_family == 'Archlinux'
- name: Ensure Redis is running.
service:
name: ""
state: started
enabled: ""
role-example.yml 생성
1
2
3
4
5
---
- hosts: tnode1
roles:
- geerlingguy.redis
설치 실행
1
ansible-playbook role-example.yml
결과 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
PLAY [tnode1] *************************************************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************************************************
ok: [tnode1]
TASK [geerlingguy.redis : Include OS-specific variables.] *****************************************************************************************************************
ok: [tnode1]
TASK [geerlingguy.redis : Define redis_package.] **************************************************************************************************************************
ok: [tnode1]
TASK [geerlingguy.redis : Ensure Redis configuration dir exists.] *********************************************************************************************************
changed: [tnode1]
TASK [geerlingguy.redis : Ensure Redis is configured.] ********************************************************************************************************************
changed: [tnode1]
TASK [geerlingguy.redis : include_tasks] **********************************************************************************************************************************
skipping: [tnode1]
TASK [geerlingguy.redis : include_tasks] **********************************************************************************************************************************
included: /root/my-ansible/roles/geerlingguy.redis/tasks/setup-Debian.yml for tnode1
TASK [geerlingguy.redis : Ensure Redis is installed.] *********************************************************************************************************************
changed: [tnode1]
TASK [geerlingguy.redis : include_tasks] **********************************************************************************************************************************
skipping: [tnode1]
TASK [geerlingguy.redis : Ensure Redis is running.] ***********************************************************************************************************************
ok: [tnode1]
RUNNING HANDLER [geerlingguy.redis : restart redis] ***********************************************************************************************************************
changed: [tnode1]
PLAY RECAP ****************************************************************************************************************************************************************
tnode1 : ok=9 changed=4 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
설치확인
1
ssh tnode1 systemctl status redis
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.













