Ansible Playbook 시작하기
Overview
Ansible을 활용하면 반복적인 시스템 작업들을 자동화 할 수 있습니다. 하지만 명령어 기반 작업이다 보니 엔지니어마다 작성하는 방식이 다르고 표준을 정하기도 어렵습니다.
게다가 하나의 명령을 수행하는 것이 아니라 여러가지 명령을 조합해서 한 번에 실행해야하는 경우는 어떨까요? 물론 쉘 스크립트로 명령을 조합해서 원하는 결과는 얻을 수 있을 것입니다. 하지만 분명 코드는 더 복잡해지고 형상 관리가 어려워질 것입니다.
저 또한 동일한 Ansible 명령을 반복적으로 수행하다보니 이것 또한 번거롭다고 느껴지고 형상관리를 해야 할 필요성을 느꼈습니다. 또 자동화 코드를 선언적인 형태로 작성해 누구나 알아보기 쉽고 유지보수하기 쉬웠으면 좋겠다고 생각했습니다.
해서 여러가지 방법을 찾아보던 중 Ansible Playbook에 대해 알게되었고 제가 원하는 방향과 맞는 거 같아 자동화 업무에 사용하고 있습니다.
Ansible Playbook을 처음 접하는 분이시라면 Ansible과 차이점에 대해 궁금하실텐데요. 간단하게 설명해 Ansible이 작업장의 도구라면 Ansible Playbook은 작업 메뉴얼이고 Inventory는 재료라고 비유할 수 있습니다.
Ansible Playbook에 대한 자세한 내용은 간단한 예제를 통해 살펴보겠습니다.
Getting Started
Ansible을 활용해 서버 계정 생성 자동화 방법에 대해 설명한 적이 있었는데요. 이 작업을 Ansble playbook을 사용해 자동화하는 방법에 대해 알아보겠습니다.
서버 계정 생성 자동화 작업은 아래의 단계로 수행됩니다. Ansible을 사용해서 각 단계의 작업을 수행하는 명령을 실행했는데요. 이를 Ansible Playbook으로 변경해보겠습니다.
- 사용자 계정 추가하기
- 패스워드 설정하기
- sudo 명령어 사용 권한 추가하기
참고
이 문서의 Ansible host(Ansible을 설치하고 있는 서버)에서 사용하는 계정은 sudo 권한이 없는 일반 사용자입니다. (sudo: 일반 사용자가 root 권한을 일시적으로 획득하여 특정 명령을 실행 할 수 있도록 하는 명령)
1. Playbook 생성
“create-account.yaml” 이라는 파일을 생성합니다. 그리고 아래와 같이 작성해보겠습니다.
---
- name: Create account
hosts: "{{ HOST_NAME }}"
become: true
tasks:
- name: create user
user:
name: "{{ USER_NAME }}"
- name: set password
user:
name: "{{ USER_NAME }}"
password: "{{ PASSWORD | password_hash('sha512') }}"
- name: create sudoers
copy:
content: |
{{USER_NAME}} ALL=(ALL) NOPASSWD:ALL
dest: "/etc/sudoers.d/{{USER_NAME}}"
owner: root
group: root
mode: 0664
Playbook은 yaml 포맷으로 선언적으로 작성합니다. 파일 위에서 부터 차례로 살펴보겠습니다.
- name: Playbook의 이름
- hosts: Remote host 이름
- become: 명령을 실행하는 사용자 계정의 권한을 승격
- tasks: Remote host에서 수행할 작업들
”{{ HOST_NAME }}”과 같이 선언한 부분은 playbook 실행 시 입력받을 인자 값입니다.
다음으로 수행하는 각 작업(tasks)에 대해 살펴보겠습니다.
- “create user” task
- user: user 모듈 사용 선언
- name: 생성할 사용자 계정 이름
- user: user 모듈 사용 선언
- “set password” task
- user: user 모듈 사용 선언
- name: 생성할 사용자 계정 이름
- password: 생성할 사용자 계정 패스워드
- user: user 모듈 사용 선언
- “create sudoers” task
- copy: copy 모듈 사용 선언
- content: 복사할 문자열
- dest: 복사할 목적지로 remote host의 절대 경로
- mode: 복사할 목적지의 파일/디렉토리 권한 입력
- owner: 복사할 목적지의 파일/디렉토리 소유자
- group: 복사할 목적지의 파일/디렉토리 그룹
- copy: copy 모듈 사용 선언
코드를 선언적으로 작성했기 때문에 누가봐도 어떤 작업을 수행하는지 알기 쉽고 작업 순서 또한 명확히 파악됩니다.
2. Playbook 실행
이제 생성한 “create-account.yaml” playbook을 실행해보겠습니다. Python Ansible 패키지를 설치하면 함께 설치되는 “ansible-playbook” 명령을 실행합니다.
- “i” 옵션: Remote host의 정보를 가지고 있는 inventory 파일 경로를 지정
- ”–extra-vars” 옵션: Playbook에 전달할 인자 값
- HOST_NAME: Remote host 이름
- USER_NAME: 생성할 사용자 계정 이름
- PASSWORD: 생성할 사용자 계정 패스워드
default-user@ansible-host:~$ ansible-playbook -i [path/to/inventory] create-account.yaml \
--extra-vars "HOST_NAME=[HOST_NAME] USER_NAME=[USER_NAME] PASSWORD=[PASSWORD]"
아래와 같이 “test” 사용자 계정을 모든 host에 생성해보겠습니다.
default-user@ansible-host:~$ ansible-playbook -i /etc/ansible/hosts create-account.yaml \
--extra-vars "HOST_NAME=all USER_NAME=test PASSWORD=test1234"
PLAY [Create account] *******************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************
TASK [create user] **********************************************************************************************************************************
- name: Create account
changed: [host03.example.com]
changed: [host02.example.com]
changed: [host01.example.com]
TASK [set password] *********************************************************************************************************************************
changed: [host02.example.com]
changed: [host03.example.com]
changed: [host01.example.com]
TASK [create sudoers] *******************************************************************************************************************************
changed: [host03.example.com]
changed: [host02.example.com]
changed: [host01.example.com]
PLAY RECAP ******************************************************************************************************************************************
host01.example.com : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host02.example.com : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host03.example.com : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
실행 결과를 보면 Playbook에 정의한 각 task 들이 순차적으로 실행되는 것을 확인할 수 있습니다. 마지막에 “PLAY RECAP”에 “changed”의 숫자는 작업에 성공해 실제 반영되 task 수를 나타냅니다.
Playbook에 3가지의 task를 정의했기 때문에 3이 표시되는 것으로 볼 수 있습니다. 만약 암호만 변경해서 다시 실행한다면 실제 반영된 task 수는 몇으로 표시될까요? 3가지 task 중 암호만 변경했으므로 1로 표시될 것입니다.
계정을 생성했으니 실제 로그인이 되는지 확인해보겠습니다.
## Remote host에 접속
default-user@ansible-host:~$ ssh host01.example.com
## test 사용자 계정으로 로그인
default-user@host01.example.com:~$ su - test
Password: ...
## sudo 명령으로 root 계정으로 로그인
test@host01.example.com:~$ sudo su - root
## root 계정으로 정상 로그인됨
root@host01.example.com:~#
참고
암호를 입력했으므로 명령어를 실행한 뒤 history를 clear 해주는 것이 좋습니다.
맺음말
지금까지 Ansible Playbook에 대해 알아봤습니다.
처음에 Ansible은 도구, Inventory는 재료이고 Playbook은 작업 메뉴얼이라고 했는데요. 이 문서를 읽고 이 뜻이 충분히 이해가 됐을지 모르겠습니다.
여기까지 충분히 이해가 되었다면 다음으로 Ansible Playbook 응용 단계에서 좀 더 다양한 기능을 살펴보세요.