Ansible 은 에이전트를 심지 않고 SSH(윈도우는 WinRM · PSRP) 로 대상 서버에 접속해 구성 관리와 배포를 자동화하는 도구다. 작업은 YAML 로 선언하고, 같은 플레이북을 여러 번 돌려도 결과가 같도록(멱등) 모듈이 보장한다. 제어 노드에는 Python 과 ansible-core 가 필요하고, 관리 대상에는 SSH 와 Python 인터프리터만 있으면 된다.
배포 형태가 둘이라 버전 표기가 헷갈린다. ansible-core 는 실행 엔진 본체이고(현행 2.21.4[1]), ansible 패키지는 그 엔진에 수백 개의 컬렉션을 묶은 커뮤니티 배포판이라 버전 번호 체계가 다르다. 특정 모듈이 없다고 나오면 대개 ansible-core 만 설치한 상태다.
| 요소 | 역할 |
|---|---|
| 제어 노드(control node) | ansible · ansible-playbook 을 실행하는 장비. 윈도우는 제어 노드가 될 수 없다 |
| 관리 대상(managed node) | 실제 작업이 일어나는 서버. 에이전트를 설치하지 않는다 |
| 인벤토리 | 대상 목록과 그룹. INI 또는 YAML |
| 플레이북 | 대상 · 작업 · 변수를 적은 YAML 파일 |
| 모듈 | 실제 동작 단위. 컬렉션(ansible.builtin, community.general …) 에 담겨 배포된다 |
| 롤(role) | 작업 · 핸들러 · 템플릿 · 변수를 정해진 디렉터리 구조로 묶은 재사용 단위 |
[web]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11
[db]
db1 ansible_host=192.168.1.20
[all:vars]
ansible_user=ubuntu
해석 결과를 확인한다.
ansible-inventory --list
ansible-inventory --graph
ansible all -m ping
- name: 웹 서버 구성
hosts: web
become: true
vars:
pkg_name: nginx
tasks:
- name: 패키지 설치
ansible.builtin.package:
name: "{{ pkg_name }}"
state: present
- name: 설정 파일 배포
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: restart nginx
- name: 서비스 기동
ansible.builtin.service:
name: nginx
state: started
enabled: true
handlers:
- name: restart nginx
ansible.builtin.service:
name: nginx
state: restarted
핸들러는 자기를 notify 한 작업이 실제로 무언가를 바꿨을 때만, 그것도 플레이 끝에 한 번만 돈다. 설정 파일 다섯 개를 바꿔도 재시작은 한 번이다.
ansible-playbook -i inventory.ini site.yml
ansible-playbook -i inventory.ini site.yml --check --diff # 변경 없이 미리 보기
ansible-playbook -i inventory.ini site.yml --limit web1 -e pkg_name=nginx
모듈 이름은 컬렉션을 포함한 정식 이름(FQCN) 으로 적는 편이 안전하다. package · service · copy 같은 짧은 이름은 ansible.builtin 의 별칭이다.
| 모듈 | 용도 |
|---|---|
ansible.builtin.package · dnf · apt |
패키지 설치 |
ansible.builtin.service · systemd_service |
서비스 기동 · 부팅 등록 |
ansible.builtin.copy · template |
파일 · Jinja2 템플릿 배포 |
ansible.builtin.file |
디렉터리 생성, 권한 · 심볼릭 링크 |
ansible.builtin.lineinfile · blockinfile |
기존 설정 파일 일부 수정 |
ansible.builtin.user · group |
계정 관리 |
ansible.builtin.command · shell |
전용 모듈이 없을 때만. 멱등성이 깨지므로 creates · removes 조건을 같이 준다 |
낮은 쪽에서 높은 쪽으로 덮인다. 자주 부딪히는 구간만 적는다.
role defaults < inventory group_vars < inventory host_vars < play vars < task vars < -e (extra vars)
-e 로 준 값은 무엇으로도 덮이지 않는다. 그래서 디버깅할 때 값을 강제로 밀어 넣는 용도로 쓴다.
roles/
nginx/
tasks/main.yml
handlers/main.yml
templates/nginx.conf.j2
files/
defaults/main.yml
vars/main.yml
meta/main.yml
- hosts: web
roles:
- nginx
defaults/main.yml 은 가장 낮은 우선순위라 사용자가 덮어쓰라고 두는 값이고, vars/main.yml 은 거의 덮이지 않는 값이다. 외부에서 바꿀 값은 defaults 에 둔다.
[defaults]
inventory = inventory.ini
remote_user = ubuntu
host_key_checking = False
forks = 20
[privilege_escalation]
become = True
become_method = sudo
host_key_checking = False 는 호스트 키 확인을 끄므로 중간자 공격을 막지 못한다. 시험 환경에만 쓰고, 운영에서는 ssh-keyscan 으로 known_hosts 를 미리 채우는 편이 낫다.
| 구분 | Ansible | Terraform |
|---|---|---|
| 하는 일 | 이미 있는 서버의 상태를 맞춘다 | 인프라 자원 자체를 만들고 지운다 |
| 성격 | 절차와 선언이 섞여 있다 | 선언형 |
| 상태 관리 | 상태 파일이 없다. 매번 대상에 접속해 현재 상태를 확인한다 | state 파일로 관리하고 드리프트를 감지한다 |
| 변경 미리보기 | --check --diff 로 부분적으로 |
terraform plan |
| 연결 방식 | SSH · WinRM | 대상 API |
| 잘 맞는 대상 | OS · 패키지 · 설정 · 서비스 · 애플리케이션 배포 | VPC · 서브넷 · VM · LB · IAM · 관리형 서비스 |
실무에서는 둘을 겹쳐 쓴다. Terraform 으로 네트워크와 VM 을 만들고, Ansible 로 OS 를 세팅하고 런타임을 설치한 뒤, 애플리케이션을 배포하는 순서다. Ansible 로 클라우드 자원을 만드는 것도 가능하지만 상태 추적이 없어 삭제와 드리프트 처리가 번거롭고, Terraform 의 provisioner 로 OS 설정을 하는 것은 HashiCorp 도 최후 수단으로만 쓰라고 안내한다.
ansible-core 최신 버전 2.21.4 — 2026-09-20 확인. https://github.com/ansible/ansible/releases/latest ↩︎