becool

20210730 (금) ansible 조건문, 블록, 핸들러 본문

ansible

20210730 (금) ansible 조건문, 블록, 핸들러

gusalstm 2021. 7. 30. 16:58
반응형

09:36 review

 

 Ansible Facts

   Ansible로 관리되는 관리 노드의 정보 (OS, NIC, IP주소, 디스크, CPU, 환경변수, 파일시스템 마운트 등)를 수집하여 저장하는 특수한 변수

   Play 실행 시 가장 먼저 Ansible Facts를 수집하며, gather_facts 를 통해 수집여부 결정.

  

 자주 사용되는 Ansible Facts

   ansible_facts['hostname'] ; short hostname

   ansible_facts['fqdn'] : FQDN hostname

   ansible_facts['default_ipv4']['address']

   ansible_facts['enp0s8']['ipv4']['address'] : 특정 NIC의 IP주소

   ansible_facts['interfaces'] : 시스템에 설치된 NIC

   ansible_facts['kernel']

   ansible_facts['distribution']

   ansible_facts['distribution']['version'] 

   ansible_facts['os_family'] : 운영체제 계열

 

Ansible Facts의 디렉터리 경로 : /etc/ansible/facts.d

  기본적으로 없는 디렉터리이므로 각 노드에 별도로 설치가 필요함

 

① 각 managed node 들에 useradd (ANSIBLE_USER), passwd 로 패스워드 지정

② 각 ANSIBLE_USER 들을 sudoers 파일에 NOPASSWD 권한 부여

[user@ansible-node03 ~]$ sudo cat /etc/sudoers |grep ansible
ansible_user ALL=(ALL) NOPASSWD:ALL

③ 각 ANSIBLE_USER 에게 키기반 인증 배포 (또는 ansbile -k 옵션을 계속 써야함)

[user@ansible-server work]$ ssh-copy-id ansible_user@192.168.56.13

④ custom.fact 작성

⑤ ansible-playbook (또는 ad-hoc명령) 통해서 디렉터리 생성 및 custom.fact 배포

### custom.fact 예제 및 배포 실습 ###

[user@ansible-server work]$ cat custom.fact

[general]
service_name = vsftpd
package_name = vsftpd
app_ver = "1.0"
location = production

[test_section]
test_name = ansible custom fact
test_host = all
work_dir = /home/ansible_user/

[user@ansible-server work]$ cat 0730_ansible_fact_custom.yaml
---
- name: Install custom ansible facts - managed nodes
  hosts: all
  become: true
  vars:
    remote_dir: /etc/ansible/facts.d
    custom_facts: custom.fact

  tasks:
  - name: Create directory (managed nodes)  
    file:  
      state: directory                                 → 디렉터리 생성
      recurse: true
      path: "{{ remote_dir }}"
  - name: Copy custom facts
    copy:                                               → custom.fact 파일 배포
      src: /home/user/work/custom.fact
      dest: "{{ remote_dir }}"

 

변수를 이용한 패키지 설치, 서비스 실행, 방화벽설정 (런타임/퍼머넌트 동시에 적용)

 ※ 위에 나와있는 /etc/ansible/facts.d/custom.fact 가 적용된 상태여야함

[user@ansible-server work]$ cat 0730_playbook_ansible_custom_fact.yaml
---
- name: Install {{ ansible_facts['ansible_local']['custom']['general']['package_name'] }} Package and Service
  hosts: 192.168.56.11
  become: yes

  tasks:
  - name: Install Package
    yum:
      name: "{{ ansible_facts['ansible_local']['custom']['general']['package_name'] }}"
      state: latest
  - name: Enable "{{ ansible_facts['ansible_local']['custom']['general']['service_name'] }}"Service
    service:
      name: "{{ ansible_facts['ansible_local']['custom']['general']['service_name'] }}"
      state: started
  - name: allow ftp service
    firewalld:
      service: ftp
      state: enabled
      permanent: yes
      immediate: true

[user@ansible-server work]$ ansible-playbook 0730_playbook_ansible_custom_fact.yaml
[user@ansible-server work]$ ansible 192.168.56.11 -m command -a "systemctl status vsftpd"
192.168.56.11 | CHANGED | rc=0 >>
● vsftpd.service - Vsftpd ftp daemon
   Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2021-07-30 11:11:07 KST; 31s ago
  Process: 4288 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf (code=exited, status=0/SUCCESS)
 Main PID: 4290 (vsftpd)
    Tasks: 1
   CGroup: /system.slice/vsftpd.service
           └─4290 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf

[user@ansible-server work]$ ansible 192.168.56.11 -m command -a "firewall-cmd --list-services" --become
192.168.56.11 | CHANGED | rc=0 >>
dhcpv6-client ftp ssh
[user@ansible-server work]$ ansible 192.168.56.11 -m command -a "firewall-cmd --list-services --permanent" --become
192.168.56.11 | CHANGED | rc=0 >>
dhcpv6-client ftp ssh

[user@ansible-server work]$ ftp 192.168.56.11
Connected to 192.168.56.11 (192.168.56.11).
220 (vsFTPd 3.0.2)
Name (192.168.56.11:user): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,56,11,130,250).
150 Here comes the directory listing.
drwxr-xr-x    2 0        0               6 Jun 09 16:15 pub
226 Directory send OK.
ftp> cd pub
250 Directory successfully changed.
ftp> ls
227 Entering Passive Mode (192,168,56,11,248,152).
150 Here comes the directory listing.
226 Directory send OK.
ftp> bye
221 Goodbye.

 

제어문

  프로그램에서 동작 흐름을 제어하기 위한 특수한 구문. 조건비교문, 반복문이 있음

반목문

  동일한 코드를 여러번 수행해야하는 경우 사용하는 제어문

  loop 문, with

조건문

  조건식의 참 거짓에 따라 실행여부를 결정하는 제어문

  when문

  ※ ansible_facts['memory_mb']['real']['total'] 

     (=  ansible_memory_mb.real.total  )

블록

  작업내용을 논리적으로 나누기 위해 사용하는 단위

 작업 내용을 논리적으로 그룹화 하기 위하여 사용함

 

  작업수행 시 오류가 발생하면 해당 부분만 묶어서 처리를 할 수 있음

 

핸들러 (Handler)

  작업 실행 시 시스템에 변경사항(changed)이 발생하고 통지(notify)하는 경우 실행되는 작업의 모임

  작업이 실행되어 시스템에 변경사항이 적용된 이후 실행되어야 하는 작업을 실행하고자 할 때 사용

 

 

A == B 같음
A == "B" 같음
A > B 크다
A < B 작다
A >= B 크거나 같다
A <= B 작거나 같다
A is defiend 변수가 정의되었음
A is not defined 변수가 정의되지 않았음

 

###loop###

[user@ansible-server work]$ cat 0730_loop2.yaml
---
- name: loop statement 2
  hosts: all
  vars:
    tools: ['vim', 'vscode', 'pycharm', 'notepad']

  tasks:
  - name: echo list variable elements
    command: echo "{{ item }}"
    loop:
      "{{ tools }}"


  [user@ansible-server work]$ cat 0730_dictionary_loop.yaml
---
- name: dictionary variable loop
  hosts: localhost

  tasks:
  - name: echo dictionary values
    command: echo "{{ item.name }} - {{ item.score }}"
    loop:
    - {name: 'alice', score: 100}
    - {name: 'bob', score: 95}
    - {name: 'charlie', score: 87}

 

###when###

[user@ansible-server work]$ cat 0730_when.yaml
---
- name: when statement
  hosts: 192.168.56.11
  vars:
    is_available: true

  tasks:
  - name: print state
    command: echo "is_available - {{ is_available }}"
    when: is_available

[user@ansible-server work]$ cat 0730_when2.yaml
---
- name: when using expression
  hosts: all
  become: true

  tasks:
  - name: add user01
    user:
      name: user01
      group: user
      groups : ['wheel']
      state: present
    when: ansible_distribution == "CentOS" and ansible_distribution_major_version >= 6
  - name: install package
    apt:
      name: apache2
      state: latest
    when: ansible_os_family == "Debian"

[user@ansible-server work]$ cat 0730_when3.yaml
---
- name: install postfix using when statement
  hosts: all
  become: true

  tasks:
  - name: install postfix package
    yum:
      name: postfix
      state: present
    when: ansible_facts['memory_mb']['real']['total'] >= 512
[user@ansible-server work]$ cat 0730_when4.yaml
---
- name: loop, when example
  hosts: 192.168.56.11
  become: true

  tasks:
  - name: Install packages
    yum:
      name: "{{ item }}"
      state: present
    loop:
    - httpd
    - vsftpd
    when: ansible_facts['os_family'] == "RedHat"

[user@ansible-server work]$ cat 0730_when5.yaml
---
- name: loop, when 2
  hosts: all
  become: true
  vars:
    max_users: 10

  tasks:
  - name: add users
    user:
      name: "{{ item }}"
      group: nobody
      groups: ['wheel']
    loop:
    - user01
    - user02
    - user03
    when: max_users > 10

 

###block###

[user@ansible-server work]$ cat 0730_block.yaml
---
- name: block example
  hosts: all

  tasks:
  - name: Install package
    block:
    - yum:
        name: httpd
        state: present
    become: true
    become_user: root
  - name: check OS version
    command: cat /etc/centos-release
  - name: print who am i
    command: whoami

[user@ansible-server work]$ cat 0730_block2.yaml
---
- name: block example2
  hosts: all

  tasks:
  - name: block begin
    block:
    - yum:
        name: nfs-utils
        state: present
    become: true
    rescue:
    - debug:
        msg: package install failed

[user@ansible-server work]$ cat 0730_block3.yaml
---
- name: block example 3
  hosts: all

  tasks:
  - name: install package
    block:
    - yum:
        name: http
        state: latest
    become: true
    rescue:
    - debug:
        msg: package install failed
    always:
    - debug:
        msg: Job finished.

 

###handler###

[user@ansible-server work]$ cat 0730_handler1.yaml
---
- name: Handler Example
  hosts: 192.168.56.11
  become: true

  tasks:
  - name: install package
    yum:
      name: httpd
      state: latest
    notify:
    - Start httpd Service

  handlers:
  - name: Start httpd Service
    service:
      name: httpd
      state: started


[user@ansible-server work]$ cat 0730_handler2.yaml
---
- name: Handler example 2
  hosts: 192.168.56.11
  become: true

  tasks:
  - name: Create a directory
    file:
      path: /work/testdir1
      state: directory
      mode: 0777
  - name: Create a file
    copy:
      content: "Hello Ansible!!"
      dest: /work/testdir1/hello.txt
    notify:
    - print hello.txt

  handlers:
  - name: print hello.txt
    command: cat /work/testdir1/hello.txt

 

 

 

###테스트###

 

[user@ansible-server work]$ cat 0730_block_test1.yaml
---
- name: block, rescue example
  hosts: all

  tasks:
  - name: touch private file
    file:
      path: /home/ansible_user/private.txt
      state: touch
  - name: copy
    copy:
      dest: /home/ansible_user/private.txt
      content : "hello world"
  - name: cat private file
    block:
    - command: cat /home/ansible_user/private.txt
    rescue:
    - debug:
        msg: file open error


[user@ansible-server work]$ cat 0730_block_test1.yaml
---
- name: block, rescue example
  hosts: all

  tasks:
  - name: touch private file
    file:
      path: /home/ansible_user/private.txt
      state: absent
  - name: copy
    copy:
      dest: /home/ansible_user/private.txt
      content : "hello world"
  - name: cat private file
    block:
    - command: cat /home/ansible_user/private.txt
    rescue:
    - debug:
        msg: file open error

 

728x90
Comments