TIL

[에스넷시스템 부트캠프] TIL Day21 - Ansible 문법

yulee_to 2025. 6. 19. 00:18
728x90

1. Ansible Playbook 주요 키워드

1) hosts

  • 작업 대상 호스트 지정
  • 인벤토리 내 그룹명 또는 호스트명 지정
  • 미리 정의된 예약어
    • localhost: 현재 로컬 머신
    • all : 인벤토리에 정의된 모든 호스트
    • [group] : 그룹 단위 작업

2) become: true

  • 권한 상승(sudo) 허용
  • 일반 사용자 -> root로 전환해 작업 수행
  • ansible.cfg의 설정을 오버라이드하여 playbook에서 직접 제어 가능

3) tasks

  • 작업의 목록 정의 시작점
  • 각 작업은 하나의 모듈 실행
  • 여러 개의 task -> 하나의 play 
  • 여러 개의 play -> 하나의 playbook 
✏️ 작성 팁:
name: 키워드를 꼭 사용해서 작업 목적을 명시적으로 설명해주는 것이 가독성과 유지보수에 매우 유리

 

 

2. 모듈 관련 명령어

ansible-doc <MODULE_NAME>

: 모듈 문서 확인

 

ansible-doc -l 

: 사용 가능한 모듈 목록 확인

 

3. 인벤토리 파일 형식

기본 형식은 INI 또는 YAML이다. 일반적으로 INI 방식이 많이 사용된다.

[web]
192.168.10.10
web01 ansible_host=192.168.10.11 ansible_user=centos

[db]
db01 ansible_host=192.168.10.20

[prod:children]
web
db
  • [web], [db] : 인벤토리 그룹 이름
  • web01, db01 : 호스트 이름(논리적 이름)
  • ansible_host=IP : 실제 IP 주소
  • ansible_user=사용자 : 해당 호스트에 접속할 유저 이름
  • [prod:children] : 하위 그룹 포함하는 상위 그룹 정의

인벤토리 파일은 일반적으로 inventory라고 구성한다. 다른 이름으로 변경하려면 ansible.cfg 파일에서 설정하면 된다. 

[defaults]
inventory = ./inventory         # 인벤토리 파일 경로
host_key_checking = False       # 호스트 키 체크 비활성화 (초기 접속 시 유용)
remote_user = ansible           # 기본 SSH 유저
ansible_ssh_port = 22           # 포트 (필요 시 변경 가능)
ansible_ssh_user = ansible      # SSH 접속 유저 (개별 호스트 변수보다 낮은 우선순위)
ansible_ssh_pass = ansible123   # SSH 접속 패스워드 (비추천)
forks = 5                       # 병렬 실행 프로세스 수
  • 여기서 지정한 옵션은 playbook이나 adhoc 명령 실행시 자동으로 반영됨
  • 설정 우선 순위 : 명령줄 옵션 > 환경변수 > ansible.cfg > /etc/ansible/ansible.cfg

4. Task 흐름 구조

Ansible의 Task는 Playbook 내에서 실행 순서를 제어할 수 있도록 3단계로 나눌 수 있다. 

  • pre_tasks : 본격적인 작업 전에 실행되는 작업들로 초기 설정, 확인, 변수 수집 등에 사용
  • tasks : 핵심 작업을 정의, 일반적으로 우리가 쓰는 모듈 기반 작업들
  • post_tasks : 모든 tasks가 끝난 후 실행되는 작업들로 후처리, 클린업, 상태 확인 등에 사용

5. 변수

1) 선언 위치

1-1) Inventory 변수

  • 인벤토리 파일 안에 직접 변수 선언
  • 가장 기본적인 방식으로 간단한 실습이나 소규모 환경에서 사용
[webservers]
web1 ansible_host=192.168.1.10 var1=hello var2=world

1-2) group_vars

  • 호스트 그룹 단위 변수 선언
  • groups_vars 디렉토리 안 yml 파일에 변수 정의

1-3) host_vars

  • 개별 호스트 단위 변수 선언
  • host_vars 디렉토리 안 yml 파일에 변수 정의

1-4) role defaults / vars

  • 특정 Role 내부에 설정된 변수
  • defaults 디렉토리 
    • 우선순위가 가장 낮음
    • 역할을 처음 가져왔을 때 제공되는 기본값
    • roles/<role_name>/defaults/main.yml
  • vars 디렉토리
    • 우선순위가 매우 높음
    • 외부에서 덮어쓰기 거의 불가능
    • roles/<role_name>/vars/main.yml

1-5) Playbook 내 변수 선언

  • Playbook에서 vars: 키워드로 직접 정의
  • 즉시 적용, 상대적으로 높은 우선순위
- name: example play
  hosts: web
  vars:
    var1: hello
    var2: world

1-6) 명령줄 변수 (-e 옵션)

  • 가장 우선순위가 높음
ansible-playbook playbook.yml -e "var1=hello var2=world"

 

💡우선순위 정리
role defaults < inventory vars < group_vars < host_vars < playbook vars < role vars < -e 옵션

 

2) 변수 유형

2-1) 리스트

  • YAML에서 -로 시작되는 배열
favorite_colors:
  - red
  - blue
  - green

 

2-2) 딕셔너리 

  • key: value 형태로 여러 값을 묶어 선언
user_info:
  name: alice
  uid: 1001
  shell: /bin/bash

2-3) 시스템 변수 / Magic 변수

변수 이름  설명
inventory_hostname 인벤토리 상의 현재 호스트 이름
ansible_host 실제 접속 IP 또는 호스트명 (기본은 inventory_hostname와 같음)
ansible_user 원격 접속할 사용자 (SSH 접속 시 사용)
ansible_ssh_pass SSH 비밀번호
ansible_port SSH 포트 (기본: 22)
ansible_connection 연결 방식 (예: ssh, local, docker, winrm 등)
ansible_facts setup 모듈 등을 통해 수집된 시스템 정보 (dict 형태)
groups 인벤토리에 정의된 모든 그룹 목록을 담은 dict
group_names 현재 호스트가 속한 그룹 목록 (list)
hostvars 다른 호스트의 변수에 접근할 수 있는 dict
play_hosts 현재 플레이에 포함된 모든 호스트 목록
ansible_play_batch 현재 배치(batch)에 포함된 호스트 목록
inventory_dir 인벤토리 파일의 디렉터리 경로
inventory_file 현재 사용 중인 인벤토리 파일 경로

 

6. when 조건문

  • Ansible에서 특정 task, play, block 등을 조건부로 실행할 때 사용하는 문법.
  • 조건이 true일 경우에만 해당 작업이 실행됨.
  • 시스템 정보가 들어 있는 ansible_facts 내용을 이용하기도 함
  • 다중 조건문 작성시 and, or, 괄호() 등을 사용
  • 인벤토리 변수 기반 조건 설정도 가능

 

7. 레지스터

register는 모듈 실행 결과를 변수로 저장해서 이후 조건문이나 디버깅, 로직 제어에 활용할 수 있도록 해준다. 

속성명  설명
stdout 표준 출력 결과
stderr 표준 에러 출력 결과
rc 리턴 코드 (0이면 성공)
changed 변경 여부 (true/false)
failed 실패 여부
skipped 스킵 여부
stdout_lines 출력된 내용을 줄 단위로 분리한 리스트

 

8. Boolean 표현

  • True 값 : yes / true / on / 1
  • False 값 : no / false / off / 0 

9. 대화형 모드 (Interactive Mode)

Ansible은 기본적으로 비대화형으로 작동한다.즉, 사용자 입력을 기다리지 않으며 자동화 목적에 맞춰 설계되어 있다.

지만 변수를 입력받아야 하는 상황에는 아래 설정이 필요하다. 

vars_prompt:
  - name: "input_password"
    prompt: "Enter your password"
    private: yes       # 입력값 숨김 처리
    confirm: yes       # 한 번 더 확인 요청
    unsafe: yes        # 특수 문자 입력 허용

 

10. 루프

Ansible에서 동일한 작업을 반복적으로 수행할 때 사용하는 문법이다. 

기존에는 with_items, with_dict 등을 많이 썼지만 요즘은 loop를 사용하는 방식이 권장된다.

loop 방식

- name: 여러 사용자 생성
  user:
    name: "{{ item }}"
    state: present
  loop:
    - user1
    - user2

 

 

11. 예외처리 

1) until 

특정 작업이 성공할 때까지 재시도하는 구조로 주로 비동기 작업이나 네트워크 지연 대응시 사용된다.

- name: 서비스 확인 반복
  shell: curl -sf http://localhost
  register: result                  # 명령 결과를 변수에 저장
  until: result.rc == 0             # 조건이 만족할 때까지 반복
  retries: 5                        # 최대 반복 횟수
  delay: 3                          # 반복 사이 대기 시간 (초)

 

2) block, rescue, always

Ansible에서 가장 널리 쓰이는 예외 핸들링 문법 구조로 Java의 try/catch/finally와 유사하다. 

  • block : 기본 작업 집합으로 하나라도 실패시 중단
  • rescue : block 내 작업 실패 실행 (롤백 등)
  • always : 무조건 실행

12. 특정 모듈 제한하기 

보안상의 이유 또는 운영 정책상 어떤 모듈의 사용을 아예 차단하고 싶을 때 사용하는 기능이다. 

 

구현방식

1. ansible.cfg 설정

[defaults]
reject_list = shell, raw, command

2. ANSIBLE_REJECT_LIST 환경 변수로 지정도 가능

export ANSIBLE_REJECT_LIST="shell,raw,command"

 

13. 테스트 문법

문법 형식

when: <변수> is match("<정규표현식>")

 

주요 키워드

키워드  설명
is match 정확히 일치하는지 (Anchored match)
is search 문자열 중 일부라도 일치하는지
is regex match와 거의 같지만 regex engine 기반

 

14. Role

Ansible에서 코드와 리소스를 계층적으로 정리해놓은 디렉터리 기반 구조로, 복잡한 플레이북을 분리하고 재사용하기 쉽게 만든다. 

 

1) 기본 디렉토리 구조

roles/
└── httpd/
    ├── tasks/        # 필수. 주요 작업 정의 (main.yml)
    ├── files/        # copy 모듈에서 사용할 정적 파일 위치
    ├── templates/    # template 모듈에서 사용할 Jinja2 템플릿
    ├── vars/         # 변수 정의
    ├── defaults/     # 기본값 정의 (vars보다 낮은 우선순위)
    ├── handlers/     # notify로 연결되는 작업 정의
    └── meta/         # 의존성 등 메타데이터 정의

 

2) 특징

 

  • 플레이북에서 호출할 때는 roles: , 변수를 포함할 때는 - role:
  • tasks/main.yml은 필수
  • include_role은 동적 실행, import_role은 정적 포함
  • 템플릿은 templates/, 정적 파일은 files/

 

15. 핸들러

핸들러는 특정 작업 이후에 실행되는 후속 작업을 정의하는 기능이다. 일반적으로 notify 키워드로 호출되고 handlers: 블록에 정의된다. 같은 이름의 핸들러는 한 번만 실행된다는 특징이 있다. 

 

1) 정적 핸들러

 

  • 기본값
  • 모든 핸들러가 플레이북 파싱 시점에 메모리에 적재됨
  • when 조건문을 사용할 수 없음
  • 핸들러가 실행 여부에 관계없이 항상 메모리에 로드됨

 

2) 동적 핸들러

 

  • include_tasks, import_tasks, include_role 등 동적 로딩 구조 안에서 핸들러가 정의되면 → 동적 핸들러로 작동
  • 핸들러가 실행 중에 동적으로 로드
  • when, loop, 변수 등 조건 기반으로 사용 가능
  • 핸들러도 재사용/범용화 가능

 

 

✍️ 하루 회고

오늘은 Ansible에 대한 방대한 개념들이 한꺼번에 몰아쳤던 날이었다.
아직 익숙하지 않은 부분이 많아 수업만으로는 이해가 완전하다고 느껴지진 않았다.

그래서 수업 내용을 기반으로 하되, 부족한 개념은 블로그 글과 ChatGPT를 참고해서 하나씩 정리하고 보완해나갔다.

 

아직은 생소하지만, 정리하고 반복해서 보니 조금씩 머릿속에 구조가 잡히는 느낌이다.
직접 실습하면서 감을 익히는 것이 중요할 것 같다.

728x90