Ansible Playbook 심화 (Handler,Template,Role)


Handler

notify가 설정된 모듈에서 change가 발생했을 때 실행되는 것.

(command 모듈은 무조건 change가 발생하기에 command와 연결하는건 안좋다.)

 

예제 시나리오 )

control의 /home/vagrant/work/src/test를 node1의 /tmp로 보내는데,

복사가 된다면 "testfile이 복사 되었습니다." 라고 출력이 되도록

[vagrant@control work]$ cat h.yaml
- name: Handlers Example
  hosts: node1
  tasks:
    - name: copy src/testfile
      copy:
        src: ./src/test
        dest: /tmp/
      notify:
        - message

  handlers:
    - name: message
      debug:
        msg: testfile이 복사 되었습니다

 

Template 템플릿

틀을 만들고 찍어내는거 

 

템플릿에도 종류가 많지만, Jinja  template을 사용할거임

(웹사이트 만들때 쓰는것이지만, 파이썬기반이라 ansible에서 사용가능)

 

예제

for.j2

[vagrant@control work]$ cat for.j2
{% for x in range(10) %}
        {{x}}
{% endfor %}

for로 시작하면 endfor로 끝남

 

jinja template는 playbook에 넣어서 실행해야한다.

[vagrant@control work]$ cat template.yaml
- hosts: localhost
  tasks:
    - template:
        src: ./for.j2
        dest: /tmp/for_result.txt
    - shell: cat /tmp/for_result.txt
      register: jinja
    - debug:
        msg: "{{jinja.stdout}}"

 

결과

더보기
[vagrant@control work]$ anp template.yaml

PLAY [localhost] **********************************************************************************

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

TASK [template] ***********************************************************************************
ok: [localhost]

TASK [shell] **************************************************************************************
changed: [localhost]

TASK [debug] **************************************************************************************
ok: [localhost] => {
    "msg": "\t0\n\t1\n\t2\n\t3\n\t4\n\t5\n\t6\n\t7\n\t8\n\t9"
}

예제2

if.j2

[vagrant@control work]$ cat if.j2
{% set a=10 %}
{% set b=20 %}
{% if a == b %}
        {{a}}가 {{b}}와 같다
{% elif a > b %}
        {{a}}가 {{b}}보다 크다
{% else %}
        {{a}}가 {{b}}보다 작다
{% endif %}

if > elif > elif > ...  > elif > else > endif

 

if.yaml

[vagrant@control work]$ cat if.yaml
- hosts: localhost
  tasks:
    - template:
        src: ./if.j2
        dest: /tmp/if_result.txt
    - shell: cat /tmp/if_result.txt
      register: jinja
    - debug:
        msg: "{{jinja.stdout}}"

 

결과

더보기
[vagrant@control work]$ anp if.yaml

PLAY [localhost] **********************************************************************************

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

TASK [template] ***********************************************************************************
changed: [localhost]

TASK [shell] **************************************************************************************
changed: [localhost]

TASK [debug] **************************************************************************************
ok: [localhost] => {
    "msg": "\t10가 20보다 작다"
}

실습예제

더보기

user.yaml

[vagrant@control work]$ cat user.yaml
- hosts: localhost
  vars:
    users: ["sunhee","younghee","chulsoo"]
    package: httpd
    result: installed
  tasks:
    - template:
        src: users.j2
        dest: ./users.txt
      notify:
        - cat_users
        - msg_users
    - template:
        src: package.j2
        dest: ./pkg.txt
      notify:
        - cat_pkg
        - msg_pkg

  handlers:
    - name: cat_users
      shell: cat ./users.txt
      register: users
    - name: msg_users
      debug:
        msg: "{{users.stdout}}"
    - name: cat_pkg
      shell: cat ./pkg.txt
      register: pkg
    - name: msg_pkg
      debug:
        msg: "{{pkg.stdout}}"

 

users.j2

[vagrant@control work]$ cat users.j2
{% for user in users %}
        {{user}}

 

package.j2

[vagrant@control work]$ cat package.j2
{% if package %}
        {{result}}
{% endif %}

 

결과

[vagrant@control work]$ anp user.yaml

PLAY [localhost] **********************************************************************************

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

TASK [template] ***********************************************************************************
changed: [localhost]

TASK [template] ***********************************************************************************
changed: [localhost]

RUNNING HANDLER [cat_users] ***********************************************************************
changed: [localhost]

RUNNING HANDLER [msg_users] ***********************************************************************
ok: [localhost] => {
    "msg": "        sunhee\n        younghee\n        chulsoo"
}

RUNNING HANDLER [cat_pkg] *************************************************************************
changed: [localhost]

RUNNING HANDLER [msg_pkg] *************************************************************************
ok: [localhost] => {
    "msg": "        installed"
}

실습 2

시나리오 : Facts변수와 template을 이용해 노드에 접속했을 때 노드이름 및 정보들을 표시하도록

 

welcome.yaml

[vagrant@control work]$ cat welcome.yaml
- hosts: all
  become: yes
  tasks:
    - name: info {{ansible_host}}
      template:
        src: ./src/node_info.j2
        dest: /etc/motd # message of today 로그인시 메시지 나오도록

 

./src/node_info.j2

[vagrant@control work]$ cat ./src/node_info.j2
welcome to {{ansible_nodename}}
OS info : {{ansible_os_family}} / {{ansible_distribution}} {{ansible_distribution_version}}
ip address : {{ansible_all_ipv4_addresses}}

 

결과

[vagrant@control work]$ ssh node1
Last login: Tue Feb 20 07:56:17 2024 from 192.168.110.10
welcome to node1.example.com
OS info : RedHat / CentOS 7.8
ip address : [u'192.168.110.20', u'10.0.2.15']

 

Role

다른사람들에게 공유할 수 있도록 약속된 구조를 갖추는 것 (디렉터리 형식)

 

role을 생성하기 전에 yaml파일을 만든다.

예제 시나리오

centos 그룹에 포함된 모든 node 를 대상으로 
아래의 조건이 되도록 플레이북을 작성하세요

1. 아파치가 설치 되어 있어야 하고
2. 아파치 서비스가 실행되어 있어야 한다. (패키지명은 변수로 처리한다)
3. http://노드주소로 접속하면 아래처럼  인사말이 출력되어야 한다.
welcome to node1.example.com
<= jinja template 을 사용해서 처리하도록 한다.

4. 플레이북이 실행될때 httpd.conf 가 managed node 에 있는것과
  local 에 있는것이 다르면 local 에 있는 /home/vagrant/src/httpd.conf 파일이 
  managed 노드로 복사되게 한다.
* 로컬에 httpd 를 설치하면 httpd.conf 가 설치되므로 테스트를 위해서
로컬의 httpd.conf 를 /home/vagrant/src/ 로 복사를 한다.

5. managed node 에 httpd.conf 가 복사되면 핸들러를 호출하여
  managed node 의 httpd 서비스를 재시되게 한다.
[vagrant@control work]$ cat httpd.yaml
- hosts: centos
  become: yes
  vars:
    package: httpd
  tasks:
    - name: apache install
      yum:
        name: "{{package}}"
        state: latest
    - name: apache start
      service:
        name: "{{package}}"
        state: started
    - name: index.html
      template:
        src: ./src/index.html
        dest: /var/www/html/index.html
    - name: copy httpd.conf
      copy:
        src: ./src/httpd.conf
        dest: /etc/httpd/conf/httpd.conf
      notify: apache restart

  handlers:
    - name: apache restart
      service:
        name: "{{package}}"
        state: restarted

 

Role로 만드는 법

"ansible-galaxy init apache" 로 틀을 만들고 그 안에 내용들을 집어넣는거임

[vagrant@control work]$ ansible-galaxy init httpd
- Role httpd was created successfully
[vagrant@control work]$ tree httpd
httpd
├── defaults
│   └── main.yml
├── files
│   └── httpd.conf
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
│   └── index.j2
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

디렉터리 안에 있는 파일 이름은 바꾸면 안된다.

 

task/main.yml

[vagrant@control work]$ cat httpd/tasks/main.yml
---
# tasks file for httpd
- name: apache install
  yum:
    name: "{{package}}"
    state: latest
- name: apache start
  service:
    name: "{{package}}"
    state: started
- name: index.html
  template:
    src: index.j2  # 경로 바꿈 httpd/template 참조
    dest: /var/www/html/index.html
- name: copy httpd.conf
  copy:
    src: httpd.conf # 경로 바꿈 httpd/files 참조
    dest: /etc/httpd/conf/httpd.conf
  notify: apache restart

tasks에서 경로를 잘 맞춰주는 것은 중요함.

 

** vim에서 한번에 띄어쓰기를 이동시킬 때는 

: set sw=4 한다음 shift+v로 블럭지정하고 "<" 키를 눌러서 왼쪽으로 밀면 된다.

(떨어진 칸수가 4칸이었기에 sw=4로 한것임.)

 

handlers/main.yml

[vagrant@control handlers]$ cat main.yml
---
# handlers file for httpd
- name: apache restart
  service:
    name: "{{package}}"
    state: restarted

 

vars/main.yml

[vagrant@control httpd]$ cat vars/main.yml
---
# vars file for httpd
package: httpd

 

** 변수가 들어갈 수 있는 곳은 defaults와 vars인데, vars가 우선순위가 높음

 

 

src 파일은 files에 집어넣으면 된다. (템플릿이 아닌)

예시에서는 httpd.conf 파일

 

** template src 파일은 template에 넣어야함.

예시에서는 index.j2

 

meta 디렉터리는 버전의 정보나 작성자의 정보 같은 것들을 남기기 위한것

 

role 실행

[vagrant@control work]$ cat httpd_role.yaml
- hosts: centos
  become: yes
  roles:
    - httpd    # 디렉터리 명

 

실행파일을 만들어야함

role 디렉토리와 같은 경로에 있어야 함. (즉 roles 디렉터리 바로 위)

더보기
[vagrant@control work]$ anp httpd_role.yaml

PLAY [centos] *************************************************************************************

TASK [Gathering Facts] ****************************************************************************
ok: [node3]
ok: [node2]
ok: [node1]

TASK [httpd : apache install] *********************************************************************
changed: [node1]
changed: [node3]
changed: [node2]

TASK [httpd : apache start] ***********************************************************************
changed: [node2]
changed: [node3]
changed: [node1]

TASK [httpd : index.html] *************************************************************************
ok: [node2]
ok: [node3]
ok: [node1]

TASK [copy httpd.conf] ****************************************************************************
changed: [node2]
changed: [node3]
changed: [node1]

RUNNING HANDLER [httpd : apache restart] **********************************************************
changed: [node2]
changed: [node3]
changed: [node1]

PLAY RECAP ****************************************************************************************
node1                      : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node2                      : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node3                      : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

정상적으로 실행됨

** 외부에서 roles를 받아서 설치할때

https://galaxy.ansible.com 에서 검색을 하고

"ansible-galaxy role install jdauphant.nginx" 이런식으로 설치를 하는데

기본 경로가 .ansible/roles다. 여기는 사용하기 불편하기에

/etc/ansible/ansible.cfg에 있는 roles_path를 원하는 곳으로 변경하여 

설치하는 것도 하나의 방법이다.

'Ansible' 카테고리의 다른 글

ansible 미니 프로젝트 - wordpress 사이트 배포  (0) 2024.02.22
Vault, Facts, Include_tasks, 조건문  (0) 2024.02.19
centos, ubuntu, window node 생성 및 nfs  (0) 2024.02.15
실습  (0) 2024.02.14
Playbook  (0) 2024.02.13

+ Recent posts