Red Hat Certified Engineer (RHCE) #2 Inventory: static, dynamic, group/host_vars
#1에서 RHCE(EX294)가 Ansible 자동화 실기 시험이라는 정체성을 잡았습니다. 플레이북을 작성하기 전에 먼저 답해야 할 질문이 하나 있습니다. Ansible이 도대체 어떤 호스트를 다루는가입니다. 이 질문에 답하는 파일이 inventory입니다. inventory는 제어 노드가 관리할 관리 노드의 목록이며, 어떤 호스트를 어떤 그룹으로 묶고 각 호스트에 어떻게 접속할지를 선언합니다.
inventory를 정확히 구성하지 못하면 그 뒤의 모든 플레이북은 대상을 찾지 못합니다. 그래서 이번 글은 static inventory의 두 형식, 그룹과 그룹의 그룹, 변수를 분리하는 group_vars와 host_vars 디렉터리, 그리고 inventory를 검증하는 명령까지 한 번에 정리하겠습니다.
inventory란 무엇인가 #
inventory는 Ansible이 작업을 수행할 대상 호스트의 목록입니다. 가장 단순한 형태는 호스트 이름이나 IP주소를 한 줄에 하나씩 적은 텍스트 파일입니다. 여기에 호스트를 그룹으로 묶고, 그룹별로 변수를 부여하고, 접속 방법까지 더해 나가면 실전에서 쓰는 inventory가 됩니다.
inventory는 크게 두 종류로 나뉩니다.
- static inventory. 사람이 직접 파일에 호스트를 적어 둔 inventory입니다. 변하지 않는 고정 환경에 적합하며, RHCE 시험에서 작성하는 inventory는 거의 전부 이쪽입니다.
- dynamic inventory. 스크립트나 플러그인이 외부 시스템(클라우드 API, CMDB 등)에 질의해 호스트 목록을 실행 시점에 생성하는 inventory입니다. 호스트가 수시로 바뀌는 환경에 적합합니다.
시험의 중심은 static inventory이므로 여기부터 정확히 다지겠습니다.
static inventory: INI 형식 #
가장 전통적인 inventory 형식은 INI 형식입니다. 대괄호로 그룹 이름을 선언하고, 그 아래에 호스트를 한 줄씩 나열합니다.
# inventory
# 그룹 없이 나열된 호스트는 자동으로 ungrouped 그룹에 속합니다
bastion.example.com
[web]
web1.example.com
web2.example.com
[db]
db1.example.com
[lb]
lb1.example.com대괄호로 묶이지 않은 채 파일 상단에 적힌 호스트는 ungrouped라는 암묵 그룹에 들어갑니다. 그리고 inventory의 모든 호스트는 자동으로 all이라는 그룹에 함께 속합니다. 즉 all과 ungrouped는 사용자가 만들지 않아도 항상 존재하는 그룹입니다.
호스트 범위 표기 #
호스트 이름이 규칙적인 숫자나 알파벳으로 이어진다면 범위 표기로 줄여 쓸 수 있습니다. 대괄호 안에 시작과 끝을 콜론으로 연결합니다.
[web]
web[1:3].example.com
[db]
db[a:c].example.comweb[1:3].example.com은 web1.example.com, web2.example.com, web3.example.com을 의미합니다. 숫자뿐 아니라 [a:c]처럼 알파벳 범위도 가능합니다. 호스트가 많을 때 inventory를 짧고 명확하게 유지하는 표기이므로 익혀 두겠습니다.
그룹의 그룹: children #
그룹을 다시 묶어 상위 그룹을 만들 수 있습니다. INI 형식에서는 [그룹이름:children] 헤더 아래에 하위 그룹 이름을 나열합니다.
[web]
web[1:3].example.com
[db]
db1.example.com
# webservers와 db를 묶은 상위 그룹
[production:children]
web
db이렇게 하면 production 그룹을 대상으로 지정했을 때 web과 db에 속한 모든 호스트가 함께 선택됩니다. 환경(production, staging)이나 역할로 호스트를 계층화할 때 유용한 구조입니다.
INI 형식의 인라인 변수 #
INI 형식에서는 호스트 줄 뒤에 변수를 바로 붙일 수도 있습니다.
[web]
web1.example.com ansible_host=192.168.10.11 ansible_user=devops
web2.example.com ansible_host=192.168.10.12 ansible_user=devops다만 이렇게 호스트 줄에 변수를 길게 붙이면 가독성이 떨어집니다. 변수는 뒤에서 다룰 group_vars와 host_vars로 분리하는 방식이 권장됩니다.
static inventory: YAML 형식 #
같은 inventory를 YAML 형식으로도 쓸 수 있습니다. 구조가 명시적이라 그룹 계층과 변수가 한눈에 들어옵니다.
# inventory.yml
all:
children:
web:
hosts:
web1.example.com:
web2.example.com:
web3.example.com:
db:
hosts:
db1.example.com:
production:
children:
web:
db:YAML 형식에서는 all 아래의 children으로 그룹을 선언하고, 각 그룹의 hosts 아래에 호스트를 둡니다. 그룹의 그룹은 그룹 안에 다시 children을 두어 표현합니다. INI의 [production:children]이 여기서는 production 아래의 children으로 대응됩니다.
YAML 형식에서도 그룹의 vars나 호스트 아래에 변수를 직접 부여할 수 있습니다. INI와 YAML 중 어느 형식을 써도 동작은 동일합니다. 시험에서는 둘 중 익숙한 형식을 쓰면 되지만, 두 형식을 모두 읽을 수 있어야 제공된 inventory를 해석할 수 있습니다.
연결 변수: 호스트에 어떻게 접속하는가 #
호스트 이름만으로 접속이 안 되는 경우가 많습니다. 접속 주소가 다르거나 로그인 계정이 다르거나 포트가 표준이 아닐 수 있습니다. 이때 쓰는 특수 변수가 connection variable입니다.
| 변수 | 의미 |
|---|---|
ansible_host | 실제 접속할 주소나 IP주소(inventory 이름과 달라도 됨) |
ansible_user | SSH 로그인 계정 |
ansible_port | SSH 포트(기본 22가 아닐 때 지정) |
ansible_connection | 연결 방식(ssh가 기본, 로컬은 local) |
ansible_become | 권한 상승 여부(true/false) |
inventory에 적은 이름과 실제 접속 정보가 다를 때 이 변수들로 맞춥니다. 연결 변수도 호스트 줄에 흩어 두기보다 group_vars와 host_vars로 정리하면 관리가 깔끔해집니다.
group_vars와 host_vars로 변수 분리 #
inventory 파일에 변수를 직접 적을 수도 있지만, 변수가 많아지면 파일이 복잡해집니다. Ansible은 inventory 옆에 정해진 디렉터리를 두면 변수를 자동으로 읽어 들이는 규약을 제공합니다. 바로 group_vars와 host_vars입니다.
group_vars/<그룹이름>.yml. 해당 그룹에 속한 모든 호스트에 적용되는 변수입니다.host_vars/<호스트이름>.yml. 특정 호스트 하나에만 적용되는 변수입니다.
디렉터리 구조는 다음과 같습니다.
project/
├── ansible.cfg
├── inventory
├── group_vars/
│ ├── all.yml
│ ├── web.yml
│ └── db.yml
├── host_vars/
│ ├── web1.example.com.yml
│ └── db1.example.com.yml
└── site.ymlgroup_vars/all.yml은 모든 호스트에 공통으로 적용되는 변수를 둡니다. group_vars/web.yml은 web 그룹에만, host_vars/web1.example.com.yml은 web1.example.com 호스트 하나에만 적용됩니다. 파일 이름이 그룹 이름이나 호스트 이름과 정확히 일치해야 자동으로 읽힙니다.
group_vars 예제 #
web 그룹 전체에 적용할 변수를 group_vars/web.yml에 둡니다.
# group_vars/web.yml
http_port: 80
max_clients: 200
app_user: webadmin
firewall_service: http모든 호스트 공통 변수는 group_vars/all.yml에 둡니다.
# group_vars/all.yml
ansible_user: devops
ansible_port: 22
ntp_server: time.example.comhost_vars 예제 #
특정 호스트에만 필요한 값은 host_vars에 둡니다. 예를 들어 web1만 접속 주소와 포트가 다르다면 다음처럼 작성합니다.
# host_vars/web1.example.com.yml
ansible_host: 192.168.10.11
ansible_port: 2222
server_id: 1이렇게 분리해 두면 inventory 파일은 호스트와 그룹 구조만 담고, 변수는 각 파일이 책임지게 됩니다. 시험에서 “이 그룹에만 이 값을 부여하라"는 유형이 나오면 거의 group_vars로 해결합니다.
inventory 확인하기 #
inventory를 작성한 뒤에는 Ansible이 의도대로 해석했는지 반드시 검증해야 합니다. 머릿속 구조와 실제 파싱 결과가 다른 경우가 흔하기 때문입니다. 검증에 쓰는 명령은 다음과 같습니다.
ansible-inventory –list #
inventory의 전체 구조와 각 호스트에 적용된 변수를 JSON으로 출력합니다.
ansible-inventory -i inventory --list이 명령은 group_vars와 host_vars까지 합쳐서 각 호스트가 최종적으로 갖는 변수를 보여 주므로, 변수가 의도한 호스트에 제대로 붙었는지 확인하기에 가장 좋습니다.
ansible-inventory –graph #
그룹과 호스트의 계층 구조를 트리 모양으로 출력합니다.
ansible-inventory -i inventory --graph출력 예는 다음과 같습니다.
@all:
|--@ungrouped:
|--@production:
| |--@web:
| | |--web1.example.com
| | |--web2.example.com
| | |--web3.example.com
| |--@db:
| | |--db1.example.com그룹의 그룹(children)이 의도대로 묶였는지를 한눈에 볼 수 있습니다. --graph 뒤에 --vars를 붙이면 각 노드의 변수도 함께 표시됩니다.
ansible all –list-hosts #
특정 패턴이 어떤 호스트로 펼쳐지는지 빠르게 확인합니다.
ansible web -i inventory --list-hosts
ansible production -i inventory --list-hosts
ansible all -i inventory --list-hostsweb 그룹이나 production 같은 상위 그룹을 지정했을 때 실제로 어떤 호스트가 선택되는지 보여 줍니다. 플레이북을 돌리기 전에 대상이 맞는지 점검하는 안전장치입니다.
dynamic inventory 개념 #
호스트가 자주 바뀌는 환경에서는 inventory를 손으로 유지하기 어렵습니다. 클라우드처럼 인스턴스가 수시로 생성되고 삭제되는 곳에서는, 실행 시점에 현재 호스트 목록을 받아 오는 dynamic inventory가 필요합니다.
dynamic inventory는 두 가지 방식으로 구현됩니다.
- inventory script. 실행하면 정해진 JSON 형식으로 호스트 목록을 출력하는 실행 파일입니다. 형식만 맞추면 어떤 언어로든 작성할 수 있습니다.
- inventory plugin. 최신 권장 방식입니다. YAML 설정 파일로 외부 소스를 지정하면 플러그인이 호스트를 가져옵니다. 예를 들어
amazon.aws.aws_ec2플러그인은 AWS의 EC2인스턴스를 inventory로 변환합니다.
플러그인 방식 설정 파일의 예시는 다음과 같습니다.
# aws_ec2.yml (inventory plugin)
plugin: amazon.aws.aws_ec2
regions:
- ap-northeast-2
keyed_groups:
- key: tags.Role
prefix: role이 파일을 -i aws_ec2.yml로 지정하면 Ansible이 실행 시점에 AWS API에 질의해 호스트 목록을 만들고, EC2의 Role 태그 값으로 그룹을 자동 생성합니다. RHCE 시험에서 dynamic inventory를 직접 작성하라는 유형은 비중이 작지만, static과 dynamic의 차이와 개념은 정리해 두겠습니다.
시험 단골 유형 #
RHCE 시험에서 inventory와 관련해 자주 등장하는 작업은 정형화되어 있습니다.
- 특정 그룹 정의. 주어진 호스트들을 지정된 그룹 이름으로 묶고, 여러 그룹을 다시 상위 그룹(children)으로 묶는 작업입니다.
- group_vars로 변수 분리. inventory 파일을 더럽히지 않고, 특정 그룹에만 적용되는 변수를
group_vars/<그룹>.yml에 두는 작업입니다. - host_vars로 예외 처리. 한 호스트만 다른 값을 가져야 할 때
host_vars/<호스트>.yml로 처리하는 작업입니다. - 연결 변수 지정.
ansible_host,ansible_user,ansible_port로 접속 정보를 맞추는 작업입니다.
다음은 위 요구를 한 번에 만족하는 종합 예제입니다. INI inventory와 group_vars를 함께 둔 구성입니다.
# inventory
[web]
web1.example.com
web2.example.com
[db]
db1.example.com
[datacenter:children]
web
db# group_vars/web.yml
http_port: 80
firewall_service: http
app_root: /var/www/app# group_vars/all.yml
ansible_user: devops
timezone: Asia/Seoul이 구성을 ansible-inventory -i inventory --graph --vars로 확인하면 datacenter 아래에 web과 db가 묶이고, 각 호스트에 group_vars의 변수가 올바르게 적용된 것을 볼 수 있습니다.
시험 포인트 #
- inventory의 모든 호스트는 자동으로
all그룹에, 그룹 없는 호스트는ungrouped그룹에 속합니다. - INI 형식의 그룹의 그룹은
[그룹:children], YAML 형식은 그룹 아래의children으로 표현합니다. - 범위 표기
web[1:3]은web1〜web3을 펼칩니다. 숫자와 알파벳 모두 가능합니다. - 변수는 inventory에 직접 적기보다
group_vars/<그룹>.yml과host_vars/<호스트>.yml로 분리합니다. 파일 이름이 그룹이나 호스트 이름과 정확히 일치해야 자동으로 읽힙니다. - 연결은
ansible_host,ansible_user,ansible_port로 제어합니다. - 작성 후에는
ansible-inventory --list,ansible-inventory --graph,ansible <패턴> --list-hosts로 반드시 검증합니다. - dynamic inventory는 script나 plugin으로 외부 소스에서 호스트를 가져오는 방식이며, 클라우드 환경에 적합합니다.
정리 #
이번 글에서 잡은 것:
- inventory는 Ansible이 다룰 호스트를 정의하는 출발점입니다. static과 dynamic으로 나뉘고, 시험의 중심은 static입니다.
- static inventory는 INI와 YAML 두 형식으로 작성하며, 호스트와 그룹, 그룹의 그룹(children), 범위 표기(
web[1:3])를 지원합니다. - 변수는
group_vars와host_vars디렉터리로 분리하고, 연결 변수(ansible_host/ansible_user/ansible_port)로 접속을 제어합니다. ansible-inventory --list와--graph,ansible all --list-hosts로 inventory를 검증합니다.- dynamic inventory는 스크립트와 플러그인으로 클라우드 같은 외부 소스의 호스트를 실행 시점에 가져옵니다.
다음: 설정 파일과 연결 #
이제 Ansible이 어떤 호스트를 다룰지는 inventory로 정의했습니다. 그렇다면 Ansible은 그 inventory를 어디서 찾고, 호스트에 어떻게 접속하며, 권한은 어떻게 올릴까요.
#3 설정 파일과 연결: ansible.cfg, ssh, become에서는 ansible.cfg의 우선순위와 주요 설정, SSH 키 기반 접속 구성, 그리고 become으로 권한을 상승하는 방법까지 직접 구성하며 정리하겠습니다.