Ansible 기초 · 플레이북 기본 · 이론
플레이북 — 명령이 아니라 상태를 적는다
한 줄 요약
플레이북의 각 태스크는 "이 명령을 실행하라"가 아니라 "끝났을 때 이런 상태여야 한다"는 선언이다.
왜 이게 필요했나
셸 스크립트로 서버를 세팅해 본 사람은 스크립트가 점점 길어지는 경험을 한다. 처음엔 mkdir /opt/app 한 줄이었다가, 두 번째 실행에서 "이미 있다" 오류가 나서 mkdir -p 로 바꾸고, 권한이 다를 수 있어 chmod 를 붙이고, 그게 이미 맞으면 굳이 안 해도 되니 if 로 감싼다. 결국 스크립트의 절반이 "지금 상태가 어떤지 확인하는 코드" 가 된다.
Ansible 의 모듈은 그 절반을 대신 짊어진다. file 모듈에 path, state=directory, mode=0755 를 주면, 없으면 만들고 있으면 두고 권한이 다르면 고친다. 그리고 실제로 무언가를 바꿨을 때만 changed 로 보고한다. 이 보고가 다음 모듈에서 배울 멱등성과 핸들러의 토대가 된다.
어떻게 동작하나
플레이북은 플레이의 목록이고, 플레이는 "어떤 호스트에 어떤 태스크를 순서대로"를 담는다.
- name: 웹 서버 기본 설정 # 플레이 이름 hosts: web # 대상 (인벤토리의 그룹/호스트/패턴) gather_facts: true # 대상의 정보를 먼저 수집할지 tasks: - name: 앱 디렉터리 준비 # 태스크 이름 ansible.builtin.file: # 모듈 path: /opt/app state: directory mode: "0755"기억할 규칙은 세 가지다.
1. 태스크는 위에서 아래로 순서대로 실행된다. 다만 여러 호스트에 대해서는 태스크 하나가 모든 호스트에서 끝난 뒤 다음 태스크로 간다.
2. 모든 태스크에 name 을 단다. 이름이 없으면 로그에 모듈 이름과 인자가 통째로 찍혀 읽기 어렵고, 태그로 고르기도 어렵다.
3. command/shell 은 최후의 수단이다. 이 둘은 상태를 모르기 때문에 매번 changed 를 보고한다. 전용 모듈이 있으면 그것을 쓰고, 어쩔 수 없이 셸을 써야 한다면 creates 같은 가드를 붙인다.
실행 전에 확인할 수 있는 수단도 있다. --syntax-check 는 YAML 과 플레이 구조를 검사하고, --check 는 실제로 바꾸지 않고 "무엇이 바뀔지"만 보고한다. --diff 를 함께 주면 파일 내용의 차이까지 보여 준다. 운영 서버에 처음 돌리는 플레이북은 반드시 --check --diff 를 먼저 거친다.
현장에서 만나는 모습
첫째, 태그의 두 얼굴. 태그를 달면 --tags config 로 설정만 다시 밀 수 있어 편하다. 그런데 태그로 일부만 실행하는 습관이 굳으면 "전체를 돌린 적이 없는 플레이북"이 생긴다. 그런 플레이북은 어느 날 전체 실행에서 처음 보는 오류를 낸다. 태그는 디버깅용 가속 장치이지 정상 실행 경로가 아니다.
둘째, 점검 모드의 한계. --check 는 모듈이 그 모드를 지원할 때만 정확하다. command 로 만든 결과에 의존하는 뒷 태스크는 점검 모드에서 엉뚱한 결과를 낼 수 있다. 그래서 점검 모드가 깨끗하다는 것과 실제 실행이 안전하다는 것은 다른 명제다.
셋째, 이름이 곧 문서다. 사고가 났을 때 사람이 읽는 것은 코드가 아니라 실행 로그다. "Install nginx" 보다 "nginx 설치 — 설정 파일은 다음 태스크에서 덮어씀" 이 훨씬 쓸모 있다.
다음 실습에서 할 것
/root/ans/play/site.yml 을 만들어 디렉터리 생성·설정 파일 배치·기존 파일 한 줄 수정을 태스크로 표현하고, 태그와 점검 모드를 직접 써 본다. 마지막에는 오류가 네 군데 심어진 플레이북을 고쳐 통과시킨다.