본문 바로가기

Engineering/Ansible

[Ansible] 8. 반복문과 조건문을 이용한 제어문 구현

앤서블 플레이북에서도 loop 문과 when 문을 이용하여 반복문과 조건문을 구현할 수 있다.


반복문

앤서블에서는 loop 구문을 이용하여 작업을 반복하고, 반복 작업에서 추출한 변수를 item 변수에 담아 이용할 수 있다. 

 

 

제어노드의 sshd와 rsyslog 서비스 상태를 체크하는 플레이북을 작성해보자. sshd와 rsyslog를 ansible.builtin.service 모듈을 이용해 각각 실행하는 플레이북 예제이다. 

[root@Ansible-Controller ch07]# cat check-services.yml 
---
- hosts: all
  
  tasks:
  - name: Check sshd state
    ansible.builtin.service:
      name: sshd
      state: started

  - name: Check rsyslog state
    ansible.builtin.service:
      name: rsyslog
      state: started

 

 

 

위와 같이 동일한 두 개의 task를 수행하는 작업을 loop구문을 넣고, item 변수를 이용하여 다음과 같이 작성할 수 있다.

[root@Ansible-Controller ch07]# cat check-services1.yml 
---
- hosts: all

  tasks:
  - name: check services
    ansible.builtin.service:
      name: "{{ item }}"
      state: started
    
    loop:
      - sshd
      - rsyslog

loop 구문에서 선언한 배열들이 돌때마다 선언한 item 변수에 저장되고, 선언한 배열들이 다 돌게 되면 작업이 종료된다.

 

 

loop 구문에서 선언할 배열들 또한 플레이북 내에 변수로 정의할 수 있다. 아래는 services 라는 배열 형태의 변수를 정의하고, loop 구문에서 해당 변수를 호출하도록 설계한 플레이북이다.

[root@Ansible-Controller ch07]# cat check-services2.yml 
---
- hosts: all
  vars:
    services:
    - sshd
    - rsyslog

  tasks:
  - name: check services
    ansible.builtin.service:
      name: "{{ item }}"
      state: started
     
    loop: "{{ services }}"

사전 목록에 의한 반복문

여러 개의 아이템이 필요한 경우 loop 문에서 사전 목록으로 사용할 수 있다.

[root@Ansible-Controller ch07]# cat make-logfile.yml 
---
- hosts: all

  tasks:
  - name: make logfiles
    ansible.builtin.file:
      path: "{{ item['log-path'] }}"
      mode: "{{ item['log-mode'] }}"
      state: touch

    loop:
      - log-path: '/var/log/test1.log'
        log-mode: '0644'
      - log-path: '/var/log/test2.log'
        log-mode: '0600'
      - log-path: '/var/log/test3.log'
        log-mode: '0600'

Register 변수를 이용한 반복문

반복문의 작업 결과를 Register 변수에 담아 이를 출력하거나 사용할 수 있다.

---
- hosts: localhost

  tasks:
  - name: loop echo
    ansible.builtin.shell: "echo 'I can speak {{ item['lang'] }}' > {{ item['file'] }} "
    loop:
      - lang: Korean
        file: Korean.txt
      - lang: English
        file: English.txt
    register: result

  - name: display register result
    ansible.builtin.debug:
      var: result

 

register 키워드에 의해 저장된 result 에 key-value 쌍으로 구성된 결과 값들이 저장된다. 배열 형상으로 저장된 result 내의 results의 특정 값을 loop 문을 이용하여 추출 후, 사용할 수도 있다.

---
- hosts: localhost

  tasks:
  - name: loop echo
    ansible.builtin.shell: "echo 'I can speak {{ item['lang'] }}' "
    loop:
      - lang: 
          Korean
      - lang:
          English
    register: result

  - name: extract stdout value
    ansible.builtin.debug:
      msg: "{{ item.stdout }}"
    loop:
      "{{ result.results }}"

result내의 results 키 값을 loop문과 item 변수로 추출하여 stdout 값을 출력한 예시이다.

 


조건문

앤서블에서는 when문을 사용하여 조건에 따른 작업제어를 가능케한다.

 

 

when문을 이용하여 boolean 변수가 true 일때 실행되는 playbook을 작성해보자

---
- hosts: localhost
  vars:
    my_boolean: True


  tasks:
  - name: when test
    ansible.builtin.yum:
       name: httpd
       state: present
    when: my_boolean

my_boolean 이라는 변수의 값이 True이고, when 문에서 해당 변수를 참조해 playbook의 task가 실행되었다.

True -> False로 바꾸고 다시 실행해보자.

[root@Ansible-Controller ch07]# sed -i 's/True/False/g' when_01.yml 
---
- hosts: localhost
  vars:
    my_boolean: False


  tasks:
  - name: when test
    ansible.builtin.yum:
       name: httpd
       state: present
    when: my_boolean

when문이 False를 전달받아, Task가 스킵이 되었다.


조건 연산자

when 문에서 boolean 값 외에도 조건 연산자를 사용할 수 있다.

Ex Description
==, <=, != 등의 기본 연산자 사용가능
min_memory is defined 'min_memory'라는 변수가 있으면 True 반환
min_memory is not defined 'min_memory'라는 변수가 없으면 True 반환
memory_available memory 값이 true이면 true. 이때 값이 1, true, yes 등이면 true
not memory_available memory 값이 false면 true. 이때 값이 0, false, no 등이면 true
ansible_facts['distribution'] in supported_os ansible_facts['distribution'] 값이 supported_os 라는 변수에 존재하면 true

 

when 문에 조건 연산자를 이용한 플레이북을 작성해보자. ansible facts를 수집하여 제어노드의 OS가 Redhat, CentOS, Rocky 중 포함이 된다면 메세지를 표출하는 플레이북이다.

[root@Ansible-Controller ch07]# cat check-os.yml              
---
- hosts: all
  gather_facts: True
  vars: 
    supported_os:
      - Redhat
      - CentOS
      - Rocky

  tasks:
  - name: Print supported os
    ansible.builtin.debug:
      msg: "We ain't Ubuntu"
    when: ansible_facts['distribution'] in supported_os


복수 조건문

and 혹은 or 를 사용하여 조건문에 복수의 조건에 따른 작업제어를 할 수 있다.

[root@Ansible-Controller ch07]# cat check-os2.yml 
---
- hosts: all
  gather_facts: True
  vars: 
    supported_os:
      - Redhat
      - CentOS
      - Rocky
    hostname:
      - Rocky-UEFI
      

  tasks:
  - name: 'Print Redhat family && hostname: Rocky-UEFI'
    ansible.builtin.debug:
      msg: |
         'OS: "{{ ansible_facts.distribution }}" '
         'hostname: "{{ ansible_facts.hostname }}" '
    when: ansible_facts['distribution'] in supported_os and ansible_facts['hostname'] in hostname

 


반복문과 조건문 사용

when 문과 loop 문을 함께 사용하여 조건문과 반복문을 함께 사용할 수도 있다.

 

아래 예시는 반복문을 사용하여, ansible_facts 값 내의 mounts 중 mount 값과 size_available 값을 추출하고, 추출한 값에 조건 연산자를 달아 결과 값을 출력하는 플레이북이다.

---
- hosts: localhost
  
  tasks: 
  - name: Printing mounted directory bigger than 90000000000
    ansible.builtin.debug:
      msg: >
        "Directory: {{ item.mount }}, size: {{ item.size_available }}"

    loop: "{{ ansible_facts['mounts'] }}"
    when: item.size_available > 90000000000

'Engineering > Ansible' 카테고리의 다른 글

[Ansible]10. Ansible Role  (2) 2024.10.16
[Ansible] 9. 핸들러 및 작업 실패 처리  (2) 2024.10.02
[Ansible] 7. Ansible Facts 활용  (0) 2024.09.02
[Ansible] 6. Ansible Vault  (0) 2024.08.29
[Ansible] 5. 변수  (1) 2024.08.28