로컬에서 개발 중인 Ansible role 테스트하기
개발 중인 Ansible role을 편리하게 테스트하기 위해 사용하고 있는 방법을 공유한다. Ansible이 제시하는 정석대로 role을 다루는 경우에 적합한 방법이라 그 정석에 대해서도 살펴본다.
이어질 내용을 요약하면 아래와 같다.
- Ansible role을 다루는 정석
- role 하나 당 Git repository 하나
- ansible-galaxy로 필요한 role들을 다운로드
- symbolic link를 쓰면 개발 중인 role의 테스트를 편하게 할 수 있다.
Ansible Role
Ansible playbook을 여러개 만들다 보면 중복되는 코드가 생긴다. 동일한 코드가 여러 벌이 되면 관리가 불가능해지기 때문에 이런 것들은 ‘모듈’ 혹은 ‘라이브러리’ 로 만들어 재사용해야 하는데 Ansible에선 role이 그런 역할을 한다.
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html
Ansible role을 다루는 정석
1. role 당 Git repository 하나
모든 코드는 Git으로 관리해야 한다. Ansible role도 예외가 아니다.
Ansible role의 Git repository는 어떤 단위로 만들어야 할까? 하나의 Git repository 에서 여러 role들을 포함하는 방법을 생각할 수도 있는데 role마다 Git repository를 만드는 것이 Ansible이 제시하는 체계에 맞는 방법이다.
전자를 생각했다면 role 하나의 코드 분량이 많지 않은데 전용 Git repository를 만드는 것은 비효율적이라는 생각 때문일 것이다. 하지만 Git repository는 관리 대상 코드가 논리적으로 독립된 것이기만 하면 코드의 분량과 관계 없이 만들 수 있고 그렇게 하는 것이 바람직하다. Git repository 하나가 방대한 리눅스 커널 코드를 관리할 수도 있지만 스크립트 하나를 관리해도 문제될 것이 없다. 관리 비용 때문에 repository 수를 쉽게 늘리기 어려운 Subversion과 차별화되는 점이다.
개별 Git repository로 관리하면 아래와 같은 장점이 있다.
- ansible-galaxy가 role을 다운로드하는 체계에 부합한다. requirements.yml에서 필요한 role마다 Git repository와 branch를 설정하는 방식이다.
- 각각의 role 별로 원하는 branch의 코드를 사용할 수 있다. master branch에 merge되기 전 개발용 branch의 코드를 사용할 수 있다.
- 로컬에서 role을 수정하면서 테스트하기 편리하다.
2. ansible-galaxy로 다운로드
playbook이 있는 디렉토리에 requirements.yml
을 만들고 다운로드할 role의 목록을 작성한다.
예를 들어 아래처럼 한다.
1- src: https://git.psh.kr/ansible_role/ec2_linux_common.git
2 scm: git
3 name: ec2_linux_common
4 version: master
5
6- src: https://git.psh.kr/ansible_role/cloudwatch_agent.git
7 scm: git
8 version: master
아래처럼 필요한 role들을 다운로드하는 스크립트를 만들어 쓰면 편리하다. 파일 이름은 get_roles.sh
이라고 하자.
1ansible-galaxy install --force --ignore-errors -r requirements.yml -p roles
이 스크립트는 requirements.yml
에 기술된 role들을 roles/ 디렉토리에 다운로드한다.
Ansible playbook은 기본적으로 roles/ 디렉토리에서 role을 찾는다.
- --force 옵션은 이미 다운받은 role을 최신 코드로 업데이트하기 위해 필요하다.
- --ignore-errors 옵션은 뒤에 설명할 symbolic link를 이용해 테스트하는 방법을 쓸 때 ansible-galaxy가 중간에 에러를 내고 멈추지 않게 한다.
아래는 roles/.gitignore
의 내용이다.
1*
2!.gitignore
.gitignore
를 제외한 모든 다운받은 role 코드를 Git이 무시하게 한다.
Symbolic link로 테스트
위에서 설명한 것처럼 requirements.yml
에 필요한 role을 기술해서 다운로드 받아 써야 한다. 하지만 로컬에서 수정 중인 role을 테스트할 때도 같은 방식을 쓰면 코드 변경을 할때마다 git commit, push 후 ansible-galaxy 실행을 반복해야 해서 불편하다.
해결책은 roles/ 아래에 다운로드한 디렉토리를 삭제하고, 작업 중인 로컬 Git repository를 가리키는 symbolic link를 만드는 것이다. ansible-galaxy 명령을 --force 옵션으로 실행해도 symbolic link는 덮어쓰지 않는다는 점을 활용한 것이다.
1$ cd roles
2# 다운로드한 role 삭제
3$ rm -rf ec2_linux_common
4
5# symbolic link인 ec2_linux_common 이 작업 디렉토리인 ~/git/ansible_role/ec2_linux_common 을 가리키게 된다.
6$ ln -s ~/git/ansible_role/ec2_linux_common .
이렇게 하면 코드를 수정한 후 commit, push할 필요 없이 role을 사용하는 playbook을 바로 실행해 테스트할 수 있다.
아래는 get_roles.sh
을 실행한 결과이다. ansible-galaxy가 warning 메시지를 출력하지만 symbolic link는 보존된다.