Skip to content

best-practice

디렉터리 레이아웃

  • 디렉토리의 최상위 수준에는 다음과 같은 파일과 디렉토리로 디자인합니다.
production                # 프로덕션 인벤토리
staging                   # 스테이징 인벤토리

group_vars/
├─ group1.yml           # 그룹별 변수
└─ group2.yml

host_vars/
├─ hostname1.yml        # 호스트별 변수
└─ hostname2.yml

library/                  # 커스텀 모듈 (optional)
module_utils/             # 모듈 유틸리티 (optional)
filter_plugins/           # 필터 플러그인 (optional)

site.yml                  # 마스터 플레이북
webservers.yml            # 웹서버 계층 플레이북
dbservers.yml             # DB서버 계층 플레이북

roles/
├─ common/
│    ├─ tasks/          # main.yml 등
│    ├─ handlers/       # main.yml
│    ├─ templates/      # .j2 템플릿
│    ├─ files/          # 스크립트·파일
│    ├─ vars/           # 역할 변수
│    ├─ defaults/       # 기본 변수
│    └─ meta/           # 의존성 정의
├─ webtier/
├─ monitoring/
└─ fooapp/

대체 디렉터리 레이아웃

  • 인벤토리별로 group_vars/·host_vars/를 완전 분리할 때 유용합니다.
inventories/
├─ production/
│    ├─ hosts
│    ├─ group_vars/
│    └─ host_vars/
└─ staging/
├─ hosts
├─ group_vars/
└─ host_vars/

library/
module_utils/
filter_plugins/

site.yml
webservers.yml
dbservers.yml

roles/
├─ common/
├─ webtier/
├─ monitoring/
└─ fooapp/

클라우드에서 동적 인벤토리 사용

  • 클라우드 환경에서는 정적 파일 대신 동적 인벤토리를 사용하세요.
  • 자체 시스템에서 관리하는 호스트 목록에도 적용 가능합니다.
인벤토리 파일
  • Ansible에서 "인벤토리"는 단순히 .ini 파일만을 의미하지 않습니다.
  • 인벤토리는 Ansible이 인식 가능한 여러 형식(Format)으로 작성된 서버(호스트) 및 그룹 정의 정보를 뜻합니다. 즉, .ini는 가장 기본적인 표현 방식 중 하나일 뿐이며, 다양한 포맷이 존재합니다.

인벤토리 형식 종류

형식 확장자 설명
INI (기본형) 없음 또는 .ini [group] 섹션 기반의 간단한 포맷. 전통적으로 가장 널리 사용됨
YAML .yml, .yaml 구조화된 형식. 동적 인벤토리나 plugin 기반에서 선호됨
JSON .json 잘 사용되진 않지만 지원됨
Python script .py 동적 인벤토리용. AWS, GCP, K8s 등 외부 리소스에서 정보를 수집함
Inventory Plugin .yml Ansible 2.8+ 이후 공식 방식. aws_ec2, gcp_compute 등 사용

예시 1: INI 형식 인벤토리

[webservers]
web1.example.com
web2.example.com

예시 2: YAML 형식 인벤토리

all:
  children:
    webservers:
      hosts:
        web1.example.com:
        web2.example.com:

요약 정리

질문 답변
인벤토리 = ini 파일인가요? ❌ 아니며, .ini는 인벤토리를 표현하는 방식 중 하나일 뿐입니다.
실무에서 가장 많이 쓰는 형식은? .ini 형식이 여전히 가장 널리 쓰입니다. 그러나 YAML 기반 plugin 사용도 점점 증가하는 추세입니다.
디렉토리 자체가 인벤토리 될 수 있나? ✅ 예. inventory/production/ 구조처럼 hosts, group_vars/, host_vars/를 포함하면 디렉토리 전체를 인벤토리로 지정할 수 있습니다.
동적 인벤토리

동적 인벤토리는 클라우드나 외부 시스템의 실시간 정보를 기반으로 인벤토리를 생성하는 방식입니다. 스크립트 기반 또는 YAML 기반(Plugin)으로 구현할 수 있으며, 대표적으로 AWS, GCP, Azure, Kubernetes 환경에서 많이 사용됩니다.

스크립트 기반 (예: AWS EC2) Ansible에서 제공하는 aws_ec2.py 스크립트를 사용해 EC2 인스턴스를 실시간으로 조회할 수 있습니다.

pip install boto3 botocore

ansible-inventory -i aws_ec2.py --list
ansible-playbook -i aws_ec2.py site.yml

YAML 기반 Plugin (권장) Ansible 공식 aws_ec2 Plugin을 이용해 YAML 파일 하나만으로도 자동 인벤토리를 구성할 수 있습니다.

inventory/
└── aws_ec2.yml
plugin: aws_ec2
regions:
  - ap-northeast-2
filters:
  tag:Environment: production
hostnames:
  - private-ip-address
keyed_groups:
  - key: tags.Name
ansible-inventory -i inventory/aws_ec2.yml --list
ansible-playbook -i inventory/aws_ec2.yml site.yml

기타 유용한 Inventory Plugins

plugin 이름 설명
aws_ec2 AWS EC2 인스턴스를 인벤토리로 자동화
gcp_compute GCP VM 인스턴스를 자동 수집
k8s Kubernetes Node/Pod 인벤토리
constructed 기존 인벤토리에서 조건 기반으로 그룹 구성
ini, yaml 전통적인 INI / YAML 정적 인벤토리 포맷
host_list, script 임시 생성 리스트 또는 커스텀 스크립트 기반 인벤토리

실무 추천 요약

환경/상황 추천 방식
온프레미스 수동 서버 관리 INI 인벤토리 + group_vars/, host_vars/
클라우드 자동화 환경 YAML 기반 Inventory Plugin (aws_ec2, gcp_compute 등)
혼합 환경 constructed, meta, script 플러그인 조합하여 활용

스테이징 vs 프로덕션 구분 방법

  • 각각의 환경에 별도 인벤토리 파일(production, staging)을 두고 -i 플래그로 선택
  • 그룹과 지리적 위치를 적절히 조합해 정의
# ini
[atlanta_webservers]
www-atl-1.example.com
...
[webservers:children]
atlanta_webservers
boston_webservers

그룹 변수 및 호스트 변수

  • group_vars/<group>.yml에 그룹 단위 변수 정의
  • host_vars/<hostname>.yml에 호스트 단위 변수 정의
  • 공통 변수는 group_vars/all.yml
# group_vars/all.yml
ntp: ntp-boston.example.com
backup: backup-boston.example.com
그룹 변수 및 호스트 변수 예시

1. 인벤토리 예시 (production)

  • webservers가 그룹 이름이고, 그 아래에 속한 web1.example.comweb2.example.com이 해당 그룹에 속한 호스트(서버)
# ini
[webservers]
web1.example.com
web2.example.com

[dbservers]
db1.example.com

2. group_vars 디렉토리 구조 및 내용

group_vars/
├─ all.yml
├─ webservers.yml
└─ dbservers.yml
  • group_vars/all.yml
ntp_server: ntp-boston.example.com
backup_server: backup-boston.example.com
  • group_vars/webservers.yml
http_port: 80
max_clients: 200
  • group_vars/dbservers.yml
db_port: 3306
db_backup_path: /var/backups/mysql

3. 플레이북 예시 (webservers.yml)

- hosts: webservers
  roles:
    - common
    - webtier
  tasks:
    - name: Show HTTP port
      debug:
        msg: "HTTP port is {{ http_port }}"
    - name: Show NTP server
      debug:
        msg: "NTP server is {{ ntp_server }}"

설명

  • group_vars/all.yml에 정의된 변수는 모든 호스트에 공통으로 적용됩니다.
  • group_vars/webservers.yml에 정의된 변수는 webservers 그룹에 속한 호스트에만 적용됩니다.
  • 플레이북이나 역할 내에서 별도 변수 선언 없이 {{ http_port }}, {{ ntp_server }} 등으로 바로 참조 가능합니다.
  • 이렇게 하면 환경별, 그룹별 변수 관리를 깔끔하게 분리할 수 있습니다.

최상위 플레이북 역할별 분리

  • site.yml
- import_playbook: webservers.yml
- import_playbook: dbservers.yml
  • webservers.yml

- hosts: webservers
  roles:
    - common
    - webtier
* ansible-playbook site.yml --limit webservers 로 부분 실행도 가능


역할별 태스크 및 핸들러 구성

  • roles/common/tasks/main.yml

- name: be sure ntp is installed
  yum:
    name: ntp
    state: present
  tags: ntp
# …
* roles/common/handlers/main.yml

- name: restart ntpd
  service:
    name: ntpd
    state: restarted

이러한 구성으로 가능한 것들

# 전체 인프라 재구성
ansible-playbook -i production site.yml

# NTP만 재구성
ansible-playbook -i production site.yml --tags ntp

# 웹서버만 재구성
ansible-playbook -i production webservers.yml

# 보스턴 웹서버만
ansible-playbook -i production webservers.yml --limit boston

배포 vs 구성 조직

  • OS 구성(playbook)과 애플리케이션 배포(playbook)를 분리
  • deploy_*.yml 같은 별도 플레이북으로 멀티티어 배포 처리

롤링 업데이트

- hosts: webservers
  serial: 3           # 한 번에 3대씩 업데이트
  roles:
    - fooapp

항상 state 명시

yum:
  name: ntp
  state: present    # 명시적으로 작성

역할별 그룹화

hosts: webservers
  • 그룹화를 통해 대상 지정 및 그룹 변수 관리 용이

운영체제 및 배포판 차이 처리

- name: OS별 동적 그룹 생성
  group_by:
    key: os_{{ ansible_facts['distribution'] }}
  • group_vars/os_CentOS.yml 등으로 OS별 변수 자동 적용

플레이북과 함께 모듈 번들링

./library/           # 플레이북 경로 하위에 library 디렉터리 두기

공백 및 주석 활용

  • # 주석과 빈 줄을 적절히 사용해 가독성 확보

태스크 항상 이름 지정

- name: Install nginx
  apt:
    name: nginx
    state: latest

단순하게 유지하기

  • 필요한 기능만 사용
  • 복잡해지면 구조를 단순화할 기회로 판단

버전 관리

  • Git 등으로 플레이북·인벤토리 관리
  • 변경 이력·사유 추적

변수 및 Vault

  1. group_vars/<group>/vars.yml에 일반 변수
  2. group_vars/<group>/vault.yml에 민감 변수 (vault_ 접두어)
  3. vars.yml에서 Jinja2로 vault_ 변수 참조
  4. vault.yml은 암호화하여 커밋

역할 간 의존성 관리

  • 역할(role) 간에 실행 순서나 의존성이 있을 경우, 각 역할의 meta/main.yml 파일에 dependencies 항목으로 명시합니다.
  • 예를 들어, k3s 역할이 secrets 역할에 의존한다면 roles/k3s/meta/main.yml에 다음과 같이 작성합니다.
dependencies:
  - role: secrets
  • 이렇게 하면 k3s 역할을 실행할 때 자동으로 secrets 역할이 먼저 실행되어 필요한 초기 설정(예: SSH 키, 시크릿 등)이 적용된 후 k3s 설치가 진행됩니다.
  • 역할 간 의존성 관리는 플레이북 내 역할 호출 순서와 별개로 역할 내부에서 명확히 정의할 수 있어 유지보수와 재사용성에 유리합니다.