Ansible
설치 및 기본 기능 익히기
Ansible 설치 및 설정
ansible 설치하기
CentOS
# rpm -qa | grep epel-release || yum install -y epel-release # yum install -y epel-release
Ubuntu
$ sudo apt-get install software-properties-common $ sudo apt-add-repository ppa:ansible/ansible $ sudo apt-get update $ sudo apt-get install ansible
ansible 설정 : /etc/ansible/ansible.cfg 또는 홈디렉토리에 .ansible.cfg 파일 설정을 함.
- ansible은 ssh key를 이용하여 로그인을 하므로 host key 체크하는 부분을 없애려면 ssh_config 를 조정하거나 ansible 설정에 host_key_checking = False 를 추가해줌
/etc/ansible/ansible.cfg 를 보면 파일복사시 기본값은 sftp를 이용하도록 되어 있습니다.
보안상의 이유로 sshd_config에 sftp를 막아놓은 경우 ansible 설정파일에서 [ssh_connection] 섹션에 scp_if_ssh = True 옵션을 추가하면 scp를 이용할 수 있습니다. (2.2.0 에서 확인)
인벤토리 설정 : /etc/ansible/hosts or -i 옵션으로 지정
$ cat hosts [localhost] localhost [test] 192.168.33.13
ssh key 를 생성하여 암호없이 로그인 하도록 설정하기
기본 기능 익히기
ping 모듈로 연결 확인하기
$ ansible -i hosts test -m ping 192.168.33.13 | SUCCESS => { "changed": false, "ping": "pong" }
해당 시스템 데이터 수집. playbook 에서 다른 모듈이 사용을 할 수 있음.
$ ansible -i hosts test -m setup 192.168.33.13 | SUCCESS => { "ansible_facts": { "ansible_all_ipv4_addresses": [ "10.0.2.15", "192.168.33.13" ], "ansible_all_ipv6_addresses": [ "fe80::48:bff:fe7c:cbf", "fe80::a00:27ff:fead:f341" ], "ansible_architecture": "x86_64", "ansible_bios_date": "12/01/2006", "ansible_bios_version": "VirtualBox", ....
모듈 기능 익히기
$ ansible -i hosts test -m file -a 'path=/etc/fstab' $ ansible -i hosts test -m file -a 'path=/tmp/mytest state=directory' $ ansible -i hosts test -m copy -a 'src=/etc/fstab dest=/tmp/fstab'
command 모듈 / shell 모듈 : 임의의 명령 실행 가능하나 가능한 다른 모듈을 이용하여 처리를 하는 것이 멱등성을 유지할 수 있기 때문에 좋음.
멱등성 개념 이해하기 : 여러 번 적용해도 결과가 바뀌지 않는다.
http://docs.ansible.com/ansible/modules_by_category.html
playbook
playbook 을 이용하여 한 번에 여러가지 작업을 할 수 있음.
YAML 파일로 구성
$ cat example-play.yml --- - hosts: localhost vars: motd_warning: 'my test' tasks: - name: setup a MOTD copy: dest=/tmp/motd content={{ motd_warning }} $ ansible-playbook -i hosts example-play.yml --sudo
타깃 : 인벤토리에서 지정한 호스트
변수 : vars_files 파일을 통해 다른 파일에서 읽어올 수도 있음. 사람의 입력을 통해서 받을 수도 있음. 변수는 {{ motd_warning }} 형태로 사용할 수 있음.
task : ansible 이 수행할 액션 목록
핸들러 : 구문은 task 와 같으며 task에서 호출될 때만 핸들러가 작동함.
playbook 모듈 : 커맨드라인에서 모듈을 사용하는 것과 조금 다르게 다른 모듈과 setup 모듈에서 사용가능한 많은 팩트를 가지고 있음. 많이 사용하는 것은 template 모듈. (jinja2 template)
ansible playbook 예제 : https://github.com/ansible/ansible-examples
Playbook example
http://docs.ansible.com/ansible/playbooks_intro.html
1)
--- - hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: - name: ensure apache is at the latest version yum: name=httpd state=latest - name: write the apache config file template: src=/srv/httpd.j2 dest=/etc/httpd.conf notify: - restart apache - name: ensure apache is running (and enable it at boot) service: name=httpd state=started enabled=yes handlers: - name: restart apache service: name=httpd state=restarted
2) using YAML dictionaries to supply the modules with their key=value
arguments
--- - hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: - name: ensure apache is at the latest version yum: name: httpd state: latest - name: write the apache config file template: src: /srv/httpd.j2 dest: /etc/httpd.conf notify: - restart apache - name: ensure apache is running service: name: httpd state: started handlers: - name: restart apache service: name: httpd state: restarted
루핑
with_items
- name: Install http and php etc yum: name={{ item }} state=present with_items: - httpd - php - php-mysql - git - libsemanage-python - libselinux-python
조건절 실행
when
- name: stop chronyd in CentOS service: name=chronyd state=stopped enabled=no when: ansible_os_family == 'RedHat'
대규모 프로젝트
Include
플레이북을 여러 개의 파일로 분리하고, 다른 위치에서 분리된 파일을 포함하기 : 변수, playbook, task, handler include 가능함.
tasks: - include: tasks/foo.yml
Role
같은 기능을 수행하는 여러 개의 파일을 포함하는 role 사용하기. ansible 에서는 가능한한 Role을 사용할 것을 적극 추천하고 있음.
Now that you have learned about tasks and handlers, what is the best way to organize your playbooks? The short answer is to use roles! Roles are ways of automatically loading certain vars_files, tasks, and handlers based on a known file structure. Grouping content by roles also allows easy sharing of roles with other users.
http://docs.ansible.com/ansible/playbooks_roles.html
Example project structure:
site.yml webservers.yml fooservers.yml roles/ common/ files/ templates/ tasks/ handlers/ vars/ defaults/ meta/ webservers/ files/ templates/ tasks/ handlers/ vars/ defaults/ meta/
In a playbook, it would look like this:
--- - hosts: webservers roles: - common - webservers
참고로 새로운 role을 만들 경우 ansible-galaxy 에서 init 명령을 이용하연 skeleton 을 이용하여 새로운 role 구성을 해주기 때문에 편리하다.
$ ansible-galaxy init mytest . `-- mytest |-- README.md |-- defaults | `-- main.yml |-- files |-- handlers | `-- main.yml |-- meta | `-- main.yml |-- tasks | `-- main.yml |-- templates |-- tests | |-- inventory | `-- test.yml `-- vars `-- main.yml
http://docs.ansible.com/ansible/playbooks_best_practices.html 에서 Directory Layout 정보 참고.
현재 구성한 ansible role 이해하기
Playbook 테스팅하기
dry run mode (-C 옵션) 잘 활용
개발 환경에서 먼저 확인 후 production 적용 (개인pc에서 테스팅 -> dev -> prod)
Playbook, Role 만들 때 지켜야 할 부분
README.md 파일을 꼭 만들자. https://guides.github.com/features/mastering-markdown/ 등을 참고하여 markdown 으로 문서를 작성한다. git markdown 테스팅은 https://gist.github.com/ 등을 이용하면 편리할 듯 하다.
name을 명시적으로 선언한다.
멀티 OS 를 지원하도록 구성
tags 활용하기
변수 선언
vars : 변하지 않고 고정된 값을 설정할 경우. 만약 설정 변경을 할 가능성이 있으면 vars 디렉토리에 두지 않는다.
defaults : 기본값 설정. 변경 가능한 모든 값에 대해서 기본 값을 설정을 함.
group_vars : 변경 가능한 값에 대해서 host group 별로 설정을 함.
변수를 설정했어도 커맨드 라인에서 -e 옵션으로 변경을 할 수 있으며 (extra vars) 커맨드 라인에서 설정한 값이 제일 우선순위를 가진다.
vars 에 설정한 값은 커맨드 라인에서 -e 옵션으로 변경을 할 수는 있지만 playbook 안에서는 변경을 하지 못하기 때문에 group_vars 에서 사용을 하지 못한다.
변경 가능한 값이냐 아니냐를 잘 판단하여 변수 설정을 해야 한다.
부가기능
ansible vault : 비밀번호 등 민감한 자료를 암호화 할 수 있는 프로그램. http://docs.ansible.com/ansible/playbooks_vault.html
참고자료
Ansible 설정 관리 : 한글 번역판인데 2013년도 책을 번역한 것임.
http://www.slideshare.net/deview/1a7ansible?qid=2def7102-fd47-478d-a281-24677153f5fe&v=&b=&from_search=1 : "Ansible 설정 관리" 번역자가 만든 공개 자료
http://docs.ansible.com/ansible/playbooks_best_practices.html
ansible 매뉴얼 일부 한글 번역 자료 : https://github.com/mcchae/ansible_doc_ko
ansible 문서 pdf 만들기
ansible 문서 pdf 만들기
https://github.com/ansible/ansible/issues/4265 : pdf 만드는 여러가지 방법이 나옴. 아래 url도 소개하고 있음. centos7 예제도 있는데 문서 목차가 안 나와서 불편함. html 파일로 만드는 작업은 간단하게 작업을 할 수 있음.
https://github.com/bonndan/ansible-userguide-pdf : ubuntu 에서 문서 생성 하는 방법. 전체 문서를 하나의 pdf로 해서 볼 수 있음. 근데 내가 해보니 문서 목차 부분이 안 나옴. 이유는 모름.
ansible galaxy
http://docs.ansible.com/ansible/galaxy.html
ansible galaxy 를 이용하면 ansible galaxy 웹사이트에서 ansible playbook 을 자동으로 가져와서 설치 할 수 있다.
ansible galaxy 에서 유용한 옵션
- --roles-path : galaxy 이용하여 설치시 기본는 /etc/ansible/roles 디렉토리에 설치를 한다. 이 부분을 변경할 수 있다. 특정 디렉토리를 지정해서 쓰는 경우에는 ansible.cfg 설정에 넣어두고 쓰는 것이 편리할 것이다. http://docs.ansible.com/ansible/intro_configuration.html#galaxy-settings
- -c : -c 옵션을 주면 SSL 인증서 에러를 무시함. -c, --ignore-certs . Ignore TLS certificate errors.
- -r requirements.yml : 하나의 파일에서 여러개의 roles 설치시 이용
galaxy 에서 requirements.yml 을 이용하여 여러 roles를 설치할 수 있으며 각 roles 에는 dependencies 를 지정해서 의존성 있는 roles을 함께 설치하도록 할 수 있다.
자세한 내용은 http://docs.ansible.com/ansible/galaxy.html 문서를 참고하면 되며 아래에는 간단한 예제만 복사를 해 두었다.
$ ansible-galaxy install username.role_name $ ansible-galaxy install --roles-path . geerlingguy.apache $ ansible-galaxy install geerlingguy.apache,v1.0.0 $ ansible-galaxy install git+https://github.com/geerlingguy/ansible-role-apache.git,0b7cd353c0250e87a26e0499e59e7fd265cc2f25 $ ansible-galaxy install -r requirements.yml
사내 gitlab을 이용하여 가져올 때는 어떻게 해야 할까? 해당 git repo에 대해서 deploy key를 먼저 활성화했다고 가정하고 설명을 한다.
git clone 명령이 문제없이 동작하는지 먼저 확인
$ git clone git+ssh://myuser@gitlab.example.net/ansible/exmaple.git
galaxy 로 내부 gitlab에서 roles 가져오기
$ ansible-galaxy -c install --roles-path . git+ssh://myuser@gitlab.example.net/ansible/exmaple.git
git 에서 roles을 가져오는 경우 해당 roles의 meta/ 디렉토리의 정보를 참고할 것인데 만약 meta/ 디렉토리가 없는 경우 아래와 같은 에러가 나기는 하지만 git 소스는 정상적으로 가져오기는 했다.
그렇지만 ansible playbook 을 만들 때 개별 roles 마다 meta/ 디렉토리를 만들고 정보를 넣어주는 것이 좋은 방법일 것이다.
$ ansible-galaxy -c install --roles-path . git+ssh://myuser@gitlab.example.net/infra/exmaple.git - extracting exmaple to ./example ERROR! Unexpected Exception: [Errno 2] No such file or directory: u'./example/meta/.galaxy_install_info' to see the full traceback, use -vvv
ansible-galaxy 로 role을 다운로드 받은 경우에는 다시 다운로드를 받지 않는다. -f 옵션을 주면 강제로 덮어쓰기를 하며 수동으로 만든 파일이 있는 경우에는 삭제가 된다.
git의 tag를 준 경우에도 ansible-galaxy 에서 버전체크를 하여 업데이트를 하지 않는다. 최신 버전의 role로 맞추려면 무조건 -f 옵션을 해 주어야 한다.
role에서도 의존성 설정을 할 수 있는데 meta/main.yml 파일에 동일한 형태로 필요한 role을 넣어주면 된다. gitlab연동도 동일하게 잘 된다.
ansible-galaxy init 으로 만든 경우에 자동생성된 meta/mai.yml에 dependencies: [] 으로 생기는데 의존성 있는 role을 지정할 때는 [] 를 제거해야 한다. 영문으로 주의사항이 나와있지만 이 부분을 안 보고 넘길 수 있다.
ansible-pull
ansible-pull을 이용하면 git에 있는 ansible playbook을 가져와서 로컬 컴퓨터에 적용을 할 수 있다.
github 또는 gitlab에 project를 만든다. top level에 local.yml 파일을 만든다. 아래 예제의 local.yml 형태로 만들어서 git에 올린다.
아래에서 become은 sudo를 이용하여 root로 실행을 하기 위하여 추가를 한 것이다. become이 없는 경우 /tmp 디렉토리 밑에 쓰기 작업은 할 수 있지만 root 권한이 필요한 경우에는 권한때문에 실행이 안된다.
$ cat local.yml --- - hosts: localhost become: yes vars: motd_warning: 'my test' tasks: - name: setup a MOTD copy: dest=/tmp/motd content={{ motd_warning }} - name: setup a MOTD to /usr/local/bin copy: dest=/usr/local/bin/motd content={{ motd_warning }}
ansible-pull 실행
$ ansible-pull -d /tmp/test -i "127.0.0.1," -U git+ssh://myuser@gitlab.example.net/taejoon.moon/pulltest.git --private-key=/home/test/.ssh/gitlab_deploy.key
사내 gitlab에서 http 방식으로 ansible-pull을 실행하는 경우에는 인증정보를 계속 물어보고 다운로드가 안되었다. 정확한 이유는 모르겠다.
그래서 git deploy key를 이용한 방식으로 다운로드를 하도록 했다. 이 경우에는 git deploy key에 대한 ssh private key 를 지정해야 한다. ssh 옵션 설정이 필요할 수도 있을 것이다.
ansible-pull 의 몇가지 옵션 설명이다. 일반적인 경우 -d, -C 옵션은 지정하지 않아도 상관이 없을 것이고 -o 옵션은 cron 을 이용하여 주기적으로 ansible-pull 을 실행할 때 유용한 옵션이다.
-d : checkout 할 파일을 저장할 디렉토리이다. 지정하지 않으면 ~/.ansible/pull/ 디렉토리 밑에 다운로드를 받는다.
-C : CHECKOUT 할 branch, tag, commit을 지정한다. 지정하지 않으면 보통은 master를 사용할 것이다.
-o, --only-if-changed : Only run the playbook if the repository has been updated. repository 가 업데이트 된 경우에만 playbook을 실행한다.
ansible-pull 참고자료
https://www.stavros.io/posts/automated-large-scale-deployments-ansibles-pull-mo/
https://github.com/ansible/ansible-examples/blob/master/language_features/ansible_pull.yml
ec2의 user_data 이용하여 실행을 할 경우
ansible을 직접 실행할 때는 문제가 없지만 ec2의 user_data 를 이용하여 실행을 할 때에는 remote_tmp, local_tmp 설정이 없는 경우 문제가 있었습니다.
http://docs.ansible.com/ansible/intro_configuration.html#local-tmp
http://docs.ansible.com/ansible/intro_configuration.html#remote-tmp
해당 설정은 ansible 에서 사용하는 임시디렉토리 설정인데 아래와 같이 명시적으로 넣어주지 않은 경우 ansible-playbook을 실행하는 디렉토리에 .ansible/tmp 파일을 만들었습니다.
cat > ~/.ansible.cfg << EOF [defaults] remote_tmp = $HOME/.ansible/tmp local_tmp = $HOME/.ansible/tmp EOF
그래서 ansible 에서 file copy 등을 할 때 임시디렉토리에서 소스를 못 찾아서 에러가 나는 경우가 있었습니다.
주의사항
Ansible 2.0.0.2 에서 tags를 이용하여 특정 role만 실행하는 기능이 안되는 증상
ansible 에서 tags를 이용하면 특정 task나 role 만 실행을 할 수 있습니다. 그런데 ansible 2.0.0.2 를 이용을 했을 때 특정 role만 실행이 되지 않고 모든 role이 실행이 되는 버그가 있습니다.
이와 관련된 이슈가 이미 있으며 이후 버전에서는 fix가 된 상태이네요.
Ansible 2.0.0.2 plays all roles even though certain tag is given : https://github.com/ansible/ansible/issues/13984
tags 참고 : http://docs.ansible.com/ansible/playbooks_tags.html
ansible 버전을 업데이트하면 됩니다. pip로 설치시에는 컴파일과 관련된 에러가 나오는 부분이 있어서 PPA를 설정하고 apt 를 이용하여 업데이트를 하면 됩니다.
http://docs.ansible.com/ansible/intro_installation.html#latest-releases-via-apt-ubuntu
$ sudo apt-get install software-properties-common $ sudo apt-add-repository ppa:ansible/ansible $ sudo apt-get update $ sudo apt-get install ansible
--list-task 옵션으로 어떤 task가 실행되는지 확인 가능하며 --list-tags 옵션으로 어떤 tag가 적용되는지 확인 가능하다.
github ssl 인증서
git 에서 ssl 인증서 확인을 하지 않도록 하는 방법이 있음.
git config --global http.sslVerify false
ansible-galaxy 에서는 -c 옵션을 주면 SSL 인증서 에러를 무시함.
-c, --ignore-certs
Ignore TLS certificate errors.