data engineering

ansible playbook을 사용한 간단한 흐름 이해

qkqhxla1 2021. 1. 13. 19:23

개념 : https://kim-dragon.tistory.com/13


참고 블로그 : https://blog.naver.com/alice_k106/221333208746


guide : https://docs.ansible.com/ansible/latest/user_guide/index.html


playbook guide 좋은 블로그 : https://moonstrike.github.io/ansible/2016/09/22/Ansible-Playbooks.html



ansible playbook에 대해서만 튜토리얼 형식으로 간단하게 다시 정리합니다. 튜토리얼이나 블로그를 많이 봤는데 일단 한번 동작하는걸 확인하고 모르는게 있으면 구글링으로 확장해서 찾아나가는 저로써는 뭔가 이해하기가 쉽지가 않더군요.


ansible은 여러 시스템들의 환경 관리를 해주는 오픈 소스입니다. 특정 환경변수를 여러 서버에 배포하거나, 특정 동작을 여러 서버에서 실행시키도록 하거나 하는데 쓰이는 infra관리 오픈소스 툴입니다. 


playbook은 https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#playbook-syntax 의 playbook syntax에도 나와있듯이 yml을 작성하고 ansible-playbook ~~.yml로 실행시키면 됩니다.


현재 playbook관련된 yml을 infra라는 디렉터리 안에서 전부 관리합니다. 

infra라는 디렉터리 안에 ansible.cfg파일과 inventory, roles 두 개의 디렉터리가 있습니다. 첫 예제로 만든 디렉터리의 구조를 캡쳐하면 아래와 같습니다.

ansible.cfg파일은 ansible의 기본적인 설정들을 세팅해주는 cfg파일인데 아래와 같이 설정되어 있습니다.


infra/ansible.cfg

[defaults]
inventory = ./inventory/hosts  # inventory의 위치
forks = 10
gathering = implicit

[ssh_connection]
# do not use the sftp.
scp_if_ssh = True

[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = True

./inventory/hosts에는 https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#intro-inventory 처럼 host들의 목록이 있습니다.


infra/inventory/hosts

[myserver]
10.10.10.10
10.10.10.11
10.10.10.12

[mysecondserver]
10.10.10.13
10.10.10.14

이런식으로 그룹별로 정리를 해놨습니다.


infra/roles내부에는 https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html 의 role directory structure처럼 정리를 해놨습니다.



이제 테스트를 해봅시다. 간단하게 hello world가 들어있는 텍스트파일을 모든 서버로 배포한다고 가정해봅시다.

첫번째로 infra/roles/copy-test라는 디렉터리를 만들고 copy-test 디렉터리 안에 files디렉터리와 tasks디렉터리를 생성합니다.(infra/roles/copy-test/files, infra/roles/copy-test/tasks가 생성됨.)


files디렉터리 안에 hello.txt를 만들고 내용을 hello world!로 채워넣습니다. 밖으로 나와 tasks디렉터리로 들어가 main.yml을 만듭니다. 이런식의 구조를 만드는 이유는 바로 위에 참조한 공식 docs에도 나와있지만 ansible이 실행시 기본적으로 참조하는 위치나 파일 이름이 이것이기 때문입니다. 

어쨌든 infra/roles/copy-test/tasks/main.yml을 열고 yml파일을 작성합니다. playbook yml syntax는 다음과 같습니다.

https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#playbook-syntax

이것과 구글링을 해서 copy예제를 만들어봅니다.


infra/roles/copy-test/tasks/main.yml

- name: copy-test
  copy:
    src: hello.txt
    dest: /home/hello.txt
    owner: user
    group: user
    mode: 0644

-name은 이름이고, copy는 copy module을 사용하겠다는 뜻입니다.

ansible copy module : https://docs.ansible.com/ansible/2.4/copy_module.html


src의 hello.txt는 위에서 infra/roles/copy-test/files/hello.txt 에 만든 hello.txt를 자동으로 참조하도록 하게 할겁니다.(아래에서 추가설명) dest는 우리가 보낼 서버의 /home/hello.txt위치에 우리가 만든 hello.txt가 생성된다는 의미입니다. owner와 group은 실제 계정정보를 넣어줍니다. mode는 눈치챘겠지만 file mode입니다.


이제 지금까지 만든 roles를 사용하기 위한 playbook yml을 만들어봅시다. 위의 role directure structure 캡쳐본에서 webserver.yml같은걸 만들겁니다. infra/copy-test.yml을 만듭니다.


infra/copy-test.yml

- hosts: myserver
  roles:
    - copy-test

여기서 hosts의 myserver 는 맨 위에서 infra/ansible.cfg의 inventory에 path를 지정했던, infra/inventory/hosts내부의 myserver그룹의 서버에 적용한다는 의미입니다. (myserver그룹은 위에서 찾아보면 10.10.10.10, 10.10.10.11, 10.10.10.12임.)


roles에 있는 copy-test는 위에서 만들었던 infra/roles/copy-test를 사용한다는 의미입니다. 위에서 hello.txt를 참조한다했는데 roles을 copy-test로 설정해줬으므로 copy-test 내부의 files 폴더를 자동으로 참조하게 됩니다.

이제 실행시켜봅시다.


infra디렉터리 안에서 ansible-playbook copy-test.yml으로 playbook을 실행시키면 gathering fact이후에 제가 위에서 작업한 task를 실행시키는 로그가 나옵니다. 아래는 일부 결과를 캡쳐했습니다.

이런식으로 잘되었고 새로 적용이 되면 changed=1, 이미 있어서 특별한 변화가 없으면 changed=0등으로 로그가 찍힙니다. 우리가 새로 하려고 했던 copy작업은 hello.txt 를 각 서버의 /home/hello.txt로 복사하는 작업이었습니다.

각각 서버로 들어가서 /home/hello.txt를 보면 우리가 만들었던 텍스트가 들어가있음을 확인할 수 있습니다.


그럼 이번엔 ansible로 pip3를 설치하고 pip, setuptools를 업그레이드한다고 가정해봅시다. 현재 제가 설치해야 하는 서버들은 전부 우분투며 python3만 설치된 상태입니다.


새 파일 이름은 pip-install.yml로 하려고 합니다. 위에서 ansible.cfg같은 기본 설정 파일은 다 만들어줬으므로 추가해야 하는 파일은 infra/pip-install.yml, infra/roles/pip-install만 하면 됩니다.


infra/pip-install.yml

- hosts: myserver
  roles:
    - pip-install

infra/pip-install/tasks/main.yml

- name: pip3 install
  apt:
    name: python3-pip  # apt-get install python3-pip를 한다.

- name: pip3,setuptools upgrade
  pip:
    name: pip  # pip install --upgrade pip를 한다.
    executable: pip3
    extra_args: --upgrade  
  pip:
    name: setuptools  # setuptools도 업그레이드 함.
    executable: pip3
    extra_args: --upgrade

이런식으로 만들어줍니다. main.yml에서 이번엔 apt, pip 모듈을 사용했습니다.

apt 모듈 : https://docs.ansible.com/ansible/2.4/apt_module.html

pip 모듈 : https://docs.ansible.com/ansible/2.4/pip_module.html


중간의 pip3, setuptools upgrade는 반복되므로, 아래처럼 loop를 쓸 수도 있습니다.

추가적인 정보는 https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html 에서 참조.

- name: pip3,setuptools upgrade
  pip:
    name: "{{ item }}"
    executable: pip3
    extra_args: --upgrade
  with_items:
    - pip
    - setuptools

이후 다시 infra안에서 ansible-playbook pip-install.yml로 실행시키면 됩니다. 에러 나면 에러메시지를 보고 구글링해서 수정하면 끝. 전 이미 한번 한 상태라 ok만 뜨지만 처음 잘 되면 changed가 뜹니다.