서버마다 SSH로 접속해 같은 파일을 복사하고 있다면, 앤서블(Ansible)로 작업을 한 번에 묶을 수 있어요. 관리 대상 목록인 인벤토리와 원하는 작업을 적은 YAML 파일인 플레이북을 만들고, 명령 하나로 실행합니다.
이 글에서는 Linux 서버 두 대에 같은 안내 파일을 배포합니다. 먼저 한 대에서 확인한 뒤 나머지 서버로 넓히는 예제이며, 대상이 한 대뿐이어도 그대로 따라 할 수 있습니다.
이 글의 목차
준비 환경과 접속 조건
| 구분 | 준비할 것 |
|---|---|
| 제어 노드 | 앤서블 명령을 실행할 Ubuntu 24.04 LTS PC 또는 서버. 인터넷 연결과 패키지 설치용 sudo 권한 |
| 관리 대상 | SSH 서버와 호환되는 Python 3가 설치된 Linux 서버 1~2대 |
| 접속 계정 | 아래 예제의 ops를 실제 SSH 계정으로 변경. 공개 키 인증이 준비되어 있어야 함 |
앤서블은 제어 노드에 설치합니다. 이 글에서 사용하는 Linux용 기본 모듈은 대상 서버에 앤서블 에이전트를 설치하지 않고 SSH와 Python으로 실행합니다. Python 지원 범위는 앤서블 버전마다 다르므로, 기존 환경에 적용한다면 공식 지원 표도 확인합니다.
1. 제어 노드에 앤서블 설치
아래 명령은 제어 노드에서 실행합니다. pipx는 Python 명령줄 도구를 별도 환경에 설치하는 도구이며, 이 예제는 기본 모듈만 필요하므로 ansible-core 패키지로 충분합니다.
sudo apt update
sudo apt install -y pipx openssh-client
pipx install ansible-core
export PATH="$HOME/.local/bin:$PATH"
pipx ensurepath
ansible --version
export는 현재 터미널에서 명령을 바로 찾도록 하고, pipx ensurepath는 이후 로그인 환경의 경로를 설정합니다. ansible --version에서 설치된 core 버전과 Python 경로를 확인하세요. 설치 절차는 공식 pipx 설치 안내를 따릅니다.
2. SSH 연결과 인벤토리 확인
예제 주소 192.0.2.11과 192.0.2.12는 문서용 주소입니다. 실제 서버 IP와 계정으로 바꾸고, 먼저 일반 SSH 접속부터 확인합니다. 첫 연결의 호스트 키 지문은 서버 관리자나 콘솔에서 확인한 값과 대조한 뒤 승인합니다.
ssh ops@192.0.2.11 "python3 --version"
ssh ops@192.0.2.12 "python3 --version"
mkdir -p ~/ansible-demo
cd ~/ansible-demo
공개 키 인증을 아직 준비하지 않았다면 제어 노드의 공개 키를 대상 계정의 ~/.ssh/authorized_keys에 등록합니다. 개인 키는 제어 노드에 보관합니다. 한 대만 실습한다면 두 번째 SSH 명령과 아래 node2 행은 생략해도 됩니다.
작업 폴더에 inventory.ini 파일을 다음 내용으로 저장합니다. node1과 node2는 앤서블에서 부를 별칭이고, lab은 두 서버를 묶는 그룹 이름입니다.
[lab]
node1 ansible_host=192.0.2.11
node2 ansible_host=192.0.2.12
[lab:vars]
ansible_user=ops
대상 목록을 확인한 뒤 ping 모듈로 접속을 점검합니다.
ansible-inventory -i inventory.ini --graph
ansible lab -i inventory.ini -m ansible.builtin.ping
각 서버에 SUCCESS와 "ping": "pong"이 나오면 다음 작업으로 넘어갑니다. 이 ping 모듈은 ICMP 통신 검사가 아니라 SSH 로그인과 Python 실행을 확인합니다. 별도 개인 키를 쓴다면 명령에 --private-key ~/.ssh/실제_키_파일을 추가합니다.
3. 파일을 배포할 플레이북 작성
같은 폴더에 deploy.yml을 저장합니다. YAML의 들여쓰기에는 탭 대신 공백을 사용합니다.
---
- name: Deploy a demo file to Linux servers
hosts: lab
gather_facts: false
tasks:
- name: Write the same demo file on each server
ansible.builtin.copy:
dest: /tmp/maruops-ansible-demo.txt
content: |
Managed by Ansible.
mode: "0644"
hosts: lab은 인벤토리의 그룹을 선택합니다. gather_facts: false는 이 작업에 필요 없는 시스템 정보 수집을 생략합니다. copy 모듈은 대상 파일의 내용과 권한을 맞추며, mode는 문자열로 적어 권한 값의 해석을 분명히 합니다.
이 예제는 /tmp/maruops-ansible-demo.txt의 내용을 위 문장으로 맞춥니다. 기존에 같은 이름의 파일이 있다면 덮어쓸 수 있으므로 실습용 경로인지 확인합니다. /tmp의 파일은 재부팅이나 정리 정책으로 지워질 수 있어 영구 설정 파일 보관에는 적합하지 않습니다.
4. 한 대에서 확인한 뒤 전체 실행
먼저 문법과 실행 대상을 확인하고, node1 한 대에서 바뀔 내용을 미리 봅니다. 아래 명령도 ~/ansible-demo 폴더에서 실행합니다.
ansible-playbook -i inventory.ini deploy.yml --syntax-check
ansible-playbook -i inventory.ini deploy.yml --list-hosts
ansible-playbook -i inventory.ini deploy.yml --limit node1 --check --diff
--check는 변경을 예측하고, --diff는 파일 내용의 차이를 보여 줍니다. 이 글의 copy 작업은 두 기능을 지원하지만, 모든 모듈과 플레이북이 같은 방식으로 미리 실행되는 것은 아닙니다. 문법 검사가 통과해도 접속이나 실행 권한까지 보장하지는 않습니다.
예상한 대상과 내용이 맞으면 한 대에 실제로 적용하고, 같은 플레이북을 전체 그룹에 실행합니다.
ansible-playbook -i inventory.ini deploy.yml --limit node1
ansible-playbook -i inventory.ini deploy.yml
ansible lab -i inventory.ini -m ansible.builtin.command \
-a "cat /tmp/maruops-ansible-demo.txt"
마지막 명령으로 각 서버에 Managed by Ansible.이 저장됐는지 확인합니다. 확인용 command 모듈은 읽기 명령도 기본적으로 CHANGED로 보고할 수 있습니다. 파일 배포가 다시 변경됐는지는 다음 플레이북 실행 결과로 판단합니다.
같은 플레이북을 한 번 더 실행해 보세요.
ansible-playbook -i inventory.ini deploy.yml
파일 내용과 권한이 그대로라면 서버별 PLAY RECAP에 changed=0, unreachable=0, failed=0이 표시됩니다. 같은 작업을 반복해도 원하는 상태가 유지되면 추가 변경을 하지 않는 성질을 멱등성이라고 합니다. 임의의 셸 명령을 실행한다고 이 성질이 자동으로 생기지는 않습니다.
실행이 막힐 때 확인할 곳
| 증상 | 확인할 곳 |
|---|---|
UNREACHABLE / Permission denied | 일반 SSH 접속, IP·포트·계정·키를 확인합니다. SSH 포트가 22가 아니라면 해당 호스트 행에 ansible_port=실제포트를 추가합니다. |
| Python 실행 실패 | 대상 서버의 Python 버전과 지원 범위를 확인합니다. 경로가 다르면 호스트 행에 ansible_python_interpreter=/실제/python3/경로를 지정합니다. |
| 파일 쓰기 권한 오류 | 이 예제의 파일 소유자와 경로를 확인합니다. /etc 등 관리자 권한이 필요한 작업은 become: true와 대상 계정의 sudo 권한이 필요합니다. sudo 암호 입력이 필요하면 실행 명령에 -K를 추가합니다. |
처음에는 인벤토리와 플레이북 두 파일만 관리해도 충분해요. 안내 파일 배포가 익숙해지면 copy 작업을 실제로 반복하는 설정 파일 배포로 바꾸고, 한 대에서 확인한 뒤 적용 범위를 넓히면 됩니다.
확인 기준: 2026년 10월 22일 공식 문서를 확인했습니다. Ubuntu 24.04 컨테이너 세 대(제어 노드 1대·관리 대상 2대), Python 3.12.3, ansible-core 2.21.5에서 SSH 접속, 파일 배포, 변경 미리보기와 재실행을 검증했습니다. 운영 서버의 설정이나 서비스는 변경하지 않았습니다.



