이 문서에 대해
이 가이드는 Ansible 2.9.27 버전을 기준으로 작성되었습니다. 아래는 사용된 환경 정보입니다.
# cat /etc/system-release
Red Hat Enterprise Linux Server release 7.8 (Maipo)
# uname -a
Linux test01 3.10.0-1160.36.2.el7.x86_64 #1 SMP Wed Jul 21 11:57:15 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
# ansible --version
ansible 2.9.27
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/vipxf/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /bin/ansible
python version = 2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
# rpm -qi ansible
Name : ansible
Arch : noarch
Version : 2.9.27
Release : 1.el7
Size : 103 M
Repo : installed
Summary : SSH-based configuration management, deployment, and task execution system
URL : http://ansible.com
License : GPLv3+
Description : Ansible is a radically simple model-driven configuration management,
: multi-node deployment, and remote task execution system. Ansible works
: over SSH and does not require any software or daemons to be installed
: on remote nodes. Extension modules can be written in any language and
: are transferred to managed machines automatically.
Ansible 개념 이해
Ansible은 오픈 소스 기반의 구성 관리 및 자동화 도구입니다.
- 공식 웹사이트: https://www.ansible.com/
- 공식 문서: https://docs.ansible.com/ansible/latest/
- 패키지 다운로드: https://releases.ansible.com/
핵심 특징
- 에이전트리스(Agentless) 방식: 관리 대상 노드에 별도 에이전트 설치 불필요. 제어 노드에만 Ansible 환경을 구축하면 됩니다.
- 풍부한 내장 모듈: 대부분의 작업 시나리오를 충족하는 다양한 모듈 제공.
- Python 기반: API 및 사용자 정의 모듈 개발이 용이합니다.
- SSH 프로토콜 사용: 별도 데몬 없이 SSH를 통해 원격 노드와 통신합니다.
- Playbook: YAML과 Jinja2 템플릿 언어를 사용하여 복잡한 작업을 정의하고 관리합니다.
- 멱등성(Idempotency): 동일한 작업을 여러 번 수행해도 결과가 동일하도록 보장합니다.
Ansible 사용 모드
- Ad-Hoc 명령: 단일 명령을 일괄 실행하여 일회성 작업이나 빠른 확인에 사용됩니다.
- Playbook 실행: 여러 Task를 순차적으로 실행하여 복잡한 워크플로우를 자동화하는 주요 관리 방식입니다.
Ansible 아키텍처 및 실행 흐름
Ansible은 다음 다섯 가지 주요 구성 요소로 이루어집니다.
- Ansible Core: Ansible의 핵심 엔진
- Modules: 실제 작업을 수행하는 모듈들 (기본 및 사용자 정의)
- Plugins: 연결 플러그인, 메일 플러그인 등 모듈의 기능을 확장합니다.
- Playbooks: 작업을 정의하는 YAML 형식의 설정 파일
- Inventory: 관리할 대상 호스트 목록을 정의합니다.
명령 실행 과정
- 설정 파일(기본:
/etc/ansible/ansible.cfg)을 로드합니다. - Inventory 파일(기본:
/etc/ansible/hosts)을 읽어 대상 호스트 목록과 변수를 확인합니다. - 호출된 모듈에 따라 임시 Python 파일을 생성합니다.
- 생성된 파일을 대상 호스트의
~/.ansible/tmp디렉토리로 전송합니다. - 파일을 실행하여 작업을 수행하고 결과를 반환합니다.
- 임시 파일을 삭제하고 종료합니다.
Ansible 기본 정보
주요 디렉토리 구조
/etc/ansible/: 설정 파일, Inventory, Roles 디렉토리/usr/bin/: Ansible 실행 파일 위치/usr/lib/python2.7/site-packages/ansible: Python 라이브러리 디렉토리/usr/share/ansible/: 모듈, 플러그인, Roles 디렉토리
설정 파일 (/etc/ansible/ansible.cfg) 주요 파라미터
inventory = /etc/ansible/hosts # Inventory 파일 위치
library = /usr/share/ansible # Ansible 모듈 디렉토리 (":"로 구분하여 여러 개 지정 가능)
forks = 5 # 동시 실행 프로세스 수 (기본값 5)
remote_port = 22 # 원격 연결 포트
host_key_checking = False # SSH 호스트 키 검사 비활성화
timeout = 60 # SSH 연결 타임아웃 (초)
log_path = /var/log/ansible.log # 로그 파일 경로 (기본 비활성화)
실행 파일 목록
$ ll /usr/bin/*ansible*
lrwxrwxrwx 1 root root 20 Mar 17 2022 /usr/bin/ansible -> /usr/bin/ansible-2.7
lrwxrwxrwx 1 root root 20 Mar 17 2022 /usr/bin/ansible-2 -> /usr/bin/ansible-2.7
-rwxr-xr-x 1 root root 5933 Jan 16 2022 /usr/bin/ansible-2.7
lrwxrwxrwx 1 root root 7 Mar 17 2022 /usr/bin/ansible-config -> ansible
-rwxr-xr-x 1 root root 13432 Jan 16 2022 /usr/bin/ansible-connection
lrwxrwxrwx 1 root root 28 Mar 17 2022 /usr/bin/ansible-console -> /usr/bin/ansible-console-2.7
...
자주 사용되는 모듈
# 모듈 도움말 보기
ansible-doc -l # 사용 가능한 모든 플러그인 목록
ansible-doc -l | grep "copy" # "copy"가 포함된 모듈 검색
ansible-doc <module_name> # 특정 모듈 설명 보기
ansible-doc -s <module_name> # Playbook 스니펫 보기
# 주요 모듈
- **command**: 기본 모듈, 변수/파이프/리다이렉션 등 셸 기능 미지원
- **ping**: 대상 호스트 연결성 테스트
- **shell**: 셸 기능(변수, 파이프 등) 지원 명령 실행
- **script**: 로컬 스크립트를 원격 호스트에서 실행
- **setup**: 대상 호스트의 시스템 정보(facts) 수집
- **copy**: 로컬 파일을 원격 호스트로 복사
- **file**: 파일 속성(권한, 소유자 등) 변경
- **service**: 서비스 상태 관리 (시작, 중지, 재시작)
- **yum**: 패키지 설치, 업데이트, 제거
- **user**, **group**: 사용자 및 그룹 관리
Ansible 명령어
명령어 집합
ansible # Ad-Hoc 명령 실행 (기본 모듈: command)
ansible-config # Ansible 설정 확인
ansible-doc # 모듈 문서 조회
ansible-galaxy # Role 및 Collection 관련 작업
ansible-inventory # Inventory 정보 출력
ansible-playbook # Playbook 파일 실행
ansible-pull # VCS에서 Playbook을 가져와 로컬에서 실행
ansible-vault # 민감한 데이터 암호화/복호화
Ad-Hoc 명령 상세
# ansible <host-pattern> [-f forks] [-m module_name] [-a args]
# 주요 옵션
-v # 상세 출력 (-vvv, -vvvv)
-i inventory_file # Inventory 파일 지정
-f forks # 동시 실행 프로세스 수
-m module_name # 사용할 모듈 지정
-a args # 모듈 인자
-l hosts_ip # 실행 대상을 특정 호스트로 제한
--become-method BECOME_METHOD # 권한 상승 방법 (sudo, su)
--become-user BECOME_USER # 권한 상승 대상 사용자
-K, --ask-become-pass # 권한 상승 암호 입력 요청
--list-hosts # 대상 호스트 목록만 출력
--syntax-check # 구문 검사
-C, --check # 변경 없이 테스트 실행 (dry-run)
# 명령 예시
ansible 192.168.56.3 -a 'hostname' # command 모듈 사용
ansible Test -m ping # Test 그룹 핑 테스트
ansible all -m shell -a 'hostname && date' # 모든 호스트에 셸 명령 실행
자주 사용하는 Ad-Hoc 명령 예제
# ping 모듈로 연결 확인
ansible ta -m ping
# command 모듈로 디렉토리 변경 후 ls 실행
ansible ta -m command -a "chdir=/home/ ls ./"
# shell 모듈로 복잡한 명령 실행
ansible ta -m shell -a 'hostname && date;cat /etc/system-release'
# script 모듈로 로컬 스크립트 실행
ansible ta -m script -a "/home/vipxf/test.sh"
# setup 모듈로 시스템 정보 수집
ansible ta -m setup -a "filter=ansible_os_family"
# copy 모듈로 파일 복사 및 권한 설정
ansible ta -m copy -a "src=/etc/hosts dest=~/test.hosts mode=664 owner=vipxf group=vipxf"
# file 모듈로 파일 생성
ansible ta -m file -a "path=~/testfile.txt state=touch mode=644"
# yum 모듈로 패키지 설치
ansible ta -m yum -a "name=httpd state=present"
# service 모듈로 서비스 시작
ansible ta -m service -a "name=sshd enabled=yes state=started"
Ansible 변수 사용
- 변수명은 문자, 숫자, 밑줄(
_)로 구성되며 숫자로 시작할 수 없습니다. - Python 키워드나 Playbook 키워드는 변수명으로 사용할 수 없습니다.
- 변수는 Playbook, Inventory, 역할(Role), 명령줄 등 다양한 곳에서 정의할 수 있습니다.
변수 정의 방법
# 방법 1: Inventory에서 호스트/그룹 변수 정의
[groupname]
192.168.56.1 variable_name=value
[groupname:vars]
variable_name=value
# 방법 2: Playbook에서 vars 또는 vars_files로 정의
vars:
- var_name: value
vars_files:
- ./external_vars.yml
# 방법 3: register 키워드로 작업 결과를 변수로 저장
tasks:
- name: test
shell: /usr/bin/foo
register: foo_result
# 방법 4: 명령줄에서 -e 또는 --extra-vars로 변수 전달
ansible-playbook test.yml --extra-vars "hosts=Test user=anliven"
# 방법 5: roles 키워드로 변수 전달
roles:
- { role: ROLE_NAME, var: value }
시스템 변수 (Facts)
setup 모듈로 수집한 원격 호스트의 시스템 정보입니다.
ansible ta -m setup # 모든 facts 정보 확인
ansible ta -m setup -a "filter=ansible_os_family" # 특정 정보 필터링
변수 참조
# 일반 변수
{{ var_name }}
# register 또는 facts 변수
{{ var_name.stdout }}
{{ ansible_facts["eth0"]["ipv4"]["address"] }}
변수 우선순위 (높은 순)
- 명령줄에서 정의된 변수 (
-e또는--extra-vars) - Inventory의 연결 변수 (예:
ansible_ssh_user) - Play, include, role 등에서 정의된 일반 변수
- Inventory의 기타 변수
- Facts 변수
Ansible 인벤토리 (Inventory)
Inventory는 관리 대상 호스트의 집합을 정의합니다. 기본 파일은 /etc/ansible/hosts입니다.
인벤토리 파일 예시
192.168.56.1 # 그룹 없는 호스트
test.example.com
[Test] # 그룹 정의
192.168.56.1
192.168.56.[2:5] # 범위 지정
anliven-[a:d].example.com # 문자 범위
[Test:vars] # 그룹 변수
ansible_ssh_user="anliven"
ansible_ssh_pass="anliven"
[Test2]
192.168.56.1 ansible_ssh_user=anliven ansible_ssh_pass=Anliven # 호스트별 변수
[TestGroup:children] # 그룹 중첩
Test
Test2
[all:vars] # 모든 호스트에 적용되는 전역 변수
ansible_ssh_port="22"
Ansible Playbook
Playbook은 YAML 형식으로 작성된 작업 자동화 스크립트입니다.
Playbook 기본 구조
---
- hosts: ta # 대상 호스트
remote_user: vipxf # 원격 실행 사용자
gather_facts: no # Facts 수집 비활성화
vars: # 변수 정의
- package: vim
tasks: # 작업 목록
- name: install vim
yum: name={{ package }} state=latest
- name: copy file
copy: src=/root/conf/httpd.conf dest=/home/vipxf/
notify: restart service # 변경 시 핸들러 호출
handlers: # 핸들러 (알림을 받은 작업만 실행)
- name: restart service
service: name=httpd state=restarted
Playbook 실행
# 구문 검사
ansible-playbook --syntax-check sample.yaml
# 변경 없이 테스트 (dry-run)
ansible-playbook -C sample.yaml
# 상세 모드 실행
ansible-playbook -v sample.yaml
# 특정 태그만 실행
ansible-playbook sample.yaml --tags "conf,http"
# 특정 태그 제외
ansible-playbook sample.yaml --skip-tags "conf"
조건부 실행 (when)
- name: example
hosts: ta
tasks:
- name: RedHat 계열에서만 실행
shell: echo "RedHat"
when: ansible_os_family == "RedHat"
- name: 이전 작업 성공 시 실행
shell: echo "step1"
register: result
- name: step2 실행
shell: echo "step2"
when: result.rc == 0
루프 (with_items)
- name: iterate example
hosts: ta
tasks:
- name: 패키지 설치
yum: name={{ item }} state=present
with_items:
- httpd
- nginx
- mysql
- name: 딕셔너리 루프
debug: msg="{{ item.name }}: {{ item.value }}"
with_items:
- { name: 'one', value: '111' }
- { name: 'two', value: '222' }
역할 (Roles)
Roles는 Playbook을 모듈화하여 재사용성을 높입니다.
# 디렉토리 구조 예시
site.yml
roles/
common/
tasks/main.yml
handlers/main.yml
templates/
files/
vars/main.yml
defaults/main.yml
meta/main.yml
webserver/
tasks/main.yml
...
# Playbook에서 Roles 호출
---
- hosts: webserver
roles:
- common
- { role: webserver, port: 8080 }
Ansible Vault (암호화)
ansible-vault는 민감한 데이터를 암호화하는 도구입니다.
주요 명령어
# 파일 암호화
ansible-vault encrypt secret.yml
# 파일 복호화
ansible-vault decrypt secret.yml
# 암호화된 파일 보기
ansible-vault view secret.yml
# 암호 변경
ansible-vault rekey secret.yml
# 암호화된 Playbook 실행
ansible-playbook secret.yml --ask-vault-pass
성능 최적화
# SSH 키 검사 비활성화
host_key_checking = False
# 동시 실행 프로세스 수 증가
forks = 20
# Facts 수집 비활성화 (필요 없는 경우)
gather_facts: False
# 파이프라이닝 활성화 (sudo 미사용 시)
pipelining = True
# 비동기 작업 및 폴링
- name: long task
shell: sleep 10 && echo "done"
async: 15
poll: 2
자주 사용하는 팁
SSH 키 기반 인증
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub user@remote_host
root 비밀번호 입력 생략
---
- hosts: ta
become: yes
become_method: su
become_user: root
vars:
ansible_become_pass: "{{ root_pass_input }}"
tasks:
- name: test
shell: date
# 실행: ansible-playbook playbook.yml -e root_pass_input=my_password
여러 핸들러에 알림 보내기
tasks:
- name: config change
template: src=config.j2 dest=/etc/config
notify: "config update"
handlers:
- name: restart service
service: name=app state=restarted
listen: "config update"
- name: reload service
service: name=app state=reloaded
listen: "config update"