48/120

김건호·2022년 4월 19일
0

템플릿 주석

/etc/ansible/ansible.cfg에서 아래 내용을 복사
ansible.cfg

[defaults]
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}

templates/port.cnf.j2

{{ ansible_managed | comment }}
[mysqld]
port={{ database["svc_port"] }}

comment 가 주석을 만들어줌

경고의 목적

아티펙트 재사용

Artefact, Artifact: 인공물

  • 애플리케이션이 작동해서 생성한 데이터
  • 사람이 직접 작성한 코드

파일을 용도별로 구분을 해서 재사용하기 위함

재사용 가능 분야

  • 변수 파일
  • 작업 파일
  • 플레이/플레이북 파일
  • 역할(Role)

변수 파일

vars_files

플레이의 키워드

- hosts: x
  vars_files:
    - vars/a.yaml

  tasks:
  ...

include_vars 모듈

- hosts: x

  tasks:
    - include_vars:
        dir: vars/

몇가지 옵션

  • dir 변수파일을 모아놓은 dir
  • file 특정 파일명
  • free_from 가능 자유형식은 파일의 위치 지정

간단한 실습

-hosts: 192.168.100.11

 tasks:
   - include_vars: var.yaml
   - debug:
        msg: "{{ message }}"

var.yaml

---
message: hello world

인벤토리 변수

인벤토리 내부 파일에 변수 설정

호스트 변수

node1 message="hello world" # 호스트에게 부여

그룹 변수

[wordpress]
node1
node2

[wordpress:vars]
message="hello world"

인벤토리 외부 파일에 변수 설정

https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable
인벤토리 파일 또는 플레이북 파일이 있는 디렉토리에

  • group_vars/<GROUP NAME>
  • host_vars/<HOST NAME>
    위 두개 디렉토리가 있는 경우
    ansible 오토메이션 엔진이 디렉토리가 있으면 디렉토리에서 변수를 가져옴
    <GROUP NAME>, <HOST NAME> 디렉토리 또는 파일을 생성

간단한 실습

[vagrant@controller ~]$ mkdir host_vars # 디렉토리명은 정해져있음 호스트 부분에 변수 설정
[vagrant@controller ~]$ code host_vars/192.168.100.11 
# 호스트에 부여하니까 호스트이름과 같은 파일을 만듬
[vagrant@controller ~]$ mkdir group_vars
[vagrant@controller ~]$ code group_vars/nodes
[vagrant@controller ~]$ tree
.
├── ansible.cfg
├── group_vars
│   └── nodes
├── host_vars
│   ├── 192.168.100.11
│   └── 192.168.100.12
│       └── var.yaml
└── inven.ini

host_vars\192.168.100.11

---
message: hello node1

host_vars\192.168.100.12\var.yaml 파일이름은 상관없음 -> 파일 분류 가능

---
message: hello node2

group_vars\nodes

service_port: 8080
message: hello world
ansible-inventory --list
ansible-inventory --host <HOST>

test.yaml

---
- hosts: nodes
  tasks:
    - debug:
        msg: "{{ message }} - {{ service_port }}"
[vagrant@controller ~]$ ansible-playbook test.yaml
TASK [debug] ***************************************************
ok: [192.168.100.11] => {
    "msg": "hello node1 - 8080"
}
ansible-inventory --host node1
# node1에 부여된 변수만 확인 가능
[vagrant@controller ~]$ ansible-inventory --host 192.168.100.11
{
    "message": "hello node1", 
    "service_port": 8080
}

작업 재사용

모듈이 있는곳

ansible-doc -l | grep include
ansible-doc -l | grep import_

include_vars: 변수 가져오기
include_role: 역할 가져오기
include_tasks: 작업 가져오기

import_playbook: 플레이북 가져오기
import_role: 역할 가져오기
import_tasks: 작업 가져오기

include vs. import

includeimport
적용 시점동적정적
루프 사용 가능가능불가능
핸들러 호출 가능불가능가능

사전에 정적으로 처리하느냐 인카운트 -> 해당되는 모듈에 가서 처리를 하느냐에 대한 차이
동적으로 가져오기 정적으로 가져오기 -> 기능상 차이가 있음

import에서 루프 불가능

import_tasks는 loop 사용 불가능

- hosts: 192.168.100.11
  tasks:
    - debug:
        msg: in play
    - import_tasks:
        file: task.yaml
      with_sequence: start=1 end=3 # 안됨
    - debug:
        msg: in play

해결방법

- hosts: 192.168.100.11
  tasks:
    - debug:
        msg: in play
    - import_tasks:
        file: task.yaml
    - debug:
        msg: in play

task.yaml

- debug:
  with_sequence: start=1 end=3

yaml파일에 반복을 추가 -> 실제로 import_tasks에서는 debug가 3번 나오는 결과

include에서 핸들러 호출 불가능

- hosts: 192.168.100.11
  tasks:
    - command: hostname
      notify:
        - hello notify
  handlers:
    - include_tasks: task.yaml

동적으로 처리하기 때문에 핸들러가 알람을 받을 수 없음
task.yaml

- name: hello notify
  debug:
    msg: hello notify

해결방법

알람을 받는 코드를 추가

- hosts: 192.168.100.11
  tasks:
    - command: hostname
      notify:
        - hello notify
  handlers:
    - name: hello notify
	  include_tasks: task.yaml

ansible 역할

역할 생성 --> 통합 --> 플레이북
통일화된 구조

mkdir roles # 반드시 roles 디렉토리 사용
ansible-galaxy init common --init-path roles # 구조화된 형식을 자동으로 만들어주는 명령어
.
└── roles
    └── common
        ├── defaults
        │   └── main.yml
        ├── files
        ├── handlers
        │   └── main.yml
        ├── meta
        │   └── main.yml
        ├── README.md
        ├── tasks
        │   └── main.yml
        ├── templates
        ├── tests
        │   ├── inventory
        │   └── test.yml
        └── vars
            └── main.yml

roles/common: 역할의 이름

tasks/main.yml: 작업이 위치
handlers/main.yml: 핸들러 작업이 위치

tests/inventory: 역할을 테스트 하기 위한 인벤토리
tests/test.yml: 역할을 테스트 하기 위한 플레이북

defaults/main.yml: 기본 역할 변수(우선 순위가 매우 낮음)
vars/main.yml: 역할 변수(우선 순위가 매우 높음)

files: 파일 관련 모듈의 src: 파라미터에서 참조하는 파일의 위치
files/a.txt: 경로 지정할 필요 없음

- copy:
	src: a.txt

templates: 템플릿 모듈의 src: 파라미터에서 참조하는 파일의 위치
templates/a.j2

- templates:
    src: a.j2

meta/main.yml: 역할을 설명하고 있는 파일

  • 역할 버전
  • 역할 이름
  • 역할 만든 사람
  • 역할 적용되는 플렛폼(리눅스 배포판)
  • 역할의 의존성

예제

아래 파일을 역할을 사용하여 구성

- hosts: 192.168.100.12
  become: yes
  vars:
    web_port: 81
    
  tasks:
    - yum:
        name: httpd
        state: installed
    - replace:
        path: /etc/httpd/conf/httpd.conf
        regexp: '^Listen'
        replace: '#Listen'
    - template:
        src: web_config/ports.conf.j2
        dest: /etc/httpd/conf.d/ports.conf
      notify:
        - Restart Web Service
    - copy:
        src: web_contents/index.html
        dest: /var/www/html/
    - service:
        name: httpd
        state: started
        enabled: yes
  
  handlers:
    - name: Restart Web Service
      service:
        name: httpd
        state: restarted
 
[vagrant@controller sample]$ tree
.
├── sample.yaml
├── web_config
│   └── ports.conf.j2
└── web_contents
    └── index.html
  • 역할에 필요한 디렉토리 생성
[vagrant@controller sample]$ mkdir roles
[vagrant@controller sample]$ mkdir -p roles/common
[vagrant@controller sample]$ mkdir -p roles/common/vars
[vagrant@controller sample]$ mkdir -p roles/common/tasks
[vagrant@controller sample]$ mkdir -p roles/common/handlers
[vagrant@controller sample]$ mkdir -p roles/common/files
[vagrant@controller sample]$ mkdir -p roles/common/templates
  • `tasks/main.yaml
tasks:
    - yum:
        name: httpd
        state: installed
    - replace:
        path: /etc/httpd/conf/httpd.conf
        regexp: '^Listen'
        replace: '#Listen'
    - template:
        src: ports.conf.j2
        dest: /etc/httpd/conf.d/ports.conf
      notify:
        - Restart Web Service
    - copy:
        src: index.html
        dest: /var/www/html/
    - service:
        name: httpd
        state: started
        enabled: yes
  • handlers/main.yaml
- name: Restart Web Service
  service:
    name: httpd
    state: restarted
  • vars/main.yaml
---
web_port: 81
  • templates/files/로 파일 이동
[vagrant@controller sample]$ cp web_contents/index.html roles/common/files/
[vagrant@controller sample]$ cp web_config/ports.conf.j2 roles/common/templates/
[vagrant@controller sample]$ ansible-playbook site.yaml 

PLAY [192.168.100.11] 

TASK [Gathering Facts] 
ok: [192.168.100.11]

TASK [common : yum] 
changed: [192.168.100.11]

TASK [common : replace] 
changed: [192.168.100.11]
TASK [common : template] 
changed: [192.168.100.11]

TASK [common : copy] 
changed: [192.168.100.11]

TASK [common : service] 
changed: [192.168.100.11]

RUNNING HANDLER [common : Restart Web Service] 
changed: [192.168.100.11]

구조

[vagrant@controller sample]$ tree
.
├── roles
│   └── common
│       ├── files
│       │   └── index.html
│       ├── handlers
│       │   └── main.yaml
│       ├── tasks
│       │   └── main.yaml
│       ├── templates
│       │   └── ports.conf.j2
│       └── vars
│           └── main.yaml
└── site.yaml

플레이에서 작업 실행 순서

# Play
- hosts:
  
  pre_tasks:
  
  roles:
  
  tasks:
  
  post_tasks:

  handlers:
  
  1. pre_tasks
  2. pre_tasks의 handlers
  3. roles
  4. roles의 handlers
  5. tasks
  6. tasks의 handlers
  7. post_tasks
  8. post_tasks의 handlers

오버엔지니어링

ansible-galaxy

https://galaxy.ansible.com/

  • 역할(Role)
  • 컬랙션(Collection): 역할 + 3rd Party 모듈(역할에 보면 library )
  • 번들(Bundle): RedHat OpenShift <-- 역할

역할 목록 확인

ansible-galaxy list
  1. /home/vagrant/.ansible/roles
  2. /usr/share/ansible/roles
  3. /etc/ansible/roles

찾는 순서를 나타냄

ansible-galaxy list --roles-path roles # 역할있는 디렉토리 직접 지정
[vagrant@controller sample]$ ansible-galaxy list --roles-path roles/common
# /home/vagrant/sample/roles/common
# /usr/share/ansible/roles
# /etc/ansible/roles
ansible-galaxy init 역할의 뼈대를 만들어줌
ansible-galaxy search elasticsearch # 역할 검색
ansible-galaxy info geerlingguy.elasticsearch # 역할의 정보 확인
ansible-galaxy install geerlingguy.elasticsearch
ansible-galaxy remove geerlingguy.elasticsearch
profile
Ken, 🔽🔽 거노밥 유튜브(house icon) 🔽🔽

0개의 댓글