Variable Precedence and Working With Facts
한국어 원문으로 표시합니다.
목표
값을 코드에서 분리해 여러 자리에 배치하고, 그중 무엇이 이기는지 직접 확인합니다. 팩트와 register 로 실행 중에 얻은 값도 다룹니다.
왜 중요한가
"변수를 바꿨는데 반영이 안 된다"는 질문의 답은 거의 언제나 우선순위입니다. Ansible 은 같은 이름의 변수를 여러 자리에서 받아들이고, 충돌해도 오류를 내지 않고 조용히 더 센 쪽을 씁니다. 이 성질은 편리하지만 디버깅을 어렵게 만듭니다. 그래서 덮어써도 되는 값은 약한 자리(롤의 defaults)에, 반드시 지켜야 할 값은 강한 자리에 두는 설계 감각이 필요합니다. 명령줄 -e 는 무엇이든 이기지만 어디에도 기록되지 않으므로, 장애 대응에서 썼다면 반드시 코드로 되돌려 놔야 합니다. 그러지 않으면 다음 배포가 조용히 그 값을 지웁니다.
단계
/root/ans/vars/site.yml을 만들고 플레이vars:에app_name: checkout을 정의하세요. 그 값을/root/ans/vars/out/app_name.txt에 쓰세요./root/ans/vars/vars/common.yml에app_port: 9090을 두고vars_files로 읽어 들이세요. 값을/root/ans/vars/out/app_port.txt에 쓰세요./root/ans/inventory/group_vars/web.yml에node_role: frontend를,/root/ans/inventory/host_vars/web1.yml에node_role: canary를 두세요. 두 디렉터리는 첫 실습에서 만든/root/ans/inventory/hosts.ini와 같은 자리에 있어야 자동으로 읽힙니다. web2 에서는 frontend 로, web1 에서는 canary 로 보여야 합니다.- 명령을 실행하고
register로 결과를 받은 뒤, 표준 출력만/root/ans/vars/out/uptime.txt에 저장하세요. gather_facts를 켜고 수집된 팩트 중 호스트 이름·아키텍처·시스템을 담은 JSON 을/root/ans/vars/out/facts.json으로 저장하세요.-e app_port=9999로 실행해 그 값을/root/ans/vars/out/precedence.txt에 저장하세요. 2번에서 만든app_port.txt는 9090 그대로여야 합니다.set_fact로app_name과app_port를 이어 붙인 값을 만들어/root/ans/vars/out/endpoint.txt에checkout:9090형태로 저장하세요./root/ans/vars/out/summary.json을 만드세요.app(=checkout),port(=9090),role(web1 의 호스트 변수 값),host(수집한 팩트의 호스트 이름) 네 키를 가져야 합니다.
참고
- 실습 파드는 실습마다 새로 뜹니다.
/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를 참고하면 됩니다. ansible-inventory -i /root/ans/inventory/hosts.ini --list로 그룹/호스트 변수가 실제로 어떻게 합쳐졌는지 볼 수 있습니다.debug모듈의var:로 특정 변수의 최종 값을 즉시 확인할 수 있습니다.- 흔한 실수 1: 4번에서 register 객체 전체를 파일에 쓰는 것.
.stdout만 필요합니다. - 흔한 실수 2: 6번에서 같은 파일을 덮어써 앞 단계 결과를 잃는 것. 단계마다 다른 파일에 남기세요.
플레이 변수 정의하고 쓰기
/root/ans/vars/site.yml 을 만들고 플레이 vars: 에 app_name: checkout 을 정의하세요. 그 값을 /root/ans/vars/out/app_name.txt 에 쓰세요.
플레이의 vars: 아래에 값을 두고, copy 모듈의 content 에서 Jinja2 로 참조하세요.
변수 파일 분리하기
/root/ans/vars/vars/common.yml 에 app_port: 9090 을 두고 vars_files 로 읽어 들이세요. 값을 /root/ans/vars/out/app_port.txt 에 쓰세요.
vars_files: 는 경로 목록입니다. 값이 늘어나면 플레이에서 떼어 내는 것이 관례입니다.
그룹 변수와 호스트 변수 만들기
/root/ans/inventory/group_vars/web.yml 에 node_role: frontend 를, /root/ans/inventory/host_vars/web1.yml 에 node_role: canary 를 두세요. 두 디렉터리는 첫 실습에서 만든 /root/ans/inventory/hosts.ini 와 같은 자리에 있어야 자동으로 읽힙니다. web2 에서는 frontend 로, web1 에서는 canary 로 보여야 합니다.
디렉터리 이름이 곧 규칙입니다. group_vars 아래 파일 이름은 그룹 이름, host_vars 아래는 호스트 이름입니다.
명령 결과를 변수에 담기
명령을 실행하고 register 로 결과를 받은 뒤, 표준 출력만 /root/ans/vars/out/uptime.txt 에 저장하세요.
register 로 받은 것은 객체입니다. 파일에는 그중 표준 출력만 넣으세요.
팩트 수집해 JSON 으로 남기기
gather_facts 를 켜고 수집된 팩트 중 호스트 이름·아키텍처·시스템을 담은 JSON 을 /root/ans/vars/out/facts.json 으로 저장하세요.
gather_facts 를 켜고 ansible_facts 의 일부를 골라 JSON 으로 씁니다. to_nice_json 필터가 도움이 됩니다.
명령줄 변수로 덮어쓰기
-e app_port=9999 로 실행해 그 값을 /root/ans/vars/out/precedence.txt 에 저장하세요. 2번에서 만든 app_port.txt 는 9090 그대로여야 합니다.
-e 로 넘긴 값이 가장 셉니다. 앞 단계에서 저장한 파일은 덮어쓰지 말고 다른 이름으로 남기세요.
set_fact 로 값 조합하기
set_fact 로 app_name 과 app_port 를 이어 붙인 값을 만들어 /root/ans/vars/out/endpoint.txt 에 checkout:9090 형태로 저장하세요.
두 변수를 이어 붙인 새 값을 만들어 파일에 씁니다. 형식은 이름:포트 입니다.
변수·팩트·호스트 변수를 합친 요약 만들기
/root/ans/vars/out/summary.json 을 만드세요. app(=checkout), port(=9090), role(web1 의 호스트 변수 값), host(수집한 팩트의 호스트 이름) 네 키를 가져야 합니다.
네 개의 키(app, port, role, host)를 가진 JSON 을 만듭니다. role 은 web1 의 호스트 변수, host 는 수집한 팩트에서 옵니다.