RHEL 계열 관리 · RHCE — Ansible 로 RHEL 을 다룬다 · 실습
Ansible 로 RHEL 을 실제로 바꾼다
이 실습은 진짜 RHEL 계열에서 돕니다
VM 안에 AlmaLinux 9 가 떠 있습니다. systemd 가 PID 1 로 돌고, **SELinux 가
Enforcing** 이며, firewalld 가 살아 있습니다. 플레이북이 시스템을 진짜로
바꾸고, 채점기는 그 결과를 시스템에서 직접 읽습니다.
기존 Ansible 코스는 파드에서 돌아 문법 확인까지가 전부였습니다. 여기서는
설정하지 않으면 실제로 막힙니다.
처음 뜨는 데 2분쯤 걸립니다.
목표
RHCE 시험이 실제로 묻는 것들을 한 바퀴 돕니다. 사용자, 서비스, SELinux,
방화벽, 템플릿, 그리고 멱등성입니다.
왜 중요한가
RHCE(EX294)는 "Ansible 문법을 아는가" 를 묻지 않습니다. **시스템을 원하는
상태로 만들 수 있는가**를 묻습니다. 그래서 감점의 대부분이 문법이 아니라
이런 데서 나옵니다.
state: started만 쓰고enabled: true를 빠뜨려 재부팅 후 서비스가 안 뜸- firewalld 를
permanent로만 열어 지금은 안 열리거나,immediate로만 열어 재시작 후 사라짐 - SELinux 불리언을 켰지만
persistent가 없어 재부팅 때 되돌아감 command/shell을 조건 없이 써서 매번 changed 가 나옴
마지막 것이 특히 중요합니다. 멱등하지 않은 플레이북은 **돌릴 때마다 무언가를
바꾸는 플레이북**입니다. 그러면 "이번 실행이 무엇을 바꿨는가" 를 알 수 없고,
핸들러가 매번 서비스를 재시작해 불필요한 중단이 생깁니다.
단계
1. /root/rhce/inventory.ini 에 [webservers] 그룹으로 이 호스트를 넣고, /root/rhce/ansible.cfg 도 만드세요. ansible webservers -m ping 이 성공해야 합니다.
2. /root/rhce/users.yml 로 webadmin 그룹과 alice·bob 사용자(셸 /bin/bash, 보조 그룹 webadmin)를 만드세요. 반복(loop) 을 쓰세요.
3. /root/rhce/service.yml 로 httpd 를 설치하고 started 와 enabled 를 모두 만족시키세요. curl http://127.0.0.1/ 이 200 이어야 합니다.
4. /root/rhce/selinux.yml 로 httpd_can_network_connect 불리언을 영구히 켜고, /srv/web 에 httpd_sys_content_t 컨텍스트를 붙이세요.
5. /root/rhce/firewall.yml 로 http 서비스를 방화벽에 여세요. runtime 과 permanent 를 모두 만족시켜야 합니다.
6. /root/rhce/templates/index.html.j2 로 호스트명이 들어간 페이지를 만들고 /root/rhce/template.yml 로 배포하세요. 바뀔 때만 httpd 를 재시작하는 핸들러를 쓰세요.
7. 위 전부를 부르는 /root/rhce/site.yml 을 만드세요. 그리고 상태를 일부러 흔들어 놓은 뒤(서비스 중지·파일 삭제·계정 삭제) 두 번 돌려 changed 수를 /root/rhce/idempotent.txt 에 changed_first=·changed_second= 로 적으세요.
첫 번째는 0보다 커야 하고 두 번째는 0 이어야 합니다. 흔들지 않고 재면 첫 실행부터 0 이라 "고쳐서 0 이 됐다" 와 "원래 아무것도 안 했다" 를 구분할 수 없습니다.
8. /root/rhce/report.md 에 selinux=Enforcing, idempotent=yes, playbooks=<개수> 세 줄과 설명을 쓰세요.
참고
- SELinux 모듈은
ansible.posix.seboolean과community.general.sefcontext입니다. 두 컬렉션이 모두 필요하고, ansible-core 버전과 맞는 판이어야 합니다 — 안 맞으면 경고만 내고couldn't resolve module/action으로 죽는데, 그 문구가 오타를 의심하게 만듭니다. 컨텍스트를 정의한 뒤에는ansible.builtin.command: restorecon -R /srv/web을changed_when과 함께 써야 멱등이 깨지지 않습니다. - firewalld 모듈에는
permanent와immediate가 따로 있습니다. 둘 다 참이어야 "지금도 열리고 재시작 후에도 열린" 상태가 됩니다. - 팩트는
ansible_facts['hostname']또는{{ ansible_hostname }}으로 씁니다. changed수는ansible-playbook site.yml | grep -oE 'changed=[0-9]+'로 셉니다.- 흔한 실수 1:
command/shell을 조건 없이 쓰는 것. 그 태스크는 언제나 changed 입니다.creates:·changed_when:으로 조건을 주세요. - 흔한 실수 2:
state: started만 쓰고enabled: true를 빠뜨리는 것. 지금은 돌지만 재부팅하면 안 뜹니다. - 흔한 실수 3: SELinux 불리언에
persistent: true를 빠뜨리는 것. 지금은 켜지지만 재부팅 때 되돌아갑니다. - 흔한 실수 4: 두 태스크가 같은 파일을 서로 다른 내용으로 관리하는 것. 서로를 되돌리며 둘 다 영원히 changed 이고, 각 태스크는 따로 보면 멀쩡해서 가장 찾기 어렵습니다. 파일 하나에는 주인이 하나여야 하고, 부트스트랩용이라면
force: false로 "없을 때만" 을 명시하세요.
단계 8개
- 인벤토리와 설정 파일
- 사용자와 그룹을 만든다
- 서비스는 두 가지를 만족해야 한다
- SELinux 는 켜져 있고 실제로 막는다
- runtime 과 permanent 는 다르다
- 바뀔 때만 재시작한다
- 두 번째 실행은 조용해야 한다
- 무엇을 배웠나