<aside>
☁️ 클라우드웨이브 · W06 · 4/5 · 예상 읽기 6~8분
</aside>
처음 작성한 플레이북은 한 파일 안에서 읽기 쉽다. 하지만 비슷한 시스템을 여러 환경에 설치하거나 같은 설정을 여러 서비스에 적용하면 파일이 길어지고 복사본이 생긴다. 4일차에는 반복을 줄이는 방법을 파일 관리, 템플릿, 재사용 단위라는 순서로 연결해 보았다.
파일을 다룰 때는 단순히 내용을 쓰는 것보다 파일의 최종 상태를 명확히 하는 편이 좋다. file은 경로의 존재, 권한, 소유자 같은 상태를 다룰 수 있고, copy는 정적인 파일을 배치한다. lineinfile과 blockinfile은 기존 파일의 일부를 관리할 때 사용하며, stat은 변경 전 상태를 확인하는 데 도움을 준다. fetch는 관리 호스트의 파일을 제어 노드로 가져오는 용도다.
파일 작업에서는 경로와 권한을 함께 생각해야 한다. 디렉터리가 없을 때의 처리, 재실행 시 중복 삽입 여부, 서비스 계정의 접근 범위를 확인해야 한다. 보안 컨텍스트가 필요한 환경이라면 파일이 생성된 뒤 애플리케이션이 실제로 읽을 수 있는지도 점검해야 한다.
환경마다 달라지는 값이 설정 파일 곳곳에 있다면 template으로 구조와 값을 분리한다. 템플릿은 변수로부터 최종 파일을 렌더링하므로, 기본값과 환경별 입력을 한눈에 파악할 수 있다. 템플릿이 바뀐 경우에만 handler를 호출해 서비스를 다시 읽게 하면 불필요한 재시작도 줄어든다.
service_name: {{ service_name }}
listen_port: {{ listen_port }}
mode: {{ runtime_mode | default('safe') }}
작업을 여러 파일로 나눌 때 import와 include의 차이도 확인했다. import는 플레이북을 읽는 시점에 정적으로 결합하는 성격이 강하고, include는 실행 중 조건이나 반복과 함께 동적으로 포함할 수 있다. 어느 쪽이 무조건 우수한 것이 아니라, 실행 구조를 예측해야 하는지 조건에 따라 확장해야 하는지에 따라 선택한다.
Role은 특정 책임을 재사용 가능한 단위로 만든다. 일반적으로 tasks에는 작업, handlers에는 변경 후속 작업, files에는 정적 파일, templates에는 렌더링할 템플릿, defaults에는 낮은 우선순위의 기본값, vars에는 더 강하게 고정할 변수를 둔다. 구조가 정해져 있으면 다른 사람이 역할의 진입점과 입력을 빠르게 파악할 수 있다.
재사용을 판단할 때는 복사한 파일의 개수보다 변경의 파급 범위를 본다. 여러 서비스가 같은 파일 규칙을 공유한다면 공통 역할로 추출할 수 있지만, 한 역할이 운영체제 설치부터 애플리케이션 배포까지 모두 맡으면 변경 이유를 추적하기 어렵다. 역할의 입력과 결과를 짧게 문서화하면 호출하는 쪽의 실수도 줄일 수 있다.
defaults와 vars를 구분하는 이유는 재정의 의도를 명확히 하기 위해서다. 환경마다 바뀔 가능성이 큰 값은 defaults에 두고, 역할 내부의 불변에 가까운 값은 vars에 둘 수 있다. 다만 우선순위에 기대어 복잡한 동작을 만들기보다, 공개 입력과 내부 상수를 문서로 분리하는 편이 유지보수에 유리하다.
반복되는 플레이북을 바로 거대한 Role로 옮기기보다, 먼저 책임을 하나로 좁힌다. 예를 들어 서비스 설치, 설정 파일 생성, 서비스 시작을 한 역할로 묶고 입력 변수와 출력되는 상태를 설명한다. 여러 환경에서 같은 역할을 실행해 기본값과 재정의가 예상대로 작동하는지 확인한 뒤 버전과 변경 이력을 관리한다.