맘가는 대로

앤서블에서 변수 사용하기 본문

자동화/앤서블

앤서블에서 변수 사용하기

ALIVEisANSWER 2019. 11. 23. 16:40

앤서블의 변수

많은 프로그래밍 언어에서 데이터를 저장하고 사용하기 위해 변수를 사용한다. 이러한 원리는 앤서블에서도 마찬가지로 사용된다.
 
코딩을 한다면, 프로그램의 목적마다 다르겠지만, 전역 변수를 상수로 설정하고 주요한 데이터를 프로그램 전체에서 사용할 수 있게 하거나, 지역 변수를 사용해 특정 함수 혹은 메소드에 대해서만 사용할 수 있게 할 수 있을 것이다. 혹은 객체 지향 프로그래밍을 한다면 클래스 변수를 도입해 객체들마다 공유하는 변수를 사용할 수도 있을 것이다.
 
앤서블에서 사용하는 변수들도 개략적으로 보자면 비슷하지만, 큰 차이점은 각각의 변수가 앤서블의 모듈보다는 호스트마다 다를 수 있다는 것이다. 예를 들어, 앤서블은 호스트의 IP 주소를 수집할 수 있는데, 같은 네트워크 대역에서 호스트들은 절대 같은 IP 주소를 가질 수 없다. 만약 가졌다고 한다면 이미 통신에 문제가 있을 것이다.
 
이 글에서는 변수들의 특성과 더불어 앤서블에서 제공하는 다양한 변수 활용법들을 살펴보고자 한다.
 

변수 활용

앤서블에서 변수를 정하고 활용하는 방법은 많다. 기본적으로 호스트에 대한 정보를 앤서블에서 수집하며, 호스트 파일과 플레이북에서도 설정이 가능하고, 호스트 별로 개별 변수를 설정할 수 있다.

 

 

진행하기에 앞서 앤서블에서 변수는 크게 두 가지가 있다. 개별 호스트의 정보를 제공하는 fact 와 앤서블 작동중 관련된 정보를 제공하는 info 가 있다. 각 변수명은 _fact 와 _info 로 끝맺으며, 최근 변수의 이름이 제공되는 데이터와 의미가 같지 않다고 앤서블 2.9 버전에서 이 둘의 변수를 좀 더 구별하기 위한 패치가 있었다. 즉, 사용할 때에도 정의할 때에도 fact 와 info 변수를 잘 구별하는 것이 좋다.

 

- 기본 변수, Facts

별도의 설정을 하지 않았다면, 앤서블 플레이북을 실행할 때마다 'Gathering Facts' 라는 작업이 진행된 것을 볼 수 있을 것이다.

이 작업이 앤서블에서 기본적으로 제공하는 변수들에 데이터를 입력하기 위한 작업이다.

 

해당 작업을 통해 얻는 데이터를 확인하는 방법에는 앤서블 명령어를 입력해서 직접 조회하는 것과, 플레이북에서 debug 모듈을 이용하여 확인하는 것이 있다.

 

먼저 앤서블 명령어를 이용하여 보자. 방법은 간단하다.

ansible -m setup all

setup 모듈을 이용하여 Ad-hoc 명령을 주면 되는데 결과는 아래와 같다.

실제 결과는 각 호스트마다 매우 많은 정보를 보여주기 때문에 직접 확인하는 것으로 넘기겠다.

 

그렇다면 일부만 보려고 할 때에는 어떻게 할 수 있을까?

ansible -m setup -a "filter=ansible_all_ipv4_addresses" all

-a 옵션으로 filter 설정을 주면 특정 항목들만 볼 수 있다. 다만, filter 에서 받아들이는 방식은 shell 방식이기 때문에 임의의 문장을 지정할 때는 정규표현식의 '.*' 이 아닌 '*' 이다.

여기까지 앤서블의 Ad-hoc 방식을 이용해서 기본 변수인 ansible_facts 를 확인할 수 있는 방법을 알아보았다.

 

이제 플레이북에서 사용되는 방법을 보도록 한다.

 

플레이북을 실행할 때 fact 데이터는 ansible_facts 에 있지 않다. ansible_ 으로 시작되는 변수들만을 직접 조회할 수 있다. 그래서 setup 모듈을 통해서 알아본 ansible_facts 를 구성하는 요소들을 직접 조회하는 방법을 사용해야 한다.

 

다만, ansible_facts 를 사용하는 것이 불가능한 것은 아니지만 앤서블 설정을 변경해줘야지 가능하다. 이는 INJECTS_FACTS_AS_VARS 설정을 참고하면 된다.

 

플레이북에서 fact 를 조회해보자.

---
- hosts: all
  become: true
  tasks:
    - name: Show ansible_facts
      debug:
        var: ansible_all_ipv4_addresses

방금 전 setup 모듈을 통해 조회한 것과 일치하는 것을 볼 수 있다.

 

그렇다면 다른 호스트의 ansible_facts 를 이용하는 것은 어떤 방법이 있을까?

그 때에는 hostvars 라는 변수를 사용할 수 있다.

 

node-1 노드의 IPv4 주소를 사용한다고 해보자.

---
- hosts: all
  become: true
  tasks:
    - name: Show ansible_facts
      debug:
        var: hostvars['node-1']['ansible_all_ipv4_addresses']

hostvars 변수는 각 호스트의 변수를 조회할 수 있게 하는데, 구성 요소에서 노드명을 지정하고 다시 변수명을 지정하면 해당 노드의 변수를 조회할 수 있다.

결과를 보면 알 수 있듯이 모든 노드에서 node-1 노드의 IPv4 변수를 조회한 것을 알 수 있다. 예를 들어 앤서블 컨트롤러 노드에 대해서만 추가적으로 서버 방화벽을 열고자 할 때 노드의 IP 주소를 이용해서 열 수 있을 것이다.

 

Facts 변수들은 각 호스트의 정보를 입력하는데 쓰이고, 각 노드에 맞는 데이터를 사용해서 설정을 하거나, 다른 노드들의 정보를 이용하여 설정을 하는 등 다양하게 사용할 수 있다.

 

- 호스트 변수

호스트 변수는 개별 호스트 혹은 호스트 그룹에 할당한 변수를 의미한다.

 

호스트 변수는 호스트 파일로 사용하는 JSON, INI, YAML 파일에서 vars 항목을 통해 설정이 가능하며, 동적 호스트 파일도 마찬가지로 출력으로 나오는 JSON 에서 vars 항목에서 설정되어 있으면 사용할 수 있다.

 

호스트 그룹에 변수를 할당하기 위해 직접 호스트 파일에 vars 항목을 작성해보자.

all:
  hosts:
    ansible:
      ansible_connection: local
  vars:
    test: "This is test"
  children:
    test:
      hosts:
        node-1:
          ansible_host: 10.10.10.10
          ansible_ssh_private_key_file: /vagrant/.vagrant/machines/node-1/virtualbox/private_key 

그리고 플레이북을 통해 조회해보자.

모든 노드에서 test 라는 변수를 조회가 가능하다. 이는 all 단락에서 설정된 vars 항목에 있는 test 를 조회했기 때문이다.

 

차이를 알아보기 위해 children 항목에서 test 단락에서만 다른 변수를 정의하고 조회해보자.

all:
  hosts:
    ansible:
      ansible_connection: local
  vars:
    test: "This is test"
  children:
    test:
      hosts:
        node-1:
          ansible_host: 10.10.10.10
          ansible_ssh_private_key_file: /vagrant/.vagrant/machines/node-1/virtualbox/private_key
      vars:
        foo: "This is test's variable."
---
- hosts: all
  become: true
  tasks:
    - name: Show host variable test
      debug:
        var: test

    - name: Show host variable foo
      debug:
        var: foo

all 단락에 있는 test 변수는 모든 노드에서 조회가 가능했지만, test 단락에 있는 foo 변수는 test 단락에 포함된 node-1 노드에서만 조회가 가능했다.

 

지금까지 호스트 그룹에 변수를 할당했다면, 호스트 자체에 변수를 할당할 수도 있다. 다만, 이 경우에는 vars 항목을 추가하지 않고 바로 변수명을 사용하면 된다.

all:
  hosts:
    ansible:
      ansible_connection: local
  vars:
    test: "This is test"
  children:
    test:
      hosts:
        node-1:
          ansible_host: 10.10.10.10
          ansible_ssh_private_key_file: /vagrant/.vagrant/machines/node-1/virtualbox/private_key 
          foo: "This is test's variable."

 

- 동적 변수

프로그래밍에서 말하는 런타임 변수와 의미가 비슷하다. 앤서블에서 모듈을 실행하고 나온 결과값을 변수에 등록하고 사용할 수 있는데, 주로 호스트에서 직접 실행한 명령어의 결과값을 사용하고자 할 때 주로 사용된다.

 

테스트를 하기 위해 호스트에 있는 사용자 계정들의 정보를 가져온다고 가정해보자.

---
- hosts: all
  become: true
  tasks:
    - name: Get user info.
      command: "getent passwd"
      register: user_list

    - name: Show users in host.
      debug:
        var: user_list

command 모듈을 통해 커맨드를 실행하면 단순히 실행만 되기 때문에 결과값을 변수에 등록하기 위해 register 항목을 같이 사용해야 한다.

 

실행하면 아래와 같이 나온다.

매우 길게 나오므로 직접 실행해봐서 확인해보도록 하자. 혹은 실행결과만을 보고 싶다면 아래와 같이 작성해서 실행할 수도 있다.

---
- hosts: all
  become: true
  tasks:
    - name: Get user info.
      command: "getent passwd"
      register: user_list

    - name: Show users in host.
      debug:
        var: user_list['stdout_lines']

동적 변수는 위와 같이 모듈이 실행되고 나온 결과값을 저장하고 다시 다른 모듈에서 사용할 수 있다.

 

- 플레이북 변수

플레이북 변수는 플레이북에서 설정되고 플레이북 전체에서 사용가능한 변수를 의미한다. 호스트 변수와 사용법이 같기 때문에 새로 배운다는 느낌은 나지 않을 수도 있다.

 

변수를 정의해보자. 정의는 플레이북 내에서 한다.

---
- hosts: all
  become: true
  vars:
    playbook_var: "This is variable in playbook."
  tasks:
    - name: Show playbook variable
      debug:
        var: playbook_var

플레이북 내에서 vars 항목을 통해 원하는 변수를 정의할 수 있다.

정의도 쉽고 사용도 편하기 때문에 많이 사용될 변수이기도 하다.

 

- 기타

이외에도 로컬 변수나 별개 파일에서 가져오는 변수, 변수 우선 순위등이 있지만 대개 관리를 어렵게하는 것들이고, 로컬 변수의 경우 컨트롤러 노드에서 알기도 어렵겨니와 성능을 떨어트리는 영향도 있기 때문에 사용을 하지 않거나 주의를 바란다.

앤서블의 효과를 높여주는 변수

이 글에서는 앤서블에서 사용되는 주요 변수들과 그 사용 방법들을 보았다. 프로그래밍에 익숙할수록 앤서블도 간단히 사용할 수 있을 것이라 생각되고, 앤서블 사용을 편리하게 해주는 데에 큰 도움을 줄 것이다.
 
특히, 많이 참조되는 데이터일수록 변수의 유용함을 느낄 수 있을 것이며, 변화되는 시스템에서 간단히 설정을 바꾸는 등의 작업으로 활용될 수 있을 것이다.
 
앤서블에서 role 이라는 한 목적을 위해 다양한 앤서블 기능들을 모은 집합에서 변수는 정말 많이 사용되기 때문에 변수를 활용하는 방법은 단순히 유용함을 넘어서 꼭 알아두어야 하는 기능이기도 하다.

 

 

출처

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

 

Using Variables — Ansible Documentation

There are other places where variables can come from, but these are a type of variable that are discovered, not set by the user. Facts are information derived from speaking with your remote systems. You can find a complete set under the ansible_facts varia

docs.ansible.com

 

'자동화 > 앤서블' 카테고리의 다른 글

Ansible 을 통해 파일 작성하기  (0) 2019.11.03
Ansible 로 LAMP 구성하기  (0) 2019.09.29
앤서블 인벤토리 설정  (0) 2019.06.09
앤서블 실습 환경 구성  (0) 2019.06.08
앤서블의 구조와 작동 방식  (0) 2019.06.02
Comments