
Ansible을 이용해서 Control Node에서 Managed Node에 play를 수행하기 위해서는 3가지 파일이 필요하다.
- 구성파일 : ansible의 configuration을 전부 담고 있다. (ansible.cfg)
- 인벤토리 파일 : 관리할 managed node를 여기에 명시해야한다. (Inventory)
- 플레이북 파일 : 실행할 작업에 대한 명세를 담고 있다. (.yaml 파일 형식)
이 세 가지 유형의 파일을 저장할 작업 디렉토리를 따로 생성하고,
파일이나 하위 디렉토리로 이 파일을 위치시켜야 한다.
1. 구성파일
Ansible을 사용하기 전에 연결 설정이나 권한 설정 등을 변경할 수 있다.
Ansible의 동작 방법을 설정하는 파일을 구성파일이라고 부르고, /etc/ansible/ansible.cfg 에 위치하고 있다.
프로젝트별로 관리하기 위한 작업 디렉토리를 따로 생성해서 구성파일을 위치시켜 관리하기도 한다.
작성 방법
각 섹션에 key = value 쌍으로 작성한다.
설정이 필요한 섹션 별로 작성되고, 각 섹션은 대괄호를 이용하여 나타낸다.
(핸드폰 설정 앱에서 디스플레이/ 배터리/ 개인정보 보호 이런식으로 나뉘어 있듯이
각 섹션별로 나눠서 작성되는 것이고 그걸 대괄호로 분리하는 것이다. ex. [디스플레이], [배터리], [개인정보 보호])
# ansible.cfg
[section_name]
key = value
another_key = value
주요 섹션
| [defaults] | Ansible의 기본 동작을 정의한다. 인벤토리 파일 경로, 원격 접속 계정명, SSH 체크 여부와 같은 일반적인 설정이 포함된다. |
| [privilege_escalation] | 권한 상승(sudo)와 관련된 설정이다. 명령을 실행할 때, sudo를 사용할지, 어떤 계정으로 전환할지 등을 정한다. |
| [ssh_connection] | SSH에 대한 세부 설정이다. 연결 유지 시간이나 포트 설정 등을 다룬다. |
| [colors] | 터미널에 출력되는 결과 메시지의 색상을 설정할 수 있다. |
아래 예시를 통해서 일반적으로 관리하는 섹션과 내용에 대해 살펴보자.
[defaults]
inventory = ./inventory
#앞서 언급한 인벤토리 파일의 경로를 여기서 지정해준다.
remote_user = user
#관리 호스트에 ssh로 연결할 때 사용할 사용자의 이름을 지정한다.
#자유롭게 설정해서 만들어도 된다.
#여기서 만든 유저 이름으로 각 managed host에 user를 생성해줘야한다. (useradd 이용)
ask_pass = false
#ssh로 managed host에 연결할 떄, 암호를 묻는 메세지를 끄겠다는 것이다.
#완전히 자동화로 만들기 위해서 ask_pass를 false로 둔다.
[privilege_escalation]
become = true
#내가 설정한 사용자인 remote_user로 계속 있다는 게 아니라, 접속한 뒤에 root로 권한을 높이겠다는 뜻이다.
become_method = sudo
#사용자의 권한 전환 방식을 지정한다. (기본값이 sudo 이다.)
become_user = root
#managed host에서 전환할 사용자를 지정하는 것으로 root가 기본값이다.
become_ask_pass = false
#become_method 즉 사용자 전환 시 비밀번호 물어보지 않겠다는 설정이다.
주석 설명에 덧붙여서 ask_pass가 false이기 위해서는
control node와 managed host가 SSH 키 복사를 이미 해놓은 상태여야 한다.
참고) ssh keygen으로 키 복사하기

control node에서 public/private key pair를 생성하고,
controller가 private 키를 가지고 있고, public 키를 managed host로 배포해주는 방식으로 구성한다.
# 컨트롤 노드에서 키 생성하기
ssh-keygen -N '' -f /root/.ssh/id_rsa
# 컨트롤 노드에서 키 생성 후 managed host로 키 배포하기
ssh-copy-id <remote_user이름>@<remote_user_서버IP주소>
ssh-copy-id user@172.16.0.0 #예시
또 become_ask_pass = false를 쓰기 위해서는 managed host에 ssh로 접속해서,
remote_user의 /etc/sudoers 파일에 해당 유저에 대한 NOPASSWD 설정을 입력해줘야한다.
[remoted_user이름] ALL=(ALL) NOPASSWD:ALL
정리하자면
- remote_user = user
일단 user라는 이름표를 달고 서버 문을 열고 들어가면, (SSH 접속) - become = true
user가 이제부터 become_user로 변신하겠다고 선언하는 것이다. - become_user = root
어떤 사용자로 변할지 지정하는 것이다. (기본값이 root다)
따라서 become = true를 쓴다는 건
일반 유저 상태로 머물지 않고, 권한이 더 높은 계정으로 바꿔서 명령을 실행하겠다 는 말이 된다.
2. 인벤토리 파일 (Inventory)
앤서블에서 관리할 호스트 목록을 정의하는 파일로, 기본 위치는 /etc/ansible/hosts 이다.
근데 보통 따로 작업 디렉토리를 만들어서 플레이북 파일과 같이 위치시킨다.
INI 파일 형식이나, YAML 형식을 이용하여 작성한다.
[기본 위치에서 inventory 파일 위치를 변경하는 방법]
1. ansible -i 이용하기
ansible -i ./mydir/inventory
2. 구성파일의 [defaults] 섹션에서 inventory 위치 설정 해주기
이렇게 인벤토리 파일에 정의해놓으면 playbook에서 hosts를 지정할 때,
모든 호스트 목록을 포함하는 all || 특정 호스트 지정 || 특정 그룹 지정에 이용할 수 있다.
호스트 인벤토리는 크게 정적 인벤토리와 동적 인벤토리라는 두 가지 방법으로 정의할 수 있다.
2-1. 정적 인벤토리
텍스트 파일로, Ansible이 관리할 호스트를 목록으로 지정한다.
INI 형식으로 작성하면 대괄호로 섹션을 묶어 표현한다. (이렇게 대괄호로 묶어버리면 그룹으로 관리한다.)
서버 목록이 자주 안바뀔 때 사용한다.
1) 호스트 이름이나 IP 주소를 한 줄로 입력한 형태
nodeA
172.16.10.0
2) 섹션을 이용하여 그룹을 나눈 형태 (편의상 호스트 이름으로 작성)
| 세 개의 그룹으로 나눈 모습 | nodeA는 그룹에 속하지 않게 한 경우 | nodeA는 그룹에 속하지 않게 한 경우 (잘못된 예시) |
| [server1] nodeA [server2] nodeB nodeC [server3] nodeD |
nodeA [server1] nodeB nodeC [server2] nodeD |
[server1] nodeB nodeC [server2] nodeD nodeA |
그룹이 없는 노드들은 맨 위에 놓아야 한다.
3) 중첩 그룹 표현
호스트 그룹을 여러 개 포함할 수 있는데, 이를 위해서는 그룹 이름 생성 시 :children 접미사를 추가하면 된다.
[group0]
homeNode
[group1]
nodeA
[group2]
nodeB
nodeC
[groups:children]
group1
group2
2-2. 동적 인벤토리
클라우드 환경에서는 오토스케일링으로 서버가 유동적으로 늘어나거나 감소하고 IP도 계속 바뀐다.
그래서 정적 인벤토리를 이용해서 수동으로 서버를 관리하기가 어렵다는 문제가 있다.
그래서 동적으로 존재하는 서버를 자동으로 가져오는 방식이 동적 인벤토리 방식이다.
동적 인벤토리는 정적 인벤토리처럼 파일이 아니라 프로그램이다.
JSON 형식으로 host 정보를 출력한다.
3. 플레이북 파일 (Playbook)
Ansible은 특정한 작업을 수행하기 위해 플레이북 파일에 작업내용을 미리 정의한다.
플레이북은 작업 의도를 적는 YAML 설계도이고,
실제 작업은 Python으로 작성된 Ansible 모듈이 수행한다.
그리고 task라는 단위로 모듈과 인자를 정의하여 작성된다.
이 task는 하나의 모듈을 호출하고, 멱등성을 보장하도록 설계되어 있다.
플레이북 구성 요소
전체 구조는 아래의 계층 구조로 쉽게 이해할 수 있다.
Playbook
└─ Play
├─ hosts
├─ vars
├─ tasks
├─ handlers
└─ roles
└─ Task
├─ Module
└─ Module Arguments
플레이의 구성 요소
플레이북은 플레이로 구성되어 있고, 플레이는 아래 5개로 구성될 수 있다.
- hosts 작업 대상
- vars 변수
- tasks 실행할 작업 목록
- handlers 이벤트 기반 작업
- roles 역할 단위 구성
비유로 쉽게 이해하기
- 플레이북은 관리자가 작성하는 업무 지시서 같은 것으로, 어떤 작업을 어떤 순서로 수행할지를 정의한다.
- 플레이북 안의 play는 하나의 프로젝트 단위에 해당하며, 어느 현장에서 어떤 작업을 수행할지를 정한다.
- 각 play 안에는 task가 포함되는데, 이는 프로젝트를 진행하기 위한 구체적인 할 일 목록이다.
- 각 task는 실제 작업을 수행하는 모듈을 호출하고, 모듈은 Python으로 작성된 코드로 명령을 실행하는 실무 담당자 역할을 한다.
- managed host는 이러한 작업이 실제로 실행되는 현장, 즉 설정이 적용되는 서버를 의미한다.
플레이북 예시
---
- name: test play
hosts: web1.test.com #작업대상을 식별하는 용도로 정의한다.
tasks: #작업목록
#####################################################
- name: create new user
user: # 이게 파이썬 모듈 속성이다.
# modules에 user.py가 있는데 그걸 호출하는 것이다.
name: user01
uid: 4000
state: present #없을 때 새롭게 만들어주세요라는 코드로, 있다면 그냥 둔다.
########여기까지가 하나의 모듈 정보다.################ (파이썬 모듈이다.)
tasks 하위에는 대시 기호를 입력하여 name과 user라는 두가지 키를 입력하고 있다.
name은 설명을 위해 있는 것으로 필수는 아니다.
user는 모듈이라고 부르고, 하위 수준으로 입력된 인자를 통해 원하는 작업 내용을 구성할 수 있다.
위의 예는 user라는 항목의 하위에 name과 uid, state 정보를 입력해쏙,
이는 uid가 4000인 user01 사용자가 있는지 확인한 후, 사용자가 없다면 새로 생성하고, 있다면 그대로 둠으로써 멱등성을 보장한다.
모듈은 사용자가 원하는 작업 내용을 수행할 수 있도록 미리 설계 되어져 있고,
키워드만 입력하면 모듈을 실행할 수 있다. 또 작업 목록에는 단일 모듈 혹은 여러 개의 모듈이 정의 될 수 있다.
[ Playbook 중 task 예시 ] - 여러 개의 task 와 package 모듈을 사용한 경우
tasks:
- name: install web package
package: # 모듈
name: httpd # 모듈 인자(설치할 패키지 이름)
state: present # 모듈 인자(존재 상태 보장)
- name: install ntp package
package:
name: chrony
state: present
- name: install mail package
package:
name: postfix
state: present
3-2. 플레이북 실행하기
ansible-playbook이라는 명령어를 이용하여 플레이를 시작한다.
만약 플레이북이 아래와 같이 example.yaml이라는 파일명으로 저장되어 있다면,
ansible-playbook example.yaml 로 실행할 수 있다.
# site.yaml
- name: sample playbook
hosts: nodeA #host에 맞게 써줄 것!
tasks:
- name: sample task
yum:
name: httpd
state: latest
플레이북의 작업은 멱등성을 보장하므로, 여러 번 실행하는게 안전하다.
여러 번 실행하더라도 이미 구성되어 있다면, 따로 작업을 처리하지 않고 그대로 둔다.
3-3. 다중 플레이
하나의 playbook은 여러 개의 play를 정의할 수 있다.
하나의 호스트 집합에 대해 하나의 플레이를 실행하고, 해당 플레이가 완료되면
다른 호스트 집합에 대해 다른 플레이를 실행하는 플레이북을 작성할 수 있게 된다.
다중 Play일 때는 작성된 순서대로 실행된다.
만약에 host가 그룹으로 지정되어 있다면, 그 그룹에 있는 host에 play가 병렬로 처리된다.
(이 때 병렬 실행은 forks 개수보다 host 수가 적을 때 해당한다.)
예를 들어 아래와 같이 playbook이 작성되어 있고,
Inventory 파일에 web이라는 그룹이 있고, 그 그룹에 web1, web2, web3 가 있다고 해보자
#example_playbook.yaml
---
- name: install web packages
hosts: web
tasks:
- name: install httpd
package:
name: httpd
state: present
- name: install db packages
hosts: db
tasks:
- name: install mysql
package:
name: mysql-server
state: present
그러면 Ansible은 web1~web3 모두 동시에 install httpd task를 수행한다.
Ansible의 기본 구성을 알아보았다.
다음 글에서는 변수관리에 대해서 알아보자
'공부기록 > IaC' 카테고리의 다른 글
| [ Ansible ] 2. Ansible 변수 관리 | Vault | 암호화 (0) | 2026.01.29 |
|---|---|
| [ Ansible ] 0. Intro - Ansible이란 무엇일까? | Ansible 아키텍처 | Ansible 설치 (0) | 2026.01.26 |