서버가 10대로 늘어나면 어떻게 되나요. 한 대씩 SSH로 접속해 똑같은 명령을 반복합니다. 한 대는 설정이 빠지고, 다른 한 대는 오타가 납니다. 나중에는 어느 서버가 어떤 상태인지 아무도 모르게 됩니다. Ansible은 이 문제를 “원하는 상태를 코드로 선언”하는 방식으로 해결합니다. 이 글에서는 Ansible playbook으로 VPS 초기 세팅 전체를 자동화하는 실전 가이드를 다룹니다.

이 글은 핵심 개념과 실제 적용 방법을 단계별로 안내합니다. 본문을 통해 독자는 실무에 바로 적용할 수 있는 구체적인 설정법과 확실한 해결책을 얻게 됩니다.
초보자부터 전문가까지 누구나 쉽게 따라 할 수 있도록 구성되었습니다. 핵심 원리를 이해하고 실제 환경에 적용해 보세요.
Ansible이란 — 선언적·에이전트리스·멱등성 무엇인가요?
Ansible은 선언적 구성 관리 도구입니다. “명령을 어떤 순서로 칠까”가 아니라 “서버가 이 상태여야 한다”를 YAML 파일로 적습니다. 그러면 Ansible이 현재 상태를 확인하고 필요한 변경만 적용합니다.
세 가지 핵심 특성:
- 선언적(declarative): “nginx를 설치해”가 아니라 “nginx가 설치되어 있어야 해”로 적습니다. W28 셸 스크립팅의 명령형(imperative) 접근과의 가장 큰 차이입니다.
- 에이전트리스(agentless): 대상 서버에 에이전트를 설치할 필요가 없습니다. SSH만 열려 있으면 됩니다. 배울 것도 관리 포인트도 적습니다.
- 멱등성(idempotency): 같은 playbook을 여러 번 실행해도 결과가 항상 같습니다. 셸 스크립트는 두 번 실행하면 패키지가 중복 설치되거나 설정이 꼬일 수 있지만, Ansible은 이미 원하는 상태면 아무것도 하지 않습니다.
1. inventory 파일 — 대상 서버 정의 무엇인가요?
먼저 어느 서버에 적용할지 적은 hosts.ini를 만듭니다.
// hosts.ini
[web]
web1 ansible_host=203.0.113.10
web2 ansible_host=203.0.113.11
[db]
db1 ansible_host=203.0.113.20
[all:vars]
ansible_user=deploy
ansible_ssh_private_key_file=~/.ssh/id_ed25519
서버를 역할별 그룹(web, db)으로 묶습니다. 그룹별로 다른 playbook을 적용할 수 있습니다. 연결을 확인합니다:
ansible all -i hosts.ini -m ping
// web1 | SUCCESS => {"changed": false, "ping": "pong"}
// web2 | SUCCESS => ...
// db1 | SUCCESS => ...
SSH 키가 설정되어 있어야 합니다(W22 방화벽/SSH 보안 참고).

2. playbook YAML 구조 무엇인가요?
playbook은 “어느 호스트 그룹에 어떤 작업을 적용할지”를 정의합니다.
// setup.yml
- name: VPS 초기 세팅
hosts: all
become: yes // sudo 권한
vars:
deploy_user: deploy
ssh_port: 22
tasks:
- name: 시스템 패키지 최신화
apt:
update_cache: yes
upgrade: dist
- name: 필수 패키지 설치
apt:
name:
- nginx
- ufw
- fail2ban
- unattended-upgrades
state: present
- name: deploy 사용자 생성
user:
name: "{{ deploy_user }}"
shell: /bin/bash
groups: sudo
append: yes
- name: 방화벽 활성화
ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- "22"
- "80"
- "443"
- name: nginx 서비스 시작 + 자동 시작
service:
name: nginx
state: started
enabled: yes
실행은 한 줄입니다. 10대든 100대든 같습니다.
ansible-playbook -i hosts.ini setup.yml
3. 멱등성 실전 — 두 번 실행해도 안전 무엇인가요?
위 playbook을 두 번 실행하면 어떻게 될까요. Ansible은 각 작업(task)마다 현재 상태를 먼저 확인합니다. 이미 패키지가 설치되어 있으면 ok, 변경이 필요하면 changed를 보고합니다.
PLAY RECAP ***
web1 : ok=8 changed=3 unreachable=0 failed=0 // 첫 실행
web1 : ok=8 changed=0 unreachable=0 failed=0 // 두 번째 실행
두 번째 실행에서 changed=0인 것이 핵심입니다. 셸 스크립트였다면 패키지 재설치, 사용자 중복 생성 등 사이드 이펙트가 생길 수 있습니다. Ansible은 “이미 원하는 상태”면 손대지 않습니다. 이것이 멱등성입니다.
4. role 구조로 재사용하기 무엇인가요?
playbook이 길어지면 role로 분리합니다. role은 “특정 역할을 수행하는 작업 묶음”입니다.
// role 생성
ansible-galaxy init common
ansible-galaxy init nginx
ansible-galaxy init security
// 디렉터리 구조
roles/
common/
tasks/main.yml // 사용자 생성, 패키지 설치
nginx/
tasks/main.yml // nginx 설치 + 설정
templates/nginx.conf.j2
security/
tasks/main.yml // ufw, fail2ban, SSH 강화
playbook에서 role을 호출합니다:
- name: VPS 전체 세팅
hosts: all
become: yes
roles:
- common
- security
- nginx
W29 Nginx 리버스 프록시 설정을 role로 재작성하면, 새 서버에 Nginx 설정이 필요할 때 이 role만 부르면 됩니다. 재사용성이 극적으로 올라갑니다.
5. 실전 playbook — VPS 초기 세팅 전체를 한 번에 무엇인가요?
지금까지의 요소를 합치면, 새 VPS를 받자마자 다음을 한 번에 적용할 수 있습니다:
- 사용자 생성 + sudo 권한 + SSH 키 배포
- ufw 방화벽 (22/80/443만 오픈)
- fail2ban으로 SSH 무차별 대입 차단 (W25)
- Nginx 설치 + 기본 사이트 (W29)
- unattended-upgrades로 자동 보안 업데이트
- systemd 서비스 등록 (W24)
전체가 코드로 선언되어 있으니 git에 커밋하면 서버 구성 자체가 버전 관리됩니다. 새 서버가 추가되면 hosts.ini에 한 줄 추가하고 playbook을 다시 실행하면 끝입니다.

Ansible vs 셸 스크립트 — 언제 뭘 쓸까 무엇인가요?
W28에서 셸 스크립팅으로 VPS 자동화를 다뤘습니다. 그렇다면 Ansible은 언제 필요할까요?
| 구분 | 셸 스크립트 (W28) | Ansible playbook |
|---|---|---|
| 적합 규모 | 1-3대, 일회성 작업 | 3대 이상, 반복·표준화 필요 |
| 멱등성 | 직접 구현해야 | 기본 보장 |
| 상태 관리 | 어느 서버가 어느 상태인지 추적 어려움 | facts + changed/ok 리포트 |
| 학습 비용 | 낮음 (bash) | 중간 (YAML + 모듈) |
한두 대면 셸 스크립트가 빠릅니다. 서버가 늘거나 팀이 커지면 Ansible이 압도적으로 유리합니다.
마무리 — 다음 단계: k3s 클러스터 무엇인가요?
Ansible playbook으로 서버 구성을 코드로 선언하는 방법을 정리했습니다. 이 패턴은 다음 편에서 다룰 k3s 경량 Kubernetes 설치 자동화에도 그대로 적용됩니다. Ansible role로 k3s를 여러 VPS에 한 번에 설치하는 시나리오까지 이어집니다. VPS 데브옵스 시리즈의 마지막 편을 참고하세요.
VPS 데브옵스 시리즈. 추천 VPS 링크는 설명란에서 확인하세요.
자주 묻는 질문 (FAQ)
Q1. 셸 스크립트로도 되는데 왜 Ansible을 쓰나요?
가장 큰 차이는 멱등성입니다. 셸 스크립트는 두 번 실행하면 패키지가 중복 설치되거나 설정이 꼬일 수 있지만, Ansible은 현재 상태를 먼저 확인하고 이미 원하는 상태면 아무것도 하지 않습니다. 서버가 1~3대 일회성이면 셸이 빠르고, 3대 이상이거나 표준화가 필요하면 Ansible이 유리합니다.
Q2. 대상 서버에 에이전트를 설치해야 하나요?
필요 없습니다. Ansible은 에이전트리스라 SSH만 열려 있으면 동작합니다. 관리 포인트가 늘지 않는 것이 장점입니다.
Q3. playbook을 두 번 실행해도 안전한가요?
안전합니다. 실행 결과의 PLAY RECAP에서 첫 실행은 changed 값이 잡히지만 두 번째 실행은 changed=0으로 나옵니다. 이미 원하는 상태이면 손대지 않는다는 뜻입니다.
Q4. playbook이 길어지면 어떻게 정리하나요?
role로 분리합니다. ansible-galaxy init으로 common, nginx, security 같은 역할별 묶음을 만들고 playbook에서는 roles 목록으로 호출하면 됩니다. 새 서버에 같은 설정이 필요할 때 해당 role만 부르면 되니 재사용성이 크게 올라갑니다.
관련 글
- PostgreSQL VPS 배포 + 백업 자동화 완벽 가이드: 프로덕션 DB 직접 운영 (2026)
- VPS 백업 자동화 완벽 가이드 2026: restic + cron으로 증분 백업 구축
- VPS 모니터링 완벽 가이드 2026: Uptime Kuma + Netdata로 24시간 서버 감시



















