[A101] 4. Ansible 반복문, 조건문
cloudNet@ 팀의 가시다 님이 진행하는 앤서블 스터디 2주차 정리입니다.
지난번 포스팅 까지 앤서블의 플레이북, 모듈, 변수등에 대해서 학습했습니다.
이번 포스팅에서는 조건문과 반복문에 대해서 배워보겠습니다.
✅ 반복문
- Ansible Loops - 다음 링크 참고(앤서블 docs) https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html
Loops — Ansible Documentation
As of Ansible 2.8, you can get extended loop information using the extended option to loop control. This option will expose the following information. Note When using loop_control.extended more memory will be utilized on the control node. This is a result
docs.ansible.com
- 반복문은 IAC의 꽃이라고 할수 있습니다. 동일한 모듈을 재사용 할수 있기 때문에 동일한 작업을 여러번 불필요하게 수고하는 것을 피할 수 있습니다.
- 단순 반복문 : 특정 항목에 대한 작업을 반복 - item 변수, 변수 목록 지정
- loop 키워드를 작업에 추가하면 작업을 반복해야 하는 항목의 목록을 지정하여 사용합니다. 그리고 해당하는 값을 변수처럼 사용하려면 item 변수를 이용할 수 있습니다.
✅ 반복문 예제
1. 플레이북 작성
~/my-ansible/check-services1.yml
---
- hosts: all
tasks:
- name: Check sshd and rsyslog state
ansible.builtin.service:
name: "{{ item }}"
state: started
loop:
- sshd
- rsyslog
2. 플레이북 작성 후 동작확인
#
ansible-playbook check-services1.yml
...
TASK [Check sshd and rsyslog state] ****************************************************
ok: [tnode2] => (item=sshd)
ok: [tnode1] => (item=sshd)
ok: [tnode3] => (item=sshd)
ok: [tnode2] => (item=rsyslog)
ok: [tnode1] => (item=rsyslog)
ok: [tnode3] => (item=rsyslog)
...
✅ 도전과제 1.
linux user1~10(10명) 를 반복문을 통해서 생성 후 확인 후 삭제를 해보자
1. 플레이북 작성
---
- hosts: all
tasks:
- name: Create User {{ item }}
ansible.builtin.user:
name: "{{ 'testuser%01x' | format(item) }}"
state: present
loop: "{{ range(1, 10 + 1, 1)|list }}"
2. 플레이북 실행 후 확인
# 생성된 user을 확인함.
ubuntu@server:~/my-ansible$ for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tail -n 3 /etc/passwd; echo; done
>> tnode1 <<
user8:x:1008:1008::/home/user8:/bin/sh
user9:x:1009:1009::/home/user9:/bin/sh
user10:x:1010:1010::/home/user10:/bin/sh
>> tnode2 <<
user8:x:1008:1008::/home/user8:/bin/sh
user9:x:1009:1009::/home/user9:/bin/sh
user10:x:1010:1010::/home/user10:/bin/sh
>> tnode3 <<
user8:x:1008:1008::/home/user8:/bin/sh
user9:x:1009:1009::/home/user9:/bin/sh
user10:x:1010:1010::/home/user10:/bin/sh
3. 플레이북 삭제
---
- hosts: all
tasks:
- name: Remove the user {{ item }}
ansible.builtin.user:
name: "{{ 'testuser%01x' | format(item) }}"
state: absent
remove: yes
loop: "{{ range(1, 10 + 1, 1)|list }}"
4. 플레이북 삭제 후 확인
# user 확인
ubuntu@server:~/my-ansible$ for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tail -n 3 /etc/passwd; echo; done
>> tnode1 <<
_chrony:x:114:121:Chrony daemon,,,:/var/lib/chrony:/usr/sbin/nologin
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
>> tnode2 <<
_chrony:x:114:121:Chrony daemon,,,:/var/lib/chrony:/usr/sbin/nologin
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
>> tnode3 <<
_chrony:x:114:121:Chrony daemon,,,:/var/lib/chrony:/usr/sbin/nologin
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
✅ 도전과제 2.
루프 반복문 중 sequence 를 이용하여 /var/log/test1 ~ /var/log/test100 100개 파일(file 모듈)을 생성 확인 후 삭제를 해보자
Variables, Conditionals, Loops - Ansible Handbook
Just like any other Scripting or programming language we can use variable in ansible playbooks. Variables could store different values for different items. Variables help us to have shorter and more readable playbooks. Imagine we want to apply patches on h
borosan.gitbook.io
1. 플레이북 실행
---
- hosts: all
tasks:
- name: Create files
ansible.builtin.file:
path: /var/log/test{{ item }}
state: touch
with_sequence: start=1 end=100
2. 확인
$ ansible -m shell -a "ls -l /var/log/test100" all
tnode2 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Jan 17 22:44 /var/log/test100
tnode1 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Jan 17 22:44 /var/log/test100
tnode3 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Jan 17 22:44 /var/log/test100
3. 삭제 플레이북 실행
---
- hosts: all
tasks:
- name: Remove files
ansible.builtin.file:
path: /var/log/test{{ item }}
state: absent
with_sequence: start=1 end=100
✅ 조건문
- 앤서블은 조건문을 사용하여 특정 조건이 충족될 때 작업 또는 플레이를 실행할 수 있습니다.
- 예를 들면 호스트의 운영체제 버전에 해당하는 서비스를 설치
- 앤서블에서 조건문을 사용할 때는 플레이 변수, 작업 변수, 앤서블 팩트 등을 사용할 수 있습니다.
1. 플레이북 작성
~/my-ansible/when_task.yml
---
- hosts: localhost
vars:
run_my_task: true
tasks:
- name: echo message
ansible.builtin.shell: "echo test"
when: run_my_task
register: result
- name: Show result
ansible.builtin.debug:
var: result
2. 실행
#
ansible-playbook when_task.yml
...
TASK [echo message] ***************************************************************************************************************************************************************************
changed: [localhost]
...
3. 플레이북 변경
- run_my_task: false
---
- hosts: localhost
vars:
run_my_task: false
tasks:
- name: echo message
ansible.builtin.shell: "echo test"
when: run_my_task
register: result
- name: Show result
ansible.builtin.debug:
var: result
4. 실행
(건너뜀)
#
ansible-playbook when_task.yml
...
TASK [echo message] ***************************************************************************************************************************************************************************
skipping: [localhost]
...
✅ 조건문 연산자
- 조건 연산자 : when 문에 bool 변수(true, false) 외에도 조건 연산자를 사용할 수 있습니다.
- != : 값이 같지 않을 때 참 true
- >, >=, <=, < : ‘초과, ‘ 이상’, ‘이하’, ‘미만’ 일 때에 참 true
- not : 조건의 부정
- and, or : ‘그리고’, ‘또는’의 의미로 여러 조건의 조합 가능
- in : 값이 포함된 경우에 참 true. 예를 들어 2 in “1, 2, 3” 은 참 true
- is defined : 변수가 정의된 경우 참 true
✅ 조건문 연산자 예제 (Example)
1. 플레이북 작성
~/my-ansible/check-os.yml
---
- hosts: all
vars:
supported_distros:
- Ubuntu
- CentOS
tasks:
- name: Print supported os
ansible.builtin.debug:
msg: "This {{ ansible_facts['distribution'] }} need to use apt"
when: ansible_facts['distribution'] in supported_distros
2. 플레이북 실행
#
ansible-playbook check-os.yml
...
TASK [Print supported os] *********************************************************************************************************************************************************************
ok: [tnode1-ubuntu.local] => {
"msg": "This Ubuntu need to use apt"
}
ok: [tnode2-ubuntu.local] => {
"msg": "This Ubuntu need to use apt"
}
ok: [tnode3-ubuntu.local] => {
"msg": "This Ubuntu need to use apt"
}
✅ 조건문 도전과제 3
Ubuntu OS이면서 fqdn으로 tnode1 인 경우, debug 모듈을 사용하여 OS 정보와 fqdn 정보를 출력해보자
ansible_facts[' ' ] 안에는 굉장히 많은 Key.Value 값이 존재한다.
앤서블 서버와 tnode1,2,3에 대한 OS 정보 부터,커널 버전까지 굉장히 많은 정보들이 담겨 있다.
- 호스트 이름
- 커널 버전
- 네트워크 인터페이스 이름
- 운영체제 버전
- CPU 개수
- 사용 가능한 메모리
- 스토리지 장치의 크기 및 여유 공간
- 등등…
이중에서 fqdn과 distribution이라는 키값을 이용해서 조건문을 작성한다.
1. 플레이북 작성
---
- hosts: all
tasks:
- name: Print os type
ansible.builtin.debug:
msg: >-
fqdn: {{ ansible_facts['fqdn'] }}
OS: {{ ansible_facts['distribution'] }}
when:
- ansible_facts['fqdn'] == "ip-10-10-1-11.ap-northeast-2.compute.internal"
- ansible_facts['distribution'] == "Ubuntu"
2. 플레이북 실행
ansible-playbook check_os.yml
PLAY [all] *********************************************************************
TASK [Print os type] ***********************************************************
ok: [tnode1] => {
"msg": "fqdn: ip-10-10-1-11.ap-northeast-2.compute.internal OS: Ubuntu"
}
skipping: [tnode2]
skipping: [tnode3]
PLAY RECAP *********************************************************************
tnode1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode2 : ok=0 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
tnode3 : ok=0 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
✅ 핸들러
- 일부 작업에서 시스템을 변경 한 후에 추가 작업을 실행해야 할 수도 있습니다.
- 예를 들어 서비스의 구성 파일을 변경하려면 변경 내용이 적용되도록 서비스를 다시 로드해야 합니다.
- 이때 핸들러는 다른 작업에서 트리거한 알림에 응답하는 작업이며, 해당 호스트에서 작업이 변경될 때만 핸들러에 통지합니다.
✅ 핸들러 예제 Example
1. 플레이북 작성
~/my-ansible/handler-sample.ym
---
- hosts: tnode2
tasks:
- name: restart rsyslog
ansible.builtin.service:
name: "rsyslog"
state: restarted
notify:
- print msg
handlers:
- name: print msg
ansible.builtin.debug:
msg: "rsyslog is restarted"
#
ansible-playbook handler-sample.yml
...
TASK [restart rsyslog] **********************************************************************************************************************************************************************
changed: [tnode2-ubuntu.local]
RUNNING HANDLER [print msg] *****************************************************************************************************************************************************************
ok: [tnode2-ubuntu.local] => {
"msg": "rsyslog is restarted"
}
# 한번 더 실행 해보기
ansible-playbook handler-sample.yml