Compressing Branches With Conditionals and Loops
한국어 원문으로 표시합니다.
목표
복사·붙여넣기로 늘어나던 태스크를 데이터와 반복으로 접고, 조건으로 항목을 걸러낼 수 있게 됩니다.
왜 중요한가
거의 같은 태스크가 여러 개 있으면 그중 하나만 다른 실수가 반드시 생기고, 코드를 읽어서는 찾기 어렵습니다. 태스크를 하나로 줄이면 실수할 자리도 하나가 되고, 데이터는 표처럼 보여 빠진 칸이 눈에 띕니다. 반복을 쓸 때 실무에서 자주 걸리는 것은 세 가지입니다. 로그 노출 — 딕셔너리를 그대로 돌면 그 안의 값이 전부 로그에 찍히므로 loop_control.label 이 필요합니다. 멱등성 — 반복이 열 번 돌면 비멱등의 피해도 열 배입니다. 조합 폭발 — 두 리스트의 곱은 금방 커집니다. 그리고 until 로 무언가를 기다릴 때는 "이 시간 안에 안 되면 진짜 문제"라는 판단을 재시도 횟수에 담으세요.
단계
/root/ans/loops/site.yml에서loop로/root/ans/loops/simple/아래에alpha,beta,gamma디렉터리를 만드세요. 태스크는 하나여야 합니다./opt/lab/fixtures/ansible/users.yml의app_users를 읽어 각 항목의dir을mode권한으로 만드세요 —/root/ans/loops/deploy(0750),/root/ans/loops/metrics(0755),/root/ans/loops/backup(0700).- 같은 반복에
when을 걸어0755보다 엄격한 항목의 디렉터리에만PRIVILEGED파일을 남기세요 —/root/ans/loops/deploy/PRIVILEGED와/root/ans/loops/backup/PRIVILEGED는 생기고/root/ans/loops/metrics/PRIVILEGED는 생기면 안 됩니다. loop_control의label로 로그를 정리하고 실행 출력을/root/ans/loops/out/run.txt로 저장하세요. 로그에item=deploy형태의 축약 라벨이 보이고 딕셔너리 전체는 보이면 안 됩니다.until/retries/delay를 쓴 대기 태스크를 만들고, 성공 결과를/root/ans/loops/out/ready.txt에ready라는 내용으로 남기세요.- 환경(
dev,stage,prod) × 컴포넌트(app,worker) 조합으로/root/ans/loops/matrix/<환경>-<컴포넌트>.conf6개를 만드세요 (예:/root/ans/loops/matrix/dev-app.conf,/root/ans/loops/matrix/prod-worker.conf). 각 파일에는env=<환경>과component=<컴포넌트>줄이 들어갑니다. /root/ans/loops/collected/로 matrix 의.conf6개를 패턴으로 모아 복사하세요. 파일 이름을 하나씩 적으면 안 됩니다./root/ans/loops/out/loops.json을 만드세요.users(3개, 각 항목에privileged불리언),matrix_files(6) 을 담습니다. 그리고 두 번째 실행 결과를/root/ans/loops/out/run2.txt로 저장하되changed=0이어야 합니다.
참고
- 실습 파드는 실습마다 새로 뜹니다.
/root/ans/inventory/hosts.ini가 없으면 첫 실습에서 만든 것과 같은 인벤토리(web1·web2·db1,ansible_host=127.0.0.1,ansible_port=2222,ansible_user=root,[prod:children]에 web·db)를 먼저 다시 만드세요. 구조는/opt/lab/fixtures/ansible/inventory.sample.ini를 참고하면 됩니다. loop: "{{ app_users }}"처럼 변수를 그대로 넘길 수 있습니다.- 조합은
"{{ envs | product(components) | list }}"형태로 만듭니다. - 흔한 실수 1:
loop안의 태스크가 멱등하지 않아 두 번째 실행에서 반복 횟수만큼 changed 가 나는 것. - 흔한 실수 2: 패턴 조회 결과의 순서에 의존하는 것. 순서는 보장되지 않습니다.
리스트 반복으로 디렉터리 3개 만들기
/root/ans/loops/site.yml 에서 loop 로 /root/ans/loops/simple/ 아래에 alpha, beta, gamma 디렉터리를 만드세요. 태스크는 하나여야 합니다.
loop: 에 리스트를 주고 item 으로 참조합니다. 태스크를 복사하지 마세요.
딕셔너리 리스트 돌기
/opt/lab/fixtures/ansible/users.yml 의 app_users 를 읽어 각 항목의 dir 을 mode 권한으로 만드세요 — /root/ans/loops/deploy(0750), /root/ans/loops/metrics(0755), /root/ans/loops/backup(0700).
픽스처의 app_users 를 vars_files 로 읽습니다. item.name, item.mode 처럼 필드로 접근하세요.
조건에 맞는 항목만 처리하기
같은 반복에 when 을 걸어 0755 보다 엄격한 항목의 디렉터리에만 PRIVILEGED 파일을 남기세요 — /root/ans/loops/deploy/PRIVILEGED 와 /root/ans/loops/backup/PRIVILEGED 는 생기고 /root/ans/loops/metrics/PRIVILEGED 는 생기면 안 됩니다.
loop 와 when 을 함께 쓰면 조건이 항목마다 평가됩니다. mode 가 0755 인 항목은 빠져야 합니다.
로그에 찍히는 라벨 정리하기
loop_control 의 label 로 로그를 정리하고 실행 출력을 /root/ans/loops/out/run.txt 로 저장하세요. 로그에 item=deploy 형태의 축약 라벨이 보이고 딕셔너리 전체는 보이면 안 됩니다.
loop_control 의 label 로 축약합니다. 딕셔너리 전체가 로그에 나오면 안 됩니다.
조건이 참이 될 때까지 재시도하기
until/retries/delay 를 쓴 대기 태스크를 만들고, 성공 결과를 /root/ans/loops/out/ready.txt 에 ready 라는 내용으로 남기세요.
until/retries/delay 세 가지가 함께 필요합니다. 성공 결과를 파일로 남기세요.
두 리스트의 모든 조합 만들기
환경(dev,stage,prod) × 컴포넌트(app,worker) 조합으로 /root/ans/loops/matrix/<환경>-<컴포넌트>.conf 6개를 만드세요 (예: /root/ans/loops/matrix/dev-app.conf, /root/ans/loops/matrix/prod-worker.conf). 각 파일에는 env=<환경> 과 component=<컴포넌트> 줄이 들어갑니다.
product 필터로 조합을 만듭니다. 환경 3개 × 컴포넌트 2개 = 6개 파일입니다.
패턴으로 파일 모으기
/root/ans/loops/collected/ 로 matrix 의 .conf 6개를 패턴으로 모아 복사하세요. 파일 이름을 하나씩 적으면 안 됩니다.
파일 이름을 하나씩 적지 말고 패턴으로 목록을 얻으세요. 내용이 원본과 같아야 합니다.
반복 결과 보고서와 재실행 확인
/root/ans/loops/out/loops.json 을 만드세요. users(3개, 각 항목에 privileged 불리언), matrix_files(6) 을 담습니다. 그리고 두 번째 실행 결과를 /root/ans/loops/out/run2.txt 로 저장하되 changed=0 이어야 합니다.
사용자별 privileged 여부와 조합 파일 수를 JSON 으로 정리하고, 두 번째 실행이 changed=0 인지 확인하세요.