반복문과 조건문을 이용한 제어문 구현하기 - 조건문

728x90
반응형

출처 : 앤서블로 시작하는 인프라 자동화

 

 

조건문

  • 앤서블은 조건문을 사용하여 특정 조건이 충족될 때 작업 또는 플레이를 실행할 수 있다.
  • ex) 조건문을 사용하여 호스트의 운영체제 버전에 해당하는 서비스 설치
  • 앤서블에서 조건문을 사용할 때는 플레이 변수, 작업 변수, 앤서블 팩트 등을 사용할 수 있다.

 

 

조건 작업 구문

  • when 문은 조건부로 작업을 실행할 때 테스트할 조건을 값으로 사용한다.
  • 조건이 충족되면 작업이 실행되고, 조건이 충족되지 않으면 작업을 건너 뛴다.
  • when 문을 테스트하는 가장 간단한 조건 중 하나는 Boolean 변수가 true인지 false 인지의 여부이다.

 

vi when_task.yml

---

- hosts: localhost
  vars:
    run_my_task: true

  tasks:
    - name: echo message
      ansible.builtin.shell: "echo test"
      when: run_my_task

 

run_my_task 라는 변수에 true라는 값을 저장한다.

when 문에서 run_my_task를 사용하면 run_my_task가 true 인 경우에만 tasks가 실행된다.

 

ansible-playbook --syntax-check when_task.yml
ansible-playbook when_task.yml

 

vi when_task.yml

---

- hosts: localhost
  vars:
    run_my_task: false

  tasks:
    - name: echo message
      ansible.builtin.shell: "echo test"
      when: run_my_task

 

이번에는 run_my_task 변수를 false로 수정한다.

 

ansible-playbook when_task.yml

 

다시 플레이북을 실행해보면 이번에는 echo massage 태스크가 수행되지 않고 건너 뛴 것을 확인할 수 있다. 왜냐하면 when 문에서 run_my_task가 false 이기 때문이다.

 

 

조건 연산자

  • when 문을 사용할 때는 true 또는 false 값을 갖는 Bool 변수 외에도 조건 연산자를 사용할 수 있다.
  • ex) when 문에 ansible_facts['machine'] == "x86_64" 라는 구문을 사용했다면 ansible_facts['machine'] 값이 x86_64 일 때만 해당 태스크를 수행한다.
  • 운영체제 종류에 따라 태스크를 수행하는 예제를 통해 조건 연산자 사용법을 알아보자.

 

vi check-os.yml

---

- hosts: all
  vars:
    supported_distros:
      - CentOS
      - RedHat

  tasks:
    - name: Print supported os
      ansible.builtin.debug:
        msg: "This {{ ansible_facts['distribution'] }} need to use dnf"
      when: ansible_facts['distribution'] in supported_distros

 

vi 에디터로 check-os.yml 파일을 생성하고 위 코드를 작성한다.

 

vars 키워드로 supported_distros 라는 변수를 사전 타입의 값으로 저장한다. 그리고 태스크의 when 구문에서 ansible_facts['distribution'] in supported_distros 라는 조건문을 추가한다.

 

ansible-playbook check-os.yml

 

check-os.yml 플레이북을 실행한다.

실행하면 변수 supported_distros에 있는 centos인 tnode1-centos는 출력되지만, 변수에 없는 tnode2-ubuntu와 tnode2-ubuntu는 해당 태스크를 실행하지 않는다.

 

 

복수 조건문

  • 앤서블의 when 문은 단일 조건문 뿐만 아니라 복수 조건문도 사용할 수 있다.
  • ex) 운영체제가 CentOS이고 서버 타입이 x86_64일 경우에만 작업이 실행되게 구성 가능
  • 운영체제가 CentOS이거나 우분투일 경우 작업이 수행되는 예제를 통해 복수 조건문을 사용해 본다.

 

vi check_os1.yml

---

- hosts: all

  tasks:
    - name: Print os type
      ansible.builtin.debug:
        msg: "OS Type: {{ ansible_facts['distribution'] }}"
      when: ansible_facts['distribution'] == "CentOS" or ansible_facts['distribution'] == "Ubuntu"

 

check_os1.yml 파일을 생성하고 vi 에디터로 위 코드를 작성한다.

when 문에서는 ansible_facts['distribution'] 의 값이 CentOS 거나 Ubuntu일 경우에만 수행되도록 or 구문을 사용했다.

 

ansible-playbook check_os1.yml

 

플레이북을 실행하면 운영체제가 CentOS 거나 Ubuntu 일 경우 작업을 수행한다. 우리의 호스트들은 모두 CentOS거나 Ubuntu 이므로 모두 작업을 수행하게 된다.

 

vi check_os2.yml

---

- hosts: all

  tasks:
    - name: Print os type
      ansible.builtin.debug:
        msg: >
             OS Type: {{ ansible_facts['distribution'] }}
             OS Version: {{ ansible_facts['distribution_version'] }}
      when: ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_version'] == "8"

 

이번에는 when 문을 수정한다. ansible_facts['distribution']의 값이 CentOS고, ansible_fact['distribution_version'] 이 8인 경우에만 작업이 수행되도록 and 연산자를 사용한다.

 

즉, 현재 시스템의 운영체제가 CentOS 8 인 경우에만 작업을 수행한다.

 

ansible-playbook check_os2.yml


플레이북을 실행하면 CentOS 8 인 tnode1-centos 만 작업을 수행하고 나머지 호스트들은 작업을 건너 뛰게 된다.

 

vi check_os3.yml

---

- hosts: all

  tasks:
    - name: Print os type
      ansible.builtin.debug:
        msg: >
             OS Type: {{ ansible_facts['distribution'] }}
             OS Version: {{ ansible_facts['distribution_version'] }}
      when:
        - ansible_facts['distribution'] == "CentOS"
        - ansible_facts['distribution_version'] == "8"

 

and 연산자는 조건문에서 바로 사용하거나 사전 형태의 목록으로 표현하는 방법 2가지가 있다.

 

ansible-playbook check_os3.yml

 

플레이북을 실행해보면 위의 플레이북과 동일한 결과를 출력하는 것을 확인할 수 있다.

 

vi check_os4.yml

---

- hosts: all

  tasks:
    - name: Print os type
      ansible.builtin.debug:
        msg: >
             OS Type: {{ ansible_facts['distribution'] }}
             OS Version: {{ ansible_facts['distribution_version'] }}
      when: >
          ( ansible_facts['distribution'] == "CentOS" and
            ansible_facts['distribution_version'] == "8")
          or
          ( ansible_facts['distribution'] == "Ubuntu" and
            ansible_facts['distribution'] == "20.04" )

 

when 문에서는 and 연산자와 or 연산자를 함께 사용할 수 있다.

운영체제가 CentOS 8 이거나 Ubuntu 20.04 인 경우에만 작업을 수행하도록 만들어보자.

 

ansible-playbook check_os4.yml

 

플레이북을 실행하면 tnode1-centos 만 작업을 수행한다.

tnode2-ubuntu와 tnode3-ubuntu의 버전은 22.04 이기 때문에 skip 된다.

 

 

반복문과 조건문 사용

  • 반복문과 조건문을 함께 사용할 수 있다.

 

vi check_mount.yml

---

- hosts: db

  tasks:
    - name: Print Root Directory Size
      ansible.builtin.debug:
        msg: "Directory {{ item.mount }} size is {{ item.size_available }}"
      loop: "{{ ansible_facts['mounts'] }}"
      when: item['mount'] == "/" and item['size_available'] > 300000000

 

vi 에디터로 check_mount.yml 파일을 생성하고 위 코드를 작성한다.

when 문의 item['mount'] 는 loop 문에서 선언한 ansible_facts의 mounts 중 mount 라는 값과 size_available 이라는 값을 사용해 구현한 것이다.

 

즉, db 호스트(tnode3-ubuntu)에서 mount의 속성이 '/' 이고, size_available 속성이 300000000 보다 큰 경우에만 해당 작업을 수행한다.

 

ansible-playbook check_mount.yml

 

플레이북을 실행하면 앤서블 팩트에서 mounts 라는 사전 타입의 변수값을 반복하면서 mount가 '/' 이고 size_available 값이 300000000 보다 큰 경우에만 메시지를 출력하고, 그렇지 않으면 건너 뛴다.

 

vi register-when.yml

---

- hosts: all

  tasks:
    - name: Get rsyslog service status
      ansible.builtin.command: systemctl is-active rsyslog
      register: result

    - name: Print rsyslog status
      ansible.builtin.debug:
        msg: "Rsyslog status is {{ result.stdout }}"
      when: result.stdout == "active"

 

조건문을 사용할 때는 반복문 뿐만 아니라 register 키워드로 작업 변수도 사용할 수 있다.

 

systemctl 명령어로 rsyslog가 active 인지 체크하여 해당 결과를 result에 저장하고, Print rsyslog status 태스크에서 result.stdout 값이 active 일 경우 해당 값을 출력하는 코드이다.

 

ansible-playbook register-when.yml

 

해당 플레이북을 실행하면 각 호스트의 rsyslog 상태를 확인하고 해당 결과를 출력한다.

728x90
반응형