변수의 기본 개념
ansible에서는 ansible project 전체에서 재사용할 수 있는 값을 저장하기 위해 변수를 사용할 수 있다. playbook에서는 프로그래밍 언어처럼 변수의 타입을 지정하지는 않는다.
* 변수의 범위
- 전역 범위 : 명령줄(-e 옵션) 또는 ansible 구성에서 설정한 변수
- 플레이 범위 : 플레이 및 관련 구조에서 설정한 변수
- 호스트 범위 : 인벤토리, 팩트수집 또는 등록된 작업별로 호스트 그룹 및 개별 호스트에서 설정한 변수
우선순위는, 명령줄변수(전역) > 플레이북변수(플레이) > 인벤토리변수(호스트) 이다. 명령줄변수가 최우선.
* 변수로 사용 가능한 값 (예시)
- 사용자
- 패키지명
- 서비스
- 제거할 파일
- 인터넷에서 검색할 아카이브 등
* 변수 규칙
- 여러가지가 있지만 가장 필수적인 규칙만 설명한다.
- 문자로 시작해야 한다.
- 문자, 숫자, 밑줄(언더바) 만 사용 가능하다. 당연히 공백 안됨.
각 범위의 따른 변수 정의하기
변수 정의 방법은 총 4가지 방식이다.
- 명령줄에서 변수 정의하기
- 플레이북에서 변수 정의하기
- 인벤토리에서 변수 정의하기
- 디렉토리에서 변수 정의하기
* 명령줄에서 변수 정의하기
- ansible 명령 (애드혹), 그리고 ansible-playbook 명령 모두 -e 옵션을 사용하여 변수를 정의할 수 있다.
ansible-playbook main.yml -e "package=apache"
* 플레이북에서 변수 정의하기
- 방식1 : 플레이북 내부에 정의 : vars 라는 구문 아래에 변수를 (key:value) 형식으로 배치한다.
- name: variable
hosts: all
vars:
user: joe
home: /home/joe
- 방식2 : 외부파일에 정의하고 플레이북에 해당 외부파일을 참조
- name: variable
hosts: all
vars_files:
- vars/users.yml
이 users.yml 에는 아래와 같이 되어있다.
user: joe
home: /home/joe
# 참고 : 변수를 파일로 참조하는것과 직접 입력하는 것 비교
vars_files로 변수 파일을 삽입하면 거기에 있는 변수 리스트들이 적용된것처럼 나오기 때문에, 다음과 같이 이해될 수 있다.
변수 파일을 삽입한 경우 (변수를 직접 입력한 경우와 결과는 동일하다)
locker.yml
pw_developer: Imadev
pw_manager: Imamgr
user_list.yml
users:
- name: node1
job: developers
- name: node2
job: developers
- name: node3
job: manager
- hosts: all
vars_files:
- locker.yml
- user_list.yml
변수를 직접 입력한 경우 (변수 파일을 삽입한 경우와 결과는 동일하다)
vars:
pw_developer: Imadev
pw_manager: Imamgr
users:
- name: node1
job: developers
- name: node2
job: developers
- name: node3
job: manager
따라서 변수를 참조할 때는, "{{ pw_developer }}" 이렇게 하면 결과는 Imadev일 것이고, "{{ users }}" 이렇게 하면 아래 모두가 결과가 된다.
- name: node1
job: developers
- name: node2
job: developers
- name: node3
job: manager
* 인벤토리에서 변수 정의하기
인벤토리 파일 안에는 각 호스트 또는 호스트를 모은 그룹이 명시되는데, 여기 나온 호스트나 그룹에 대해 변수를 지정할 수 있다. 또한 참고로 인벤토리 변수끼리 우선순위를 정할 때 호스트 변수가 그룹 변수보다 우선된다.
이 방법은 인벤토리 파일을 작업하기 어렵게 만들고, 같은 파일에서 호스트와 변수에 대한 정보가 합쳐지고 사용되지 않는 구문을 사용하는 몇 가지 단점이 있습니다. 권장하는 방법은 host_vars, group_vars 디렉토리를 만들어서 그룹변수와 호스트변수를 정의한 파일들을 넣는 것이다.
1. 특정 호스트 하나에 정의하기
[servers]
demo.example.com ansible_user=joe
이런식으로 하면, demo.example.com 에서는 ansible_user가 joe가 된다.
2. 특정 호스트그룹에 정의하기 (:vars 를 사용)
[servers]
demo1.example.com
demo2.example.com
[servers:vars]
user=joe
3. 호스트 그룹을 모은 그룹에 정의하기
[servers1]
demo1.example.com
demo2.example.com
[servers2]
test1.example.com
test2.example.com
[allservers:children]
servers1
servers2
[allservers:vars]
user=joe
* 인벤토리에 맞춰 host_vars, group_vars 디렉토리를 만들어 변수 정의하기
이 방법은 인벤토리에 정의한 값을 바탕으로 같은 프로젝트 디렉토리 안에 추가 디렉토리를 만들어 변수파일을 지정하는 방식이다. 아래 예시를 참고한다. host_vars, group_vars는 정의된 이름이므로 정확히 이 이름을 가진 디렉토리를 생성해야 한다.
인벤토리 파일
[datacenter1]
demo1.example.com
demo2.example.com
[datacenter2]
demo3.example.com
demo4.example.com
[datacenters:children]
datacenter1
datacenter2
해당 인벤토리를 가진 프로젝트의 디렉토리 구조
(datacenters1, datacenters2 각각 s가 빠져야 한다 오타인듯)
이렇게 인벤토리의 그룹과 호스트명을 바탕으로 위와 같이 각각의 그룹/호스트 이름으로 파일을 만든다. 만약 datacenters에 대한 변수를 넣고 싶으면, datacenters 파일에 변수를 명시한다. 예를들어 다음과 같다.
package: httpd
user: uktae
이렇게 하면, datacenters에 포함된 datacenter1, datacenter2 각각에도 위의 변수가 적용된다. 이 말은, 각각 demo1~4.example.com 에도 적용된다는 뜻이다. 만약 단일 호스트 demo1.example.com 에다 변수를 넣고 싶으면 demo1.example.com 파일에 위와 동일하게 변수를 지정하면 된다.
플레이북에서 변수 사용하기
- 정의된 변수는 사용할 때, {{ }} 대괄호 두개 사이에 놓는다.
- 참고로, 키/밸류형태에서 밸류값에 변수를 첫번째로 쓸 때는, " " 로 감싸줘야한다고 한다. 첫번째만 그렇다. 변수가 뒤에 있으면 안써도 된다. (대체 왜지?)
- name: variable
hosts: all
vars:
user: joe
home: /home/joe
tasks:
- name: creates the user {{ user }}
user:
name: "{{ user }}"
* 변수가 적용된 추가예제
- 아래와 같이 vars에 정의된 변수들은 tasks에서 같은 파란색 음영 부분으로 참조된다.
여러 변수 할당 시 배열 사용하기
같은 요소 (패키지, 서비스, 사용자 등)와 관련된 구성 데이터를 여러 변수에 할당하는 대신, 배열을 사용할 수 있다. 이렇게 하면 배열을 검색하여 변수를 지정할 수 있고 좀 더 명확하고 간편하게 변수 참조할 수 있다.
* 배열 변수 만들기
일반적으로 변수는 아래와 같이 지정할 수 있을 것이다. 하지만 이 경우 변수들이 좀 난잡하다.
user1_first_name: bob
user1_last_name: jones
user1_home_dir: /users/bjones
user2_first_name: anne
user2_last_name: cook
user2_home_dir: /users/acook
이 경우 users 라는 배열로 아래와 같이 다시 변수를 작성할 수 있다.
users:
bjones:
first_name: bob
last_name: jones
home_dir: /users/bjones
acook:
first_name: anne
last_name: cook
home_dir: /users/acook
* 배열 변수 참조하기
- bob은 다음 변수로 표현된다 : users.bjones.first_name 또는 users['bjones']['first_name']
- /users/acook은 다음 변수로 표현된다 : users.acook.home_dir 또는 users['acook']['home_dir']
- 점 방식, 대괄호 방식 모두 파이썬에서 볼 수 있는 변수 참조 방식이다.
* 유의사항
- key 이름을 넣을 때, discard, copy, add 같은 "키워드"를 쓰지 말 것. 이러한 키워드를 점 방식으로 사용하면 오류가 날 수 있다.
- 점 방식과 대괄호 방식을 섞어 쓰지 말 것. 일관되게 쓰는 것이 레드햇 권고사항이다.
- 일반적으로 대괄호 표기법이 충돌과 오류가 발생할 가능성이 낮다.
register 키워드
register 키워드는 특정 변수를 만들고 그 변수에 해당 task의 결과를 저장한다. 이 결과는, 그냥 내가 그 명령어를 쳤을때 볼 수 있는 결과 "자체"를 보여준다. 이러한 값은 debugging 또는 명령 출력을 기반으로한 특정 구성과 같은 다른 작업을 수행할 때 사용할 수 있다.
아래 구문은 이미 설치된 httpd를 uninstall 하는 것이다. (참고 : debug 모듈에 대한 상세 정보는 이후에 자세히 전달한다.)
---
- name: play to uninstall web server
hosts: web.example.com
tasks:
- name: latest httpd version uninstalled
yum:
name: httpd
state: absent
register: uninstall_result
- name: debug install_result
debug:
var: uninstall_result
아래 결과를 보면, yum 명령으로 지웠을때의 결과 자체가 그대로 텍스트로 나오는 것을 확인할 수 있다. rester 키워드는 이러한 결과 자체를 보여준다.
주요 링크
인벤토리 ansible 설명서
https://docs.ansible.com/ansible/2.7/user_guide/intro_inventory.html
변수 ansible 설명서
https://docs.ansible.com/ansible/2.7/user_guide/playbooks_variables.html
변수 우선 순위: 변수를 어디에 두어야 합니까?
'Ansible' 카테고리의 다른 글
10장. ansible vault (0) | 2021.02.23 |
---|---|
9장. fact 변수 관리 (0) | 2021.02.20 |
7장. ansible playbook 기본 구현 (0) | 2021.02.20 |
부록1 - 자주 사용되는 모듈들 (0) | 2021.02.19 |
6장. ansible에서 모듈 사용하기 (0) | 2021.02.19 |