4. 자동화 - Automation
● 사람이 수동으로 하던 일을 기계가 처리하는 것
○ 100 대의 서버에 특정 파일이 있는지 체크하기 위해서
■ 수동
● 손으로 100대의 서버에 들어간다.
● 해당 파일이 있는지 체크한다.
■ 자동화
● for i in {1..100}
do
HOST=`printf %03d $i`
echo $HOST
done
5. Ansible
● 인프라를 자동화하기 위한 도구
○ 꼭 클라우드가 아니라도 동작함.
● Python 으로 작성되어 있음.
○ Python 2.x 대 부터 가능하나 Python 3.5 이상을 추천.
6. Ansible의 특징
● Agent가 따로 없다
○ SSH로 접근해서 처리하므로 추가적인 Agent 설치가 필요없음
○ 반대로 ssh key가 처음에 설치될 필요는 있음
● 멱등성
○ 여러번 실행하더라도 같은 결과를 보장.
■ 이건 약간 오해의 소지는 있음.
● 다양한 모듈
○ 이미 많은 사람들이 만들어 둠
7. 그냥 배포 이미지를 이용하면 안되나요?
● AWS등을 보면 현재의 OS 상태를 이미지화한 AMI(Amazon
Machine Images)를 사용해서 인스턴스 생성이 가능함.
○ 많은 곳에서 이런 방식의 배포방식도 이용함
● 그럼 Ansible은 왜?
9. Ansible Components
● ansible
○ 간단한 명령을 수행해 볼 수 있는 ansibe 커맨드
● Inventory
○ 인벤토리가 하나의 배포 리전이라고 생각하면 됨
○ 단순한 웹서버 그룹이 아니라, AWS로 생각하면 Region 같은?
● Playbook
○ 실제로 ansible이 수행해야할 작업을 정의해 둔 것
● Role
○ 특정 작업을 담당하는 기능을 모듈화 한 것들
13. 간단한 실습 #1 - Inventory 만들기
● mkdir local
● cd local
● hosts 파일 생성
○ [test]
127.0.0.1
14. 간단한 실습 #2 - ping 으로 확인하기
● ansible -m ping test -i local
● ansible -m ping all -i local
15. 간단한 실습 #3 - ping 으로 확인하기
● ansible -m ping test -i local
● ansible -m ping all -i local
127.0.0.1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
16. ansible.cfg 파일이 필요 - 해당 작업 디렉토리 루트에 복사
● 타겟 호스트에 어떻게 접근할 것인가에 대한 정보가 필요.
[defaults]
inventory = hosts
forks = 20
remote_port = 22
roles_path = roles:roles/external
#remote_user가 접속한 userid, private_key_file이 접속할 때 사용할 private key를 지정한다.
remote_user = charsyam
private_key_file = ~/.ssh/id_rsa_vagrant
ansible_managed = Ansible managed file, do not edit directly
callback_plugins = ./callback_plugins
stdout_callback = unixy
nocows = 1
retry_files_enabled = False
host_key_checking = False
[ssh_connection]
pipelining = True
ssh_args = -o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=120s
17. 간단한 실습 #2 - ping 으로 확인하기
● ansible -m ping test -i local
● ansible -m ping all -i local
127.0.0.1 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: vagrant@127.0.0.1: Permission
denied (publickey,password).",
"unreachable": true
}
18. 간단한 Playbook 만들기 #1
● 실제로 ansible을 이용할 경우에는 playbook을 이용한 role의
조합으로 실행된다.
19. 간단한 Playbook 만들기 #2
● test.yml 작성
---
- name: Test testboxes
hosts: test
tasks:
- name: Hello, World
debug:
msg: "Hello, World"
20. 간단한 Playbook 만들기 #3
● ansible-playbook test.yml -i local
vagrant@vagrant:~/ansible$ ansible-playbook test.yml -i local
Executing playbook test.yml
- Test testboxes on hosts: test -
Gathering Facts...
127.0.0.1 ok
Hello, World...
127.0.0.1 ok: {
"changed": false,
"msg": "Hello, World"
}
- Play recap -
127.0.0.1 : ok=2 changed=0 unreachable=0 failed=0 rescued=0
ignored=0
21. Variable
● Role이나 playbook에서 사용할 변수를 정의한다.
---
- name: Test testboxes
hosts: test
vars:
mymsg: "Hello, MyMSG"
mymsg2:
name1: "Hello"
name2: "MyMSG"
tasks:
- name: mymsg
debug:
msg: "Msg is {{ mymsg }}"
22. Loop
● 특정 변수의 값만큼 반복하고 싶을 때
---
- name: Test testboxes
hosts: test
vars:
names:
- name1
- name2
- name3
- name4
tasks:
- name: Display Names
debug:
msg: "Msg is {{ item }}"
with_items: "{{ names }}"
23. Condition
● 특정 변수의 값만큼 반복하고 싶을 때
---
- name: Test testboxes
hosts: test
vars:
names_loop: False
names:
- name1
- name2
- name3
- name4
tasks:
- name: Display Names
debug:
msg: "Msg is {{ item }}"
with_items: "{{ names }}"
when: names_loop is defined and names_loop
24. Register
● 해당 연산의 결과를 저장하고 싶을때
---
- name: Test testboxes
hosts: test
tasks:
- name: get filename
shell: ls -al /etc/
register: output
- name: Debug oruput
debug:
msg: "Msg is {{ item }}"
with_items: "{{ output.stdout_lines }}"
- name: Debug rc
debug:
msg: "Msg is {{ output.rc}}"
25. Role에 대해서 알아보자.
● Playbook에 모든 걸 정의하는 것은 재사용하기 굉장히 어려움.
● Nginx를 설치하는 Role등을 만들어두고, 어떤 파라매터로 생성할
것인가만 Playbook등에 정의하는 것으로 재활용성을 높일 수 있음.
27. Role의 구조 #2
● defaults
○ 기본 값을 설정한다.
● tasks
○ 실제로 동작할 내용을 설정한다.
○ tasks만 있어도 role은 동작한다.
● handlers
○ tasks 에서 설정한 값으로 동작한다.
28. 간단한 nginx 설치 role을 만들어보자. #1
● roles/nginx/tasks/main.yml 생성
---
- name: Install Nginx
apt:
pkg: nginx
state: present
update_cache: yes
notify:
- Restart Nginx
become: True
29. 간단한 nginx 설치 role을 만들어보자. #2
● Permission 이 없다고 실패, charsyam user에 대해서 sudo 권한
수정이 필요. Taget 서버의 /etc/sudoers 파일 수정
charsyam ALL=(ALL) NOPASSWD: ALL
30. 간단한 nginx 설치 playbook을 만들어보자. #1
● webservers.yml 생성
● ansible-playbook webservers.yml -i local
○ local is inventory name
○ ex) ansible-playbook webservers.yml -i prod-useast1
---
- name: Install Web Servers
hosts: test
roles:
- { role: nginx, tags: ["nginx"] }
31. 여러 Role을 Playbook에서 돌려보자.
● webservers.yml 생성
● ansible-playbook webservers.yml -i local
---
- name: Install Web Servers
hosts: test
Roles:
- { role: base, tags: ["base"] }
- { role: nginx, tags: ["nginx"] }
32. 특정 Role만 쓰고 싶을 때는 태그를 사용한다.
● webservers.yml 생성
● ansible-playbook webservers.yml -i local --tags “nginx”
---
- name: Install Web Servers
hosts: test
Roles:
- { role: base, tags: ["base"] }
- { role: nginx, tags: ["nginx"] }
33. Template를 이용해보자 #1
● 설정한 변수 값과 template을 이용하여 배포해보자.
● Webserver1 과 WebServer2 그룹이 있을 때 서로 접속해야 할
주소가 다르다면?
35. Template를 이용해보자 #3
● {{ key }} 식으로 template 지정이 가능
# include snippets/snakeoil.conf;
root {{ nginx_root_dir }};
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
36. GROUP_VARS 를 이용해보자 #1
● Template 은 편하긴 하지만, 인벤토리마다 다른 값을 쉽게 지정하는
방법이 없을까?
● 앞에서 사용한 방법은 매번 배포할때 마다 해당 값을 바꿔줘야 함.
37. GROUP_VARS 를 이용해보자 #2 - GROUP
● 각 inventory 에 지정된 hosts 에 []로 둘러싸인 것 하나가 그룹
● 아래는 test와 webserver 두 개의 그룹이 존재한다.
[test]
127.0.0.1
[webserver]
192.168.0.100
192.168.0.101
192.168.0.102
38. GROUP_VARS 를 이용해보자 #3 - GROUP의 지정
● 아래 hosts 에 들어가는 값이 Group 값
● 여기서는 test 그룹을 사용함.
---
- name: Install Web Servers
hosts: test
vars:
- nginx_root_dir: /var/www/html2
roles:
- { role: base, tags: ["base"] }
- { role: nginx, tags: ["nginx"] }
39. GROUP_VARS 를 이용해보자 #4
● GROUP_VARS는 각 inventory 안에 존재
● local/group_vars/test 생성
○ nginx_root_dir: /var/www/html
● useast1/group_vars/test 생성
○ nginx_root_dir: /var/www/html2
● 다음 두 개의 결과를 비교하자.
○ ansible-playbook webservers.yml -i local --tags ‘nginx’
○ ansible-playbook webservers.yml -i useast1 --tags ‘nginx’
40. Role 에 default 값을 지정해보자 #1
● Group_vars 를 지정하는 것도 좋지만, 보통은 전부 동일한 값을
쓰다가 특별한 녀석들만 바꾸고 싶다면? Default 값을 부여할 수
있다.
41. Role 에 default 값을 지정해보자 #2
● roles/nginx/defaults/main.yml 작성
● 다음과 같은 테스트를 해봅시다.
○ defaults 값을 지정해두고
■ 특정 inventory group만 group_vars 적용
---
nginx_root_dir: /var/www/html
42. 모든 그룹에 값을 지정하고 싶다면?
● {원하는 inventory}/group_vars/all 을 생성하고 여기에 넣어두면 됨
43. 그런데, 이러면 중요한 정보가 다 repository에 남아요!!!
● 암호화 되어 있어야 할 정보들이 필요하면 어떻게 될까?
● group_vars 나 해당 파일에 데이터는 전부 다른 사람이 볼 수 있다.
● 실제로 대부분의 코드는 사내 repo등에 있으므로 언제든지 패스워드를 볼
수 있음.
○ 파일이 유출된다면?
44. ansible-vault
● 암호화된 형태로 var를 저장할 수 있음.
● 패스워드를 저장하는 vault_password_file 파일이 필요함
● ansible.cfg 에 vault_password_file 라는 키로 저장을 함
● vault_password_file의 값은 마음대로 정하면 됨.
● 암호화된 값도 실제 vars와 동일하다.
vault_password_file = ~/.ansible/vault-password-file
45. ansible-vault 사용법 #1
● 값 암호화 하기
● 해당 값을 vars/vault 파일에 저장한다고 가정.
$ ansible-vault encrypt_string "this is a secret" -n mysecret
mysecret: !vault |
$ANSIBLE_VAULT;1.1;AES256
64306135323761346632396430633339353431306566326637336166313433666238383266663564
3438303166303135653066653833613664653836626636650a333964343139386238643332383532
39626663333739333730383266623661663532666439393334366661313534353238396433343936
6265396236326337390a396664623866626162353838656234383066616661336564313637376438
38316365306165636330306238646132363061623132373733613331353661636330
Encryption successful
46. ansible-vault 사용법 #2
● 값 확인 하기
$ ansible -o -e @vars/vault -i localhost, localhost -m debug -a 'msg={{mysecret}}'
localhost | SUCCESS => { "changed": false, "msg": "this is a secret"}