Red Hat Certified Engineer (RHCE) #4 ad-hoc 명령: 모듈 즉석 실행
#3에서 ansible.cfg와 SSH, become로 제어 노드가 관리 노드에 어떻게 연결하는지 잡았습니다. 연결이 되면 이제 실제로 명령을 보내 봐야 합니다. 플레이북을 작성하기 전에, 한 줄로 모듈을 즉석 실행하는 ad-hoc 명령부터 익히겠습니다. ad-hoc은 빠른 점검과 일회성 작업에 쓰는 도구이며, 동시에 각 모듈이 어떤 일을 하는지 손에 익히는 가장 빠른 길입니다.
ad-hoc 명령이란 #
ad-hoc 명령은 플레이북 파일을 만들지 않고 ansible 명령 한 줄로 모듈 하나를 호출하는 실행 방식입니다. “지금 모든 웹 서버가 살아 있는지 확인”, “특정 그룹에 패키지 한 개를 설치”, “파일 한 개를 배포” 같은 단발성 작업에 적합합니다. 같은 작업을 매번 반복하거나 여러 작업을 묶어야 한다면 플레이북이 맞지만, 한 번 보고 끝낼 점검에는 ad-hoc이 훨씬 빠릅니다.
ad-hoc 명령의 기본 구조는 다음과 같습니다.
ansible <pattern> -m <module> -a "<arguments>"각 요소의 의미는 다음과 같습니다.
| 요소 | 의미 |
|---|---|
<pattern> | 대상 호스트 패턴. inventory의 호스트명, 그룹명, 또는 와일드카드 |
-m <module> | 실행할 모듈 이름. 생략하면 기본 모듈(command)이 쓰임 |
-a "<args>" | 모듈에 넘길 인자. key=value 형식이 일반적 |
-b | become로 권한 상승(기본 root) |
-i <inventory> | inventory 파일 지정 |
가장 단순한 예로, web 그룹의 모든 호스트에 ping 모듈을 보내는 명령은 다음과 같습니다.
ansible web -m ping여기서 ping은 ICMP가 아니라 Ansible이 관리 노드에 연결해 Python을 실행할 수 있는지 확인하는 모듈입니다. 응답으로 pong이 돌아오면 SSH 연결과 Python 환경이 모두 정상이라는 뜻입니다.
호스트 패턴 #
ad-hoc이든 플레이북이든 첫 인자는 항상 대상 호스트 패턴입니다. 시험에서 “이 그룹에만 적용하라” 같은 요구가 자주 나오므로 패턴 문법을 정확히 알아 두겠습니다.
| 패턴 | 대상 |
|---|---|
all 또는 * | inventory의 모든 호스트 |
web | web 그룹에 속한 호스트 |
web:db | web 또는 db 그룹(합집합) |
web:&db | web이면서 db에도 속한 호스트(교집합) |
web:!staging | web에 속하되 staging은 제외(차집합) |
192.168.* | 패턴에 맞는 호스트명/IP |
web[0:2] | 그룹 안에서 인덱스 범위로 선택 |
예를 들어 web 그룹에서 staging을 뺀 호스트에만 명령을 보내려면 다음과 같이 씁니다. 셸이 !를 해석하지 않도록 작은따옴표로 감싸겠습니다.
ansible 'web:!staging' -m ping대상이 실제로 어떤 호스트로 풀리는지 미리 확인하려면 --list-hosts를 붙이면 됩니다.
ansible 'web:!staging' --list-hosts자주 쓰는 모듈 #
ad-hoc으로 가장 자주 쓰는 모듈들을 정리하겠습니다. 같은 모듈을 플레이북에서도 그대로 쓰므로, 여기서 옵션을 익혀 두면 #5 이후가 수월해집니다.
ping #
연결과 Python 실행을 점검합니다. 인자가 없습니다.
ansible all -m pingcommand와 shell의 차이 #
둘 다 관리 노드에서 명령을 실행하지만 동작이 다릅니다.
command. 기본 모듈입니다. 셸을 거치지 않고 명령을 직접 실행합니다. 따라서 파이프(|), 리다이렉트(>), 변수 확장($HOME) 같은 셸 기능을 쓸 수 없습니다. 보안상 더 안전하므로 셸 기능이 필요 없으면 이쪽이 권장됩니다.shell./bin/sh를 거쳐 실행하므로 파이프와 리다이렉트, 환경 변수 확장이 모두 동작합니다.
# command: 셸 기능 없이 직접 실행
ansible web -m command -a "uptime"
# command가 기본 모듈이므로 -m 생략 가능
ansible web -a "id"
# shell: 파이프와 리다이렉트가 필요할 때
ansible web -m shell -a "ps aux | grep nginx"command로 파이프를 쓰면 |가 명령의 인자로 넘어가 실패하므로, 그럴 때만 shell을 쓰겠습니다.
copy #
제어 노드의 파일을 관리 노드로 복사하거나, 내용을 직접 써넣습니다.
# 파일 복사
ansible web -m copy -a "src=/etc/motd dest=/etc/motd owner=root mode=0644" -b
# content로 내용을 직접 작성
ansible web -m copy -a 'content="Managed by Ansible\n" dest=/etc/motd' -bfile #
파일과 디렉터리의 상태(존재, 권한, 소유자, 링크)를 관리합니다.
# 디렉터리 생성
ansible web -m file -a "path=/opt/app state=directory owner=app mode=0755" -b
# 파일 삭제
ansible web -m file -a "path=/tmp/old.log state=absent" -b
# 심볼릭 링크 생성
ansible web -m file -a "src=/opt/app/current dest=/opt/app/live state=link" -bstate의 주요 값은 directory(디렉터리), touch(빈 파일), absent(삭제), link(심링크)입니다.
package와 dnf #
패키지를 설치하거나 제거합니다. dnf는 RHEL 계열 전용이고, package는 배포판에 맞는 패키지 관리자를 자동으로 고르는 범용 모듈입니다.
# dnf로 설치
ansible web -m dnf -a "name=httpd state=present" -b
# package로 설치(범용)
ansible web -m package -a "name=httpd state=present" -b
# 최신으로 갱신
ansible web -m dnf -a "name=httpd state=latest" -b
# 제거
ansible web -m dnf -a "name=httpd state=absent" -bservice와 systemd #
서비스를 시작,중지하거나 부팅 시 자동 시작을 설정합니다.
# 시작하고 부팅 시 자동 시작 활성화
ansible web -m service -a "name=httpd state=started enabled=yes" -b
# systemd 모듈로 재시작
ansible web -m systemd -a "name=httpd state=restarted" -bstate는 started, stopped, restarted, reloaded를 받고, enabled로 부팅 시 자동 시작 여부를 정합니다.
user #
사용자 계정을 생성하거나 제거합니다.
# 사용자 생성
ansible web -m user -a "name=deploy groups=wheel state=present" -b
# 사용자 제거(홈 디렉터리 포함)
ansible web -m user -a "name=deploy state=absent remove=yes" -blineinfile #
파일 안의 특정 행을 보장하거나 교체합니다. 설정 파일의 한 줄만 바꿔야 할 때 유용합니다.
ansible web -m lineinfile -a 'path=/etc/ssh/sshd_config regexp="^#?PermitRootLogin" line="PermitRootLogin no"' -bregexp에 맞는 행이 있으면 line으로 교체하고, 없으면 파일 끝에 추가합니다.
become로 권한 상승 #
패키지 설치나 시스템 파일 수정처럼 root 권한이 필요한 작업은 -b(또는 --become)를 붙여 권한을 상승시킵니다. 특정 사용자로 상승하려면 --become-user를 함께 씁니다.
# root로 상승해 패키지 설치
ansible web -m dnf -a "name=vim state=present" -b
# 특정 사용자로 상승
ansible web -m command -a "whoami" -b --become-user=app#3에서 ansible.cfg에 become=true를 지정해 두었다면 -b 없이도 상승되지만, ad-hoc에서는 명시적으로 -b를 붙이는 편이 의도가 분명합니다.
ansible-doc으로 모듈 옵션 찾기 #
시험장에는 인터넷이 없으므로 모듈의 옵션은 ansible-doc으로 찾습니다. 모듈 이름과 주요 옵션, 그리고 문서 하단의 EXAMPLES를 빠르게 읽는 습관이 시간을 아낍니다.
# 모듈 전체 문서
ansible-doc copy
# 한 줄 요약만
ansible-doc -s copy
# 설치된 모듈 목록
ansible-doc -lansible-doc -s <module>은 옵션을 key=value 골격으로 보여 주므로, 인자를 어떻게 쓸지 빠르게 확인하기 좋습니다. 모듈 이름이 기억나지 않을 때는 ansible-doc -l | grep <키워드>로 후보를 좁히겠습니다.
시험 포인트 #
- command vs shell. 파이프,리다이렉트,변수 확장이 필요하면
shell, 그렇지 않으면command(기본 모듈)를 씁니다. 셸 기능이 필요 없는데shell을 쓰면 불필요하게 위험을 키웁니다. - 멱등성이 없는 모듈에 주의.
command와shell은 멱등성이 없어 실행할 때마다 changed로 표시됩니다. 같은 결과를 보장해야 한다면copy,file,dnf,service같은 상태 기반 모듈을 쓰는 것이 RHCE의 채점 기준에 맞습니다. - become는 명시적으로. 권한이 필요한 작업은
-b를 빠뜨리면 권한 오류로 실패하므로 습관처럼 붙입니다. - ansible-doc이 유일한 참고서. 옵션 이름이 헷갈리면 추측하지 말고
ansible-doc -s로 확인합니다. - ad-hoc보다 playbook 위주. 시험은 대부분 플레이북으로 답을 요구하지만, ad-hoc은 연결 확인과 모듈 동작 점검에 유용하므로 두 방식을 모두 손에 익혀 둡니다.
ad-hoc과 playbook의 경계 #
ad-hoc은 빠르고 가볍지만, 두 개 이상의 작업을 순서대로 묶거나 변수,핸들러,조건을 쓰려면 한계가 있습니다. 여러 작업을 순서대로 실행하거나, 변수와 Jinja2 템플릿으로 호스트별로 다르게 구성하거나, 변경이 생겼을 때만 서비스를 재시작하는 핸들러가 필요하거나, 같은 작업을 반복,버전 관리해야 한다면 플레이북으로 넘어가는 것이 맞습니다. 즉 ad-hoc은 “지금 한 번 확인,실행"이고, 반복하고 재현해야 하는 구성은 플레이북의 몫입니다.
정리 #
이번 글에서 잡은 것:
- ad-hoc 구조.
ansible <pattern> -m <module> -a "args"로 모듈 하나를 즉석 실행합니다. - 호스트 패턴.
all, 그룹명,:(합집합),:&(교집합),:!(차집합),*(와일드카드)로 대상을 고릅니다. - 자주 쓰는 모듈. ping, command/shell, copy, file, package/dnf, service/systemd, user, lineinfile를 예제로 익혔습니다.
- become. 권한이 필요한 작업에는
-b를 붙입니다. - command vs shell. 셸 기능이 필요할 때만 shell을 쓰고, command와 shell은 멱등성이 없다는 점을 기억합니다.
- ansible-doc. 인터넷 없는 환경에서
ansible-doc -s <module>이 유일한 참고서입니다.
다음: Playbook 기초 #
ad-hoc으로 모듈 하나를 즉석 실행하는 법을 잡았습니다. 이제 같은 모듈들을 파일로 묶어 반복 가능하게 만드는 단계입니다.
#5 Playbook 기초: task, handler, 멱등성에서는 플레이북의 기본 구조(play, task, module), 변경이 생겼을 때만 도는 handler, 그리고 RHCE 채점의 핵심인 멱등성을 직접 작성하고 두 번 돌려 검증하는 흐름까지 정리하겠습니다.