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 |