변수의 기본 개념

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 

 

Working with Inventory — Ansible Documentation

Docs » User Guide » Working with Inventory You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the latest Ansi

docs.ansible.com

변수 ansible 설명서

https://docs.ansible.com/ansible/2.7/user_guide/playbooks_variables.html

 

Working with Inventory — Ansible Documentation

Docs » User Guide » Working with Inventory You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the latest Ansi

docs.ansible.com

변수 우선 순위: 변수를 어디에 두어야 합니까?

https://docs.ansible.com/ansible/2.7/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable

 

Working with Inventory — Ansible Documentation

Docs » User Guide » Working with Inventory You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the latest Ansi

docs.ansible.com

 

'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

+ Recent posts