Ansible 플레이북 — 원하는 상태를 YAML로 선언하기
Ansible 플레이북 — 원하는 상태를 YAML로 선언하기
Ansible 플레이북은 반복 가능하고 재사용 가능한 설정 관리·멀티머신 배포 시스템이에요. 복잡한 애플리케이션을 배포하는 데 특히 잘 맞죠. 같은 작업을 Ansible로 한 번 이상 해야 한다면 플레이북으로 작성해 소스 제어 아래에 두면 돼요. 이후에 새 설정을 밀어 넣거나 원격 시스템의 구성을 확인하는 데 그 플레이북을 사용할 수 있어요.
플레이북을 쓰면 설정을 선언하고, 여러 머신에서 어떤 수동 절차의 단계를 정해진 순서로 오케스트레이션하며, 태스크를 동기적으로 또는 비동기적으로 실행할 수 있어요. 이 글에서는 플레이북의 기본 문법과 실행 원리를 살펴볼게요.
출처: 공식문서
플레이북 문법
플레이북은 최소한의 문법으로 YAML 형식으로 표현해요. YAML에 익숙하지 않다면 YAML 문법 개요를 먼저 보고, 텍스트 편집기용 애드온을 설치해 깔끔한 문법을 유지하는 걸 추천해요.
플레이북은 순서가 있는 목록 안의 하나 이상의 '플레이(play)'로 구성돼요. 플레이북과 플레이는 스포츠에 빗댄 용어예요. 각 플레이는 플레이북의 전체 목표 중 일부를 실행하며, 태스크(task) 하나 이상을 실행해요. 그리고 각 태스크는 Ansible 모듈을 호출하죠.
플레이북 실행
플레이북은 위에서 아래로 순서대로 실행돼요. 각 플레이 안에서 태스크도 위에서 아래로 순서대로 실행되고요. 플레이가 여러 개인 플레이북은 멀티머신 배포를 오케스트레이션할 수 있어요. 웹 서버에 한 플레이를, 데이터베이스 서버에 다른 플레이를, 네트워크 인프라에 세 번째 플레이를 실행하는 식이죠. 각 플레이는 최소 두 가지를 정의해요.
- 패턴(pattern)을 사용해 관리 대상 노드 지정
- 실행할 태스크 최소 하나
Ansible 2.10 이상에서는 플레이북에 전체 한정 컬렉션 이름(FQCN)을 사용해야 해요. FQCN을 쓰면 올바른 모듈을 선택할 수 있어요. 여러 컬렉션이 user처럼 같은 이름의 모듈을 담을 수 있기 때문이죠.
다음 예시는 첫 번째 플레이가 웹 서버를, 두 번째 플레이가 데이터베이스 서버를 대상으로 해요.
---
- name: Update web servers
hosts: webservers
remote_user: root
tasks:
- name: Ensure apache is at the latest version
ansible.builtin.yum:
name: httpd
state: latest
- name: Write the apache config file
ansible.builtin.template:
src: /srv/httpd.j2
dest: /etc/httpd.conf
- name: Update db servers
hosts: databases
remote_user: root
tasks:
- name: Ensure postgresql is at the latest version
ansible.builtin.yum:
name: postgresql
state: latest
- name: Ensure that postgresql is started
ansible.builtin.service:
name: postgresql
state: started
플레이북은 hosts 줄과 태스크만 담지는 않아요. 위 예시에서는 각 플레이에 remote_user를 설정했는데, 이 값은 SSH 연결에 쓰는 사용자 계정이에요. 플레이북 키워드(Playbook keywords)는 플레이북·플레이·태스크 수준에서 추가해 Ansible의 동작을 조정할 수 있어요. 연결 플러그인, 권한 상승(become) 여부, 오류 처리 등을 제어할 수 있죠. 이런 매개변수 중 다수는 Ansible 설정이나 인벤토리의 명령줄 플래그로도 지정할 수 있어요.
태스크 실행
기본적으로 Ansible은 호스트 패턴에 매칭된 모든 머신에 대해 각 태스크를 하나씩 순서대로 실행해요. 각 태스크는 특정 인자를 가진 모듈을 실행하죠. 태스크가 모든 대상 머신에서 실행된 뒤에야 다음 태스크로 넘어가요. 전략(strategies)을 쓰면 이 기본 동작을 바꿀 수 있어요. 각 플레이 안에서 Ansible은 같은 태스크 지시문을 모든 호스트에 적용해요. 어떤 호스트에서 태스크가 실패하면 Ansible은 그 호스트를 나머지 플레이북 실행에서 제외해요.
플레이북을 실행하면 연결 정보, 모든 플레이·태스크의 name 줄, 각 머신에서 태스크가 성공·실패했는지, 그리고 각 머신에서 태스크가 변경을 만들었는지에 대한 정보가 반환돼요. 플레이북 실행 맨 아래에는 대상으로 삼은 노드와 그 성과를 요약해 주는 요약이 나와요. 일반 실패와 치명적인 'unreachable' 통신 시도는 별도로 집계돼요.
원하는 상태와 멱등성(idempotency)
대부분의 Ansible 모듈은 원하는 최종 상태가 이미 달성됐는지 확인하고, 이미 달성됐다면 아무 작업도 하지 않고 종료해요. 태스크를 반복해도 최종 상태는 바뀌지 않죠. 이렇게 동작하는 모듈을 '멱등적(idempotent)'이라고 불러요. 플레이북을 한 번 실행하든 여러 번 실행하든 결과는 같아야 해요. 다만 모든 플레이북과 모든 모듈이 이렇게 동작하지는 않아요. 확신이 없다면 프로덕션에서 여러 번 실행하기 전에 샌드박스 환경에서 테스트해 보는 게 좋아요.
플레이북 실행하기
플레이북을 실행하려면 ansible-playbook 명령을 사용해요.
ansible-playbook playbook.yml -f 10
실행할 때 --verbose 플래그를 쓰면 성공·실패한 태스크의 상세 출력을 볼 수 있어요.
체크 모드로 실행하기
Ansible 체크 모드(check mode)는 시스템에 어떤 변경도 적용하지 않고 플레이북을 실행하게 해줘요. 프로덕션에 적용하기 전에 플레이북을 테스트하는 데 쓸 수 있어요.
체크 모드로 실행하려면 ansible-playbook 명령에 -C 또는 --check 플래그를 전달해요.
ansible-playbook --check playbook.yaml
이 명령을 실행하면 플레이북이 정상적으로 실행되지만, 변경 대신 했을 변경 사항에 대한 보고서를 제공해요. 이 보고서에는 파일 수정, 명령 실행, 모듈 호출 같은 세부 정보가 담겨요. 체크 모드는 시스템에 의도치 않은 변경을 가하지 않고 플레이북의 기능을 살펴볼 수 있는 안전하고 실용적인 접근법이에요. 기대대로 동작하지 않는 플레이북을 진단하는 데도 유용하죠.
Ansible-Pull
Ansible 아키텍처를 뒤집어서, 설정을 밀어 내보내는 대신 노드가 중앙 위치에 체크인하도록 만들 수도 있어요.
ansible-pull 명령은 git에서 설정 지침 저장소를 체크아웃한 뒤 그 콘텐츠에 대해 ansible-playbook을 실행하는 작은 스크립트예요.
체크아웃 위치를 로드밸런싱하면 ansible-pull은 무한히 확장돼요. 자세한 내용은 ansible-pull --help를 실행해 보세요.
더 알아보기
- 패턴(Patterns): 호스트와 그룹을 선택해 실행 대상을 지정하는 방법
- 핸들러(Handlers): 변경이 있을 때만 실행되는 태스크
- 조건문(Conditionals):
when을 사용한 조건부 태스크 실행 - 권한 상승(become): 다른 사용자로 또는 승격된 권한으로 태스크 실행
- ansible-lint: 플레이북을 실행하기 전에 상세한 Ansible 전용 피드백을 받는 도구