동적 인벤토리 사용하기

동적 인벤토리 사용하기 (Working with dynamic inventory)

Ansible 인벤토리가 시간에 따라 변동하고, 비즈니스 요구에 따라 호스트가 켜지고 꺼진다면, "How to build your inventory"에서 설명한 정적 인벤토리 방식으로는 부족해요. 호스트를 클라우드 프로바이더, LDAP, Cobbler, 엔터프라이즈 CMDB 시스템 등 여러 소스에서 추적해야 할 수 있어요.

Ansible은 동적 외부 인벤토리 시스템으로 이 모든 옵션을 통합해요. Ansible은 외부 인벤토리에 연결하는 두 가지 방법, 즉 **인벤토리 플러그인(Inventory plugins)**과 **인벤토리 스크립트(inventory scripts)**를 지원해요. 인벤토리 플러그인은 Ansible Core 코드의 최신 업데이트를 활용하며, 동적 인벤토리에는 스크립트보다 플러그인을 권장해요. 추가 동적 인벤토리 소스에 연결하려는 직접 플러그인을 작성할 수도 있어요.

출처: 문서

본문

인벤토리 스크립트를 쓰고 싶다면 여전히 쓸 수 있어요. 인벤토리 플러그인을 구현할 때 script 인벤토리 플러그인을 통해 하위 호환성을 보장했기 때문이에요. 아래 예시들은 인벤토리 스크립트 사용법을 보여줘요.

동적 인벤토리를 처리하는 GUI를 선호한다면, AWX 또는 Red Hat Ansible Automation Platform의 인벤토리 데이터베이스가 모든 동적 인벤토리 소스와 동기화되고, 결과에 대한 웹·REST 접근을 제공하며, 그래픽 인벤토리 편집기를 제공해요. 모든 호스트의 데이터베이스 레코드로 과거 이벤트 기록을 대조해 지난 플레이북 실행에서 어떤 호스트가 실패했는지 볼 수 있어요.

인벤토리 스크립트 예시: Cobbler

Ansible은 원래 Michael DeHaan이 작성하고 현재 Ansible에서 일하는 James Cammarata가 이끄는 Linux 설치 서버인 Cobbler와 완벽하게 통합돼요. Cobbler는 주로 OS 설치 킥오프와 DHCP·DNS 관리를 위해 쓰이지만, 여러 구성 관리 시스템(동시에라도)의 데이터를 표현할 수 있는 일반 계층이 있어 '가벼운 CMDB' 역할을 할 수 있어요.

Ansible 인벤토리를 Cobbler에 연결하려면 이 스크립트를 /etc/ansible에 복사하고 chmod +x로 실행 권한을 주세요. Ansible을 쓸 때마다 cobblerd를 실행하고, -i 명령줄 옵션(예: -i /etc/ansible/cobbler.py)으로 Cobbler의 XMLRPC API를 통해 Cobbler와 통신하세요.

/etc/ansiblecobbler.ini 파일을 추가해서 Ansible이 Cobbler 서버가 어디 있는지 알게 하고 캐시 개선이 쓰일 수 있게 하세요. 예:

[cobbler]

# Set Cobbler's hostname or IP address
host = http://127.0.0.1/cobbler_api

# API calls to Cobbler can be slow. For this reason, we cache the results of an API
# call. Set this to the path you want cache files to be written to. Two files
# will be written to this directory:
#   - ansible-cobbler.cache
#   - ansible-cobbler.index

cache_path = /tmp

# The number of seconds a cache file is considered valid. After this many
# seconds, a new API call will be made, and the cache file will be updated.

cache_max_age = 900

먼저 /etc/ansible/cobbler.py를 직접 실행해 스크립트를 테스트해 보세요. JSON 데이터 출력이 보여야 하지만, 아직 아무것도 없을 수도 있어요.

이 것이 무엇을 하는지 살펴볼게요. Cobbler에서 다음과 같은 시나리오를 가정해요.

cobbler profile add --name=webserver --distro=CentOS6-x86_64
cobbler profile edit --name=webserver --mgmt-classes="webserver" --ksmeta="a=2 b=3"
cobbler system edit --name=foo --dns-name="foo.example.com" --mgmt-classes="atlanta" --ksmeta="c=4"
cobbler system edit --name=bar --dns-name="bar.example.com" --mgmt-classes="atlanta" --ksmeta="c=5"

위 예시에서 시스템 'foo.example.com'은 ansible로 직접 주소를 지정할 수 있고, 'webserver'나 'atlanta' 그룹 이름을 쓸 때도 주소를 지정할 수 있어요. Ansible은 SSH를 쓰므로 시스템 foo에 'foo.example.com'으로만 접촉하고, 절대 'foo'만으로는 접촉하지 않아요. 마찬가지로 "ansible foo"를 시도하면 시스템을 찾지 못하지만, "ansible 'foo*'"는 동작해요 — 시스템 DNS 이름이 'foo'로 시작하기 때문이에요.

이 스크립트는 호스트·그룹 정보 이상을 제공해요. 보너스로, 'setup' 모듈이 실행되면(플레이북 사용 시 자동으로 일어나요) 변수 'a', 'b', 'c'가 모두 템플릿에 자동으로 채워져요.

# file: /srv/motd.j2
Welcome, I am templated with a value of a={{ a }}, b={{ b }}, and c={{ c }}

이건 이렇게 실행할 수 있어요.

ansible webserver -m setup
ansible webserver -m template -a "src=/tmp/motd.j2 dest=/etc/motd"

참고: 'webserver'라는 이름은 Cobbler에서 왔고, 구성 파일의 변수도 마찬가지예요. Ansible에서 평소처럼 자신만의 변수를 전달할 수는 있지만, 외부 인벤토리 스크립트의 변수는 같은 이름의 것을 재정의해요.

그래서 위 템플릿(motd.j2)과 함께라면, 시스템 'foo'의 /etc/motd에는 다음 데이터가 쓰여져요.

Welcome, I am templated with a value of a=2, b=3, and c=4

시스템 'bar'(bar.example.com)에는,

Welcome, I am templated with a value of a=2, b=3, and c=5

그리고 기술적으로 (딱히 좋은 이유는 없지만) 이 것도 동작해요.

ansible webserver -m ansible.builtin.shell -a "echo {{ a }}"

즉, 이 변수들을 인자/액션에서도 쓸 수 있다는 뜻이에요.

다른 인벤토리 스크립트

Ansible 2.10 이상에서 인벤토리 스크립트는 연결된 컬렉션으로 옮겨졌어요. 대부분은 이제 ansible-community/contrib-scripts 저장소에 있어요. 대신 인벤토리 플러그인 사용을 권장해요.

인벤토리 디렉터리와 여러 인벤토리 소스 사용하기

Ansible에서 -i에 주어진 위치가 디렉터리(또는 ansible.cfg에서 그렇게 구성)라면, Ansible은 동시에 여러 인벤토리 소스를 사용할 수 있어요. 이 때 같은 ansible 실행에서 동적·정적으로 관리되는 인벤토리 소스를 섞을 수 있어요. 즉석 하이브리드 클라우드! 인벤토리 디렉터리에서 실행 가능한 파일은 동적 인벤토리 소스로, 대부분의 다른 파일은 정적 소스로 취급돼요. 다음 확장자로 끝나는 파일은 무시돼요.

~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo

ansible.cfg에서 inventory_ignore_extensions 목록을 구성하거나 ANSIBLE_INVENTORY_IGNORE 환경 변수를 설정해 이 목록을 자신의 선택으로 교체할 수 있어요. 두 경우 모두 값은 위처럼 패턴의 쉼표 구분 목록이어야 해요.

인벤토리 디렉터리의 group_vars·host_vars 하위 디렉터리는 예상대로 해석돼서, 인벤토리 디렉터리는 서로 다른 구성 집합을 정리하는 강력한 방법이 돼요. "Passing multiple inventory sources"에서 더 자세히 보세요.

동적 그룹의 정적 그룹

정적 인벤토리 파일에서 그룹의 그룹을 정의할 때는 자식 그룹도 정적 인벤토리 파일에 정의돼 있어야 해요. 그렇지 않으면 ansible이 에러를 반환해요. 동적 자식 그룹의 정적 그룹을 정의하고 싶다면, 동적 그룹을 정적 인벤토리 파일에서 빈 채로 정의하세요. 예:

[tag_Name_staging_foo]

[tag_Name_staging_bar]

[staging:children]
tag_Name_staging_foo
tag_Name_staging_bar

더 알아보기 (Learn more)

  • How to build your inventory — 정적 인벤토리 파일에 대한 모든 것
  • Inventory plugins — 동적 인벤토리에 권장되는 방법
  • Communication — 질문·도움이 필요하면 Ansible 커뮤니케이션 가이드 방문