mingming

Ansible - 반복문 & 조건문 본문

새싹 하이브리드 클라우드/Ansible

Ansible - 반복문 & 조건문

mingming_96 2023. 11. 19. 01:13

Ansible 반복문

반복문에서 제공되는 목록을 참조하는 변수명은 항상 item 입니다. 

---
- name: add several users
  user:
    name: "{{ item }}"
    state: present
    groups: "wheel"
  loop:
    - testuser1
    - testuser2

 

반복문에 변수 참조 

---
- hosts: webserver
  vars:
    user_list: [ 'testuser1', 'testuser2']
  tasks:
    - name: add several users
      user:
        name: "{{ item }}"
        staste: present
        groups: "wheel"
      loop:
      - "{{ user_list }}"

 

매개변수에 목록을 직접 전달 

apt, yum 등 패키지 관련 모듈에선 매개변수에 목록을 직접 전달 할 수 있습니다. 

---
- hosts: install list of packages
  vars:
    list_of_packages: [ 'apache2', 'mode_ssl' ]
  become: yes
  tasks:
    - name: optimal yum 
      apt:
        name: "{{ list_of_packages }}"
        state: present
        
### apt install apache2, mod_ssl    
 
    - name: non optimal yum
      apt:
        name: "{{ item }}"
        state: present
      loop: "{{ list_of_packages }}"
      
### apt install apache2 ; apt install mod_ssh

 

딕셔너리 참조

---
    - name: add several users
      user:
        name: "{{ item.name }}"
        state: present
        groups: "{{ item.groups }}"
      loop:
        - { name: 'testuser1', groups: 'wheel' }
        - { name: 'testuser2', groups: 'root' }

 

 

Ansible 조건문 

when절을 이용해 해당 조건이 참인지 거짓인지 판별 후 작업을 수행하게 됩니다.

조건문서 변수를 참조하더라도 변수명에 {{  }} 이중 중괄호를 사용하지 않습니다.   

---
- name: boolean test
  hosts: worker 
  become: yes
  vars:
    - run_mny_task: true
  tasks:
    - name: mariadb is stopped
      service:
        name: mariadb
        state: stopped
      when: "{{ run_my_task }}"
      
  
위의 플레이북을 실행하게 되면 아래와 같은 경고 메세지가 출력됩니다. jinja2 템플릿을 사용할 수 없다는 내용입니다.
[WARNING]: conditional statements should not include jinja2 templating
delimiters such as {{ }} or {% %}. Found: {{ run_my_task }}


---
- name: boolean test
  hosts: worker
  become: yes
  remote_user: slave
  vars:
    - my_service: mariadb
  tasks:
    - name: mariadb is started
      service:
        name: mariadb
        state: started
      when: my_service is defined

 

 

조건문 연산자

A==B          A 와 B는 같다 
A=="B"        A 와 B 는 같다 ( 문자열 )

A < B         A 가 B 보다 작다
A > B         A 가 B 보다 크다
A <= B        A가 B보다 크거나 같다
A >= B        A가 B보다 크거나 같다
A != B        A 와 B는 다르다

A             A 가 1이거나 True면 실행
NOT A         A가 0이거나 False 면 실행
A in B        A가 B 안에 있으면 참
A not in B    A가 B 안에 없으면

 

 

IN 연산자를 사용한 플레이북

---
- name: Redhat in keyword
  gather_facts: yes
  become: yes
  hosts: worker
  remote_user: slave
  vars:
    supported_distros:
      - CentOS
      - Fedora
  tasks:
    - name: stopped mairadb using service, where supported
      service:
        name: mariadb
        state: stopped
      when: ansible_distribution in supported_distros

 

위의 플레이북에 사용된 ansible_distribution 변수는 팩트변수로 플레이북 실행 시 자동으로 수집되는 변수입니다. 

debug 모듈을 이용해 ansible_deistribution 변수를 확인해 보도록 하겠습니다.

---
- name: ansible_distributions
  hosts: local
  remote_user: master
  tasks:
    - name: debug ansible distribution
      debug:
        var: ansible_distribution
        
  
[master@master when]$ ansible-playbook debug.yaml

PLAY [ansible_distribution] ****************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [debug ansible distribution] **********************************************
ok: [localhost] => {
    "ansible_distribution": "CentOS"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

 

다중 조건문

---
- name: and or test
  hosts: worker
  remote_user: slave
  vars:
    - A: "a"
    - B: "b"
  tasks:
    - name: and test1
      debug:
        msg: >
          This is working
      when: A == "a" and B == "c"

    - name: and test2
      debug:
        msg: >
          This is working
      when: A == "a" and B == "b"

    - name: or test1
      debug:
        msg: >
          This is working
      when: A == "a" or B == "b"

    - name: or test2
      debug:
        msg: >
          This is working
      when: A == "b" or B == "c"

 

 

조건문과 반복문 함께 사용 

 

mariadb 와 httpd 재시작 

---
- name: httpd and mariadb restart
  hosts: worker
  become: yes
  remote_user: slave
  vars:
    A: "A"
    web_db:
      - httpd
      - mariadb
  tasks:
    - service:
        name: "{{ item }}"
        state: restarted
      loop: "{{ web_db }}"
      when: '"A" == "A"'

## 문자열과 문자열을 비교할 때는 작은 따옴표로 묶어줘야 함

 

mariadb 가 동작중이라면 재시작

---
- name:
  hosts: worker
  remote_user: slave
  become: yes
  tasks:
    - name: get mariadb server status
      command: /usr/bin/systemctl is-active mariadb
      register: mariadb_status
      ignore_errors: yes
      register: result  ## mariadb 의 상태를 확인 후 결과값저장  

    - name: check var result
      debug:
        var: result  ## result 값 확인 

    - name: mariadb restarted
      service:
        name: mariadb
        state: restarted
      when: result["rc"] == 0
            result.rc == 0
            result["stdout_lines"][0] == "active"  ## result 값과 비교해true or false 반환

 

result 값 확인 

TASK [check var result] ********************************************************
ok: [192.168.56.112] => {
    "result": {
        "changed": true,
        "cmd": [
            "/usr/bin/systemctl",
            "is-active",
            "mariadb"
        ],
        "delta": "0:00:00.004844",
        "end": "2023-11-02 01:29:16.523094",
        "failed": false,
        "rc": 0,
        "start": "2023-11-02 01:29:16.518250",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "active",
        "stdout_lines": [
            "active"
        ]
    }
}