LabHub
배우기 러닝패스 코스

Ansible 실전 · 필터가 없으면 만든다 · 실습

필터가 없어서 shell 로 때우던 것을 플러그인으로 만든다

LabHub 에서 이어서 보기

목표

Jinja2 필터·테스트·룩업과 사용자 모듈을 직접 만들어 플레이북에서 부릅니다. 네 가지가 각각 어디서 실행되는지, 그 자리 차이가 무엇을 할 수 있고 무엇을 할 수 없게 만드는지를 코드로 확인합니다.

왜 중요한가

플레이북이 커지면 어느 팀에나 같은 자리가 생깁니다 — 이름을 다듬고, 숫자를 분류하고, 어딘가의 표를 찾아보는 일입니다. 표준 필터로 안 되면 사람들은 shellsed 로 때우고, 그 순간 그 태스크는 멱등성도 점검 모드도 잃습니다. 플러그인은 그 자리를 위한 것입니다. 다만 아무 데나 넣으면 되는 것이 아니라, 어디서 도는가가 설계의 절반입니다. 필터·테스트·룩업은 컨트롤러에서 돌아서 대상에 아무것도 설치할 필요가 없는 대신 대상의 상태를 볼 수 없고, 모듈은 대상으로 복사되어 거기서 돌기 때문에 상태를 바꿀 수 있는 대신 멱등성과 점검 모드를 스스로 책임져야 합니다. 이 실습은 그 경계를 네 번 넘나들며 손으로 확인합니다.

단계

1. /root/ansplug/ansible.cfg 를 만들어 기본 인벤토리를 ./inventory/hosts.ini 로 지정하세요. /root/ansplug/inventory/hosts.ini 에는 그룹 셋을 적습니다 — webweb1(svc_port 8080, svc_name Web Front 01)과 web2(9090, Web Front 02), dbdb1(5432, Main DB!), edgecache1(443, Edge Cache). 네 호스트 모두 ansible_host=127.0.0.1 ansible_port=2222 이고 [all:vars]ansible_userroot 입니다. 그다음 ansible all -m ansible.builtin.ping -o 를 돌려 표준 출력과 표준 오류를 함께 /root/ansplug/out/ping.txt 에 저장하세요.
2. /root/ansplug/filter_plugins/labfilters.py 를 만들어 slugify 필터 하나를 등록하세요. 이 필터는 문자열을 소문자로 낮추고, 영숫자가 아닌 글자를 모두 - 로 바꾸고, 연달아 나온 - 를 하나로 줄이고, 양 끝의 - 를 떼어 냅니다. 문자열이 아닌 값이 들어오면 AnsibleFilterError 를 던집니다. 그다음 /root/ansplug/slug.yml 을 만들어 'Web Server 01!!' 를 이 필터에 넣은 결과를 /root/ansplug/out/slug.txt 에 쓰고 실행하세요.
3. 같은 /root/ansplug/filter_plugins/labfilters.pyport_class 필터를 더하세요. port_class(value, privileged_below=1024, dynamic_from=49152) 는 포트가 privileged_below 보다 작으면 system, dynamic_from 이상이면 dynamic, 그 사이면 user 를 돌려주고, 정수가 아니면 AnsibleFilterError 를 던집니다. 그다음 /root/ansplug/ports.yml 을 만들어 /root/ansplug/out/ports.txt 에 인벤토리의 네 호스트를 이름 오름차순으로 <호스트> <포트> <분류> 한 줄씩 쓰고 실행하세요.
4. /root/ansplug/test_plugins/labtests.py 를 만들어 reserved_port 테스트를 등록하세요 — 포트 번호가 1024 보다 작으면 참입니다. 그다음 /root/ansplug/reserved.yml 을 만들어 /root/ansplug/out/reserved.txt 에 네 호스트를 이름 오름차순으로 <호스트> <포트> <reserved|free> 한 줄씩 쓰고 실행하세요. 판정은 반드시 is reserved_port 꼴로 부릅니다.
5. /root/ansplug/registry.json{"web": "seoul-a", "db": "seoul-b", "edge": "seoul-c"} 를 적으세요. /root/ansplug/lookup_plugins/labregistry.py 를 만들어 labregistry 룩업을 정의합니다 — 열쇠를 받아 등록부의 값을 돌려주고, registry= 키워드 인자로 다른 파일을 지정할 수 있으며(기본값은 /root/ansplug/registry.json), 파일이 없거나 열쇠가 없으면 AnsibleError 를 던집니다. 그다음 /root/ansplug/regions.yml/root/ansplug/out/regions.txtdb·edge·web 세 그룹의 <그룹> <지역> 을 이 순서로 쓰고 실행하세요.
6. /root/ansplug/collections/ansible_collections/labhub/site/ 에 컬렉션을 놓으세요 — galaxy.ymlnamespacelabhub, namesite 이고, 필터 파일은 plugins/filter/ 아래에 둡니다(2·3단계에서 만든 것을 그대로 복사하면 됩니다). /root/ansplug/ansible.cfgcollections_path = ./collections 를 더하고, /root/ansplug/fqcn.yml'Prod DB 02!!'labhub.site.slugify 에 넣은 결과를 /root/ansplug/out/fqcn.txt 에 쓰고 실행하세요.
7. /root/ansplug/library/lab_marker.py 에 사용자 모듈 lab_marker 를 만드세요 — 인자는 pathcontent 이고, 파일 내용이 이미 같으면 changed=false, 다르면 파일을 쓰고 changed=true 로 끝냅니다. supports_check_mode=True 를 선언하고 점검 모드에서는 쓰지 않습니다. /root/ansplug/marker.ymlweb 그룹에 이 모듈을 돌려 /root/ansplug/out/<호스트이름>.marker 에 그 호스트 이름 한 줄을 쓰게 하고, 플레이북을 두 번 실행해 두 번째 실행의 출력을 /root/ansplug/out/marker_run2.txt 에 저장하세요.
8. /root/ansplug/report.yml/root/ansplug/out/report.txt 에 네 호스트를 이름 오름차순으로 한 줄씩 쓰세요 — <호스트> <이름슬러그> <포트> <포트분류> <reserved|free> <지역> 이고, 이름슬러그는 svc_nameslugify 한 값, 포트분류는 port_class, 다섯째 칸은 reserved_port 테스트, 지역은 그 호스트의 첫 그룹 이름을 labregistry 로 물은 값입니다. 플레이북을 두 번 실행하고 두 번째 실행의 출력을 /root/ansplug/out/report_run2.txt 에 저장하세요.

참고

단계 8개

  1. 네 대를 흉내 내는 인벤토리부터 세운다
  2. 첫 필터 — 컨트롤러에서 도는 순수 함수
  3. 인자를 받는 필터와 잘못된 입력을 끊는 자리
  4. 테스트 플러그인 — 참거짓만 돌려주는 자리
  5. 룩업 — 컨트롤러의 파일을 읽어 오는 자리
  6. 같은 필터를 컬렉션 안으로 옮겨 FQCN 으로 부른다
  7. 모듈은 대상에서 돈다 — 멱등성과 점검 모드는 그쪽 책임이다
  8. 네 종류를 한 플레이북에서 잇는다