ENCORE CLOUD ARCHITECTURE TIL 4/9 Ansible 작업 제어

신민창·2021년 4월 11일
0

TIL

목록 보기
39/46

작업제어

반복문, 조건문, 핸들러, 오류 처리 등

반복문

# 반복문 사용 방식
---
- name: service start
  hosts: webservers
  become: true
  tasks:
    - name: install service httpd, mariadb-server
      yum:
        name:
          - httpd
          - mariadb-server
        state: latest
    - name: start service httpd
      service:
        name: httpd
        state: started
    - name: start service mariadb
      service:
        name: mariadb
        state: started
---
- name: service start
  hosts: webservers
  become: true
  tasks:
    - name: install service httpd, mariadb-server
      yum:
        name:
          - httpd
          - mariadb-server
        state: latest
    - name: start service httpd
      service:
        name: "{{ item }}"
        state: started
      loop:
        - httpd
        - mariadb
---
- name: service start
  hosts: webservers
  become: true
  vars:
    services:
      - httpd
      - mariadb
  tasks:
    - name: install service httpd, mariadb-server
      yum:
        name:
          - httpd
          - mariadb-server
        state: latest
    - name: start service httpd
      service:
        name: "{{ item }}"
        state: started
      loop: "{{ services }}"
---
- name: service start
  hosts: webservers
  become: true
  vars:
    svcpkg:
      - service: httpd
        package: httpd
      - service: mariadb
        package: mariadb-server
  tasks:
    - name: install service httpd, mariadb-server
      yum:
        name: "{{ item.package }}"
        state: latest
      loop: "{{ svcpkg }}"
    - name: start service httpd
      service:
        name: "{{ item.service }}"
        state: started
      loop: "{{ svcpkg }}"

반복문 + register

# 반복문을 사용하여 register 로 결과 저장시 결과 물 또한 배열 형태로 모두 저장됨
---
- name: loop register test
  hosts: webservers
  tasks:
    - name: Echo with loop
      shell: "echo Hello {{ item }}!"
      loop:
        - Kim
        - Park
        - Lee
      register: result
    - name: print result
      debug:
        var: result
---
- name: loop register test
  hosts: webservers
  tasks:
    - name: Echo with loop
      shell: "echo Hello {{ item }}!"
      loop:
        - Kim
        - Park
        - Lee
      register: result
    - name: print result
      debug:
        var: result['results'][0]['rc']

실습

webservers에 설치할 패키지: httpd, firewalld
webservers에 구동할 서비스: httpd, firewalld

dbservers에 설치할 패키지: mariadb-server, firewalld
dbservers에 구동할 서비스: mariadb, firewalld

각 그룹별 그룹 변수 지정

$ cat group_vars/webservers 
svcpkg:
  - service: httpd
    package: httpd
  - service: firewalld
    package: firewalld
$ cat group_vars/dbservers 
svcpkg:
  - service: mariadb 
    package: mariadb-server
  - service: firewalld
    package: firewalld
---
- name: Install packaged and start services with each group vars
  hosts: webservers, dbservers
  become: true
  tasks:
    - name: Install package
      yum:
        name: "{{ item.package }}"
        state: latest
      loop: "{{ svcpkg }}"
    - name: Start service
      service:
        name: "{{ item.service }}"
        state: started
        enabled: true
      loop: "{{ svcpkg }}"

조건문

조건을 설정하여 작업의 수행 여부를 결정
팩트 정보를 사용하여 조건을 확인 경우가 많음
when 사용. 작업의 이름과 동일한 위치로 호출
name: when test
yum:
name: httpd
state: latest
when: <조건>
조건식 사용방법
연산자
산술비교 : ==, !=, >, <, >=, <=
문자열 비교 : ==
변수의 존재유무 : <변수> is defined, <변수> is not defined
bool 타입의 변수 : <변수>, not <변수>
목록 내의 항목 중 하나 : <변수> in <목록>
복수 조건 사용
논리합: <조건1> or <조건2>
논리곱: <조건1> and <조건2>
조건을 목록 형태로 작성 : and 조건으로 적용
when

  • <조건1>
  • <조건2>
    조건식 사용시 조건의 내용이 길어질 경우 다음 줄에 작성 가능
    when: >
    ( <조건1> or <조건2> ) and ( <조건3> or <조건4> )
    when: >
    ( <조건1> or
    <조건2> )
    and
    ( <조건3> or
    <조건4> )

조건식과 반복문 함께 사용
조건식에 item 사용시 loop에 지정된 항목을 가지고 와서 접근 가능
ex)
name: install package if enough space
yum:
name: package_name
state: latest
loop: “{{ ansible_facts.mounts }}”
when: item.mount == “/” and item.size_available > 1000000000

예시1: 패키지 설치 - yum 모듈을 사용해서 패키지를 설치 (redhat, centos, fedora)

---
- name: install package when true
  hosts: webservers
  become: true
  vars:
    os_list:
      - CentOS
      - RedHat
      - Fedora
  tasks:
    - name: yum install tree
      yum:
        name: tree
        state: latest
      when: ansible_distribution in os_list

예시2: 서비스 이름과 재시작여부를 포함하고 있는 변수를 사용하여 loop를 수행하고, 이 때 재시작여부 변수의 값에 따라 실행 여부 결정

---
- name: when test 2
  hosts: webservers
  become: true
  vars:
    svcs:
      - name: httpd
        restart: true
      - name: sshd
        restart: false
  tasks:
    - name: restart service
      service:
        name: "{{ item.name }}"
        state: restarted
      loop: "{{ svcs }}"
      when: item.restart

register 와 조건문을 함께 사용하여 command, shell 등의 모듈의 실행결과 판단

---
- name: service running check
  hosts: webservers
  become: true
  tasks:
    - name: check httpd service
      command: /usr/bin/systemctl is-active httpd.service
      ignore_errors: true
      register: result
    - name: start httpd
      service:
        name: httpd
        state: started
      when: result.rc != 0

핸들러 (Handler)

notify / handler 세트로 동작함
notify: 모듈 실행 시 changed 결과가 나올 경우 핸들러에 실행 통지
handler: 실행할 내용을 명시
핸들러 동작 특성
notify가 있는 위치에서 핸들러를 실행하는 것이 아님
notify는 핸들러를 사용할 것을 통지만 하고, 핸들러는 모든 task가 완료된 후에 실행
핸들러는 여러 차례 호출된다고 하더라도 한 번만 실행
핸들러가 여러 개 있고 여러 핸들러가 실행될 경우, 핸들러의 notify 순서와 무관하게 handler에 명시된 순서대로 실행

웹 서비스 설치
웹 서비스 컨텐츠 파일 복사
웹 서비스 설정 파일 복사
웹 서비스 재실행

웹 서비스 설치
웹 서비스 컨텐츠 파일 복사
웹 서비스 설정 파일 복사
웹 서비스 재실행 (설정 파일이 변경되면)

notify/handler 예시

---
- name: Web service
  hosts: webservers
  become: true
  tasks:
    - name: install httpd
      yum:
        name: httpd
        state: latest
    - name: copy contents
      copy:
        dest: /var/www/html/index.html
        content: "Hello World"
    - name: copy config file
      copy:
        src: ./httpd.conf
        dest: /etc/httpd/conf/httpd.conf
      notify:
        - restart httpd
  handlers:
    - name: restart httpd
      service:
        name: httpd
        state: restarted
---
- name: Web service
  hosts: webservers
  become: true
  tasks:
    - name: install httpd
      yum:
        name: httpd
        state: latest
    - name: copy contents
      copy:
        dest: /var/www/html/index.html
        content: "Hello World 3"
      notify: echo hello
    - name: copy config
      copy:
        content: "Hello World 3"
        dest: /tmp/httpd.conf
      notify:
        - restart httpd
  handlers:
    - name: restart httpd
      service:
        name: httpd
        state: restarted
    - name: echo hello
      debug:
        msg: "Hello"

작업 오류 처리

ignore_errors
에러 발생시 중지하지 않고 다음 작업을 실행하도록 진행
작업 내부에 사용

force_handlers
작업의 오류로 인해 플레이가 중지되더라도 트리거 된 핸들러는 실행하고 종료
작업 오류 시 즉시 중지됨(ignore_error와 다름)
플레이 내부에 사용

---
- name: Web service
  hosts: webservers
  become: true
  force_handlers: true
  tasks:
    - name: copy contents
      copy:
        dest: /var/www/html/index.html
        content: "Hello World 6"
      notify: echo hello
    - name: error
      yum:
        name: abcdefjhg
        state: latest
    - name: copy config
      copy:
        content: "Hello World 6"
        dest: /tmp/httpd.conf
      notify:
        - restart httpd
  handlers:
    - name: restart httpd
      service:
        name: httpd
        state: restarted
    - name: echo hello
      debug:
        msg: "Hello"

force_handlers: true 설정으로 에러 이전 까지 트리거된 핸들러는 에러로 종료된 이후에도 실행됨

changed_when

작업의 changed 여부를 직접 지정
조건을 만족할 경우 결과를 changed로 전달
조건을 만족하지 않을 경우 결과를 ok로 전달

---
- name: changed_when test
  hosts: webservers
  tasks:
    - name: copy file
      copy:
        content: "Hello World 1"
        dest: /tmp/helloworld
      changed_when: false

failed_when

작업의 failed 여부를 직접 지정
조건을 만족할 경우 결과를 failed로 전달

---
- name: failed when test
  hosts: webservers
  tasks:
    - name: sed command 1
      command: /usr/bin/sed -n '/root/p' /etc/passwd
    - name: sed command 2
      command: /usr/bin/sed -n '/abcdefg/p' /etc/passwd
---
- name: failed when test
  hosts: webservers
  tasks:
    - name: sed command 1
      command: /usr/bin/sed -n '/root/p' /etc/passwd
    - name: sed command 2
      command: /usr/bin/sed -n '/abcdefg/p' /etc/passwd
      register: result
      failed_when: result.stdout == ""

블록 처리

블록(Block)
처리가 되는 단위로 묶음
대표적으로 when의 조건을 사용할 경우
block / rescue / always 구조에서 사용
block : 실행할 내용
rescue : block 실행 중 오류 발생 시 실행할 내용
always : 무조건 실행될 내용

---
- name: block test
  hosts: webservers
  tasks:
    - name: install package
      block:
      - yum:
          name: httpd
          state: latest
      - name: start service
        service:
          name: httpd
          state: restarted
      when: ansible_facts.distribution == "CentOS"
---
- name: block rescue always test
  hosts: webservers
  tasks:
    - name: Block
      block:
      - name: echo hello 1
        debug:
          msg: "hello 1"
      rescue:
      - name: echo hello 2
        debug:
          msg: "hello 2"
      always:
      - name: echo hello 3
        debug:
          msg: "hello 3"
---
- name: block rescue always test
  hosts: webservers
  tasks:
    - name: Block
      block:
      - name: echo hello 1
        debug:
          msg: "hello 1"
      - name: failed task
        fail:
      rescue:
      - name: echo hello 2
        debug:
          msg: "hello 2"
      always:
      - name: echo hello 3
        debug:
          msg: "hello 3"

0개의 댓글