스터디
A101 - 1주차
willamette
2024. 1. 14. 04:04
1주차
aws cloudformation describe-stacks --stack-name **mylab** --query 'Stacks[*].**Outputs[0]**.OutputValue' --output text --region ap-northeast-2
실습 환경
- 마스터 노드 내 hosts 파일에 도메인 수동 매핑
- 10.10.1.10 server 10.10.1.11 tnode1 10.10.1.12 tnode2 10.10.1.13 tnode3 # 키 복사 for i in {1..3}; do **ssh-copy-id root@tnode$i**; done
인벤토리: 관리할 대상 호스트를 지정, ini/yaml 스타일
# 범위 설정 : 192.168.4.0 ~ 192.168.4.255 사이의 IP 범위를 표현
[master]
db[01:03].foo.link
# datacenter 그룹이 webserver, dbservers를 자식으로 포함할 때
[webservers]
web1.example.com
web2.example.com
[db-servers]
db01.example.com
db02.example.com
[datacenter:children]
webservers
dbservers
플레이북 환경설정: ansible.cfg
- privilege_escalation: 앤서블 실행 시점에 리모트에서 어떤 권한으로 실행할지 지정 https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_privilege_escalation.html
- become_method: 에스컬레이션 방법, 기본은 sudo
- become_user
- 별도로 설정되어 있지 않으면 앤서블은 실행 시 로컬 사용자와 같은 사용자 이름을 사용
변수
우선순위: 추 변수 > 플레이 변수 > 호스트 변수 > 그룹 변수
- 그룹 변수: 인벤토리에 정의된 호스트 그룹에 적용되는 변수
- 그룹 변수를 이용해 해당 그룹 내에서 카운팅을 한다면
# inventory [web] tnode1 tnode2 [db] tnode3 [all:children] web db [replica] tnode1 tnode2 [replica:vars] special_user = archon
# create-user.yml
---
- hosts: replica
tasks:
- name: Create User {{ special_user }}
ansible.builtin.user:
name: "{{ special_user }}"
state: present
- name: Create User with populate vars
ansible.builtin.user:
name: "{{ special_user + ansible_play_hosts | length | string }}"
state: present
$ ansible-playbook create-user.yml --check --diff -vvv
...
changed: [tnode2] => {
"changed": true,
"invocation": {
"module_args": {
"append": false,
"authorization": null,
"comment": null,
"create_home": true,
"expires": null,
"force": false,
"generate_ssh_key": null,
"group": null,
"groups": null,
"hidden": null,
"home": null,
"local": null,
"login_class": null,
"move_home": false,
"name": "archon2",
"non_unique": false,
"password": null,
"password_expire_max": null,
"password_expire_min": null,
"password_lock": null,
"profile": null,
"remove": false,
"role": null,
"seuser": null,
"shell": null,
"skeleton": null,
"ssh_key_bits": 0,
"ssh_key_comment": "ansible-generated on tnode2",
"ssh_key_file": null,
"ssh_key_passphrase": null,
"ssh_key_type": "rsa",
"state": "present",
"system": false,
"uid": null,
"umask": null,
"update_password": "always"
}
}
}
...
changed: [tnode1] => {
"changed": true,
"invocation": {
"module_args": {
"append": false,
"authorization": null,
"comment": null,
"create_home": true,
"expires": null,
"force": false,
"generate_ssh_key": null,
"group": null,
"groups": null,
"hidden": null,
"home": null,
"local": null,
"login_class": null,
"move_home": false,
"name": "archon2",
"non_unique": false,
"password": null,
"password_expire_max": null,
"password_expire_min": null,
"password_lock": null,
"profile": null,
"remove": false,
"role": null,
"seuser": null,
"shell": null,
"skeleton": null,
"ssh_key_bits": 0,
"ssh_key_comment": "ansible-generated on tnode1",
"ssh_key_file": null,
"ssh_key_passphrase": null,
"ssh_key_type": "rsa",
"state": "present",
"system": false,
"uid": null,
"umask": null,
"update_password": "always"
}
}
}
PLAY RECAP *********************************************************************************************************************************************************
tnode1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
tnode2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
- 호스트 변수: 해당 호스트에서만 사용 가능, 인벤토리에서 해당 호스트에 인라인으로 정의
- # inventory [web] tnode1 user=nginx
- 플레이 변수: 플레이북 내에서 선언된 변수
- # <https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-in-included-files-and-roles> # users.yml user: templer # create-user.yml - hosts: all var_files: - users.yml tasks: - name: create user {{ user }} #파일명 기재 필요없이 바로 변수명 참조 가능
- 추가 변수: ansible 실행 시 인라인 아규먼트로 넘겨주는 변수 ansible-playbook -e user=templer ...
- 작업 변수: 플레이 결과를 저장하기 위한 변수
vault
root@server:~/my-ansible# ansible-vault create userdata.yml
New Vault password: qwe123
Confirm New Vault password: qwe123
root@server:~/my-ansible# ansible-vault view userdata.yml
Vault password: oops
ERROR! Decryption failed (no vault secrets were found that could decrypt) on userdata.yml for userdata.yml
root@server:~/my-ansible# ansible-vault view userdata.yml
Vault password: qwe123
>>
password: qwe123
root@server:~/my-ansible# cat userdata.yml
$ANSIBLE_VAULT;1.1;AES256
64363633616336623064396337346230623739643362303532303831343739386338366166393232
6236313531333864613763646538316637346533386437660a333536663861343330396234316361
31336234636430623961326262393763613434663963393731396537346461326335623262303831
3561376130653532320a326133373462386235613636663031306232663836376435333630376234
65623632393436653937363437633830653131646666393037323932326633326630
root@server:~/my-ansible# ansible-playbook --vault-id @prompt create-user.yml
facts = 대상 호스트 정보
역시 이런 IaC에선 호스트 정보 스크래핑이 빠질 수가 없다.
saltstack에서 grains와 거의 동일해보임 https://docs.saltproject.io/en/latest/topics/grains/index.html
---
- hosts: all
tasks:
- name: Print all facts
ansible.builtin.debug:
var: ansible_facts
- debug:
msg: |
hostname: {{ ansible_facts.hostname }}
distributioni: {{ ansible_facts.distribution }}
TASK [debug] *******************************************************************************************************************************************************
ok: [tnode1] => {
"msg": "hostname: tnode1\\ndistributioni: Ubuntu\\n"
}
ok: [tnode2] => {
"msg": "hostname: tnode2\\ndistributioni: Ubuntu\\n"
}
- 만약 모종의 사유로 fact 수집을 비활성화 하고 싶다면 https://november11tech.tistory.com/108
- --- - hosts: all gather_facts: no 와 같이 하면 다음과 같은 Fact gathering이 안 나올 것임 TASK [Gathering Facts] ********************************************************************************************************************************************* ok: [tnode2] ok: [tnode1]
도전과제
# uptime 확인
---
- hosts: replica
tasks:
- name: get uptime
ansible.builtin.shell: /usr/bin/uptime
register: uptime
- debug:
var: uptime
TASK [debug] *******************************************************************************************************************************************************
ok: [tnode1] => {
"uptime": {
"changed": true,
"cmd": "/usr/bin/uptime",
"delta": "0:00:00.007493",
"end": "2024-01-14 02:48:26.050096",
"failed": false,
"msg": "",
"rc": 0,
"start": "2024-01-14 02:48:26.042603",
"stderr": "",
"stderr_lines": [],
"stdout": " 02:48:26 up 1:39, 1 user, load average: 0.23, 0.05, 0.02",
"stdout_lines": [
" 02:48:26 up 1:39, 1 user, load average: 0.23, 0.05, 0.02"
]
}
}
ok: [tnode2] => {
"uptime": {
"changed": true,
"cmd": "/usr/bin/uptime",
"delta": "0:00:00.007402",
"end": "2024-01-14 02:48:25.998745",
"failed": false,
"msg": "",
"rc": 0,
"start": "2024-01-14 02:48:25.991343",
"stderr": "",
"stderr_lines": [],
"stdout": " 02:48:25 up 1:39, 1 user, load average: 0.11, 0.03, 0.01",
"stdout_lines": [
" 02:48:25 up 1:39, 1 user, load average: 0.11, 0.03, 0.01"
]
}
}
# fact 이용한 커널 버전 확인
- name: Print all facts
ansible.builtin.debug:
var: ansible_facts
- debug:
msg: |
kernel version: {{ ansible_facts.kernel }}
distributioni: {{ ansible_facts.distribution }}
꿀팁
- ansible-playbook --syntax-check : syntax check
- ansible-playbook --check : dry-run