Red Hat Certified Engineer (RHCE) #19 풀스케일 모의고사: 15개 작업 + 해설
#1 시험 소개에서 #18 시험 팁까지 RHCE 전 영역을 모두 다뤘습니다. 이번 글은 실제 EX294 형식에 맞춘 풀스케일 모의고사입니다. 전 영역을 통합한 15개 작업으로 구성했고, 각 작업별로 배점이 정해져 있습니다.
권장 제한 시간은 실제 시험과 같은 4시간입니다. 합격선은 210/300(70%)이며, 15개 작업의 배점을 합산해 채점합니다. 한 작업에 막히면 표시해 두고 넘어간 뒤, 배점이 높고 손에 익은 작업부터 처리하는 전략이 합격선을 넘기는 길입니다.
RHCE는 명령을 한 번 잘 치는 시험이 아니라 같은 플레이북을 여러 번 돌려도 결과가 같은 멱등성을 검증하는 시험입니다. 모든 작업은 가능하면 모듈로 작성하고 command,shell 남용을 피하며, 최신 환경에서는 ansible.builtin.copy처럼 FQCN(Fully Qualified Collection Name)으로 모듈을 적는 습관이 채점과 디버깅을 모두 돕습니다. 각 작업은 먼저 스스로 끝까지 푼 뒤 정답을 펼쳐 보십시오. 정답을 먼저 읽으면 손에 익지 않습니다.
풀이 방법 #
- 제어 노드 한 대와 관리 노드 여러 대로 꾸린 환경에서 푸는 것이 가장 실전에 가깝습니다. 로컬에서 어렵다면 클라우드 VM 서너 대로 제어 노드 한 대와 관리 노드
node1〜node4를 세워 두십시오. inventory와 SSH 키, become까지 직접 꾸려 본 사람이 시험장에서 흔들리지 않습니다. - 작성한 플레이북은 반드시 두 번 실행합니다. 두 번째 실행에서
changed가 0으로 나와야 멱등성이 검증된 것입니다.
ansible-navigator run -m stdout site.yml
ansible-navigator run -m stdout site.yml # 두 번째: changed=0 확인- 인터넷이 없으므로 모듈 사용법은
ansible-doc <module>로 찾습니다. 문서 하단의 EXAMPLES를 빠르게 보는 습관이 시간을 아낍니다. 이 시리즈에서 잡은ansible.cfg의inventory,remote_user,become기본값을 먼저 적용하면 매 명령에서 옵션을 줄일 수 있습니다. - 15개를 끝까지 푼 뒤 정답을 펼쳐 한 번에 채점합니다. 중간에 정답을 보면 실제 시험 감각이 흐려집니다.
영역 분포 #
실제 EX294의 영역 비중에 맞춰 15개 작업을 배치했습니다. RHCSA 자동화가 시험의 절반가량을 차지하므로 작업 수도 가장 많습니다.
| # | 영역 | 작업 수 | 작업 번호 |
|---|---|---|---|
| 1 | 환경과 inventory, 연결 | 2 | 1, 2 |
| 2 | 플레이북과 변수, 템플릿 | 3 | 3, 4, 5 |
| 3 | 제어 흐름과 오류 처리, Vault | 3 | 6, 7, 8 |
| 4 | role과 collection, system roles | 3 | 9, 10, 11 |
| 5 | RHCSA 작업 자동화 | 4 | 12, 13, 14, 15 |
배점은 영역 비중과 작업 난이도를 반영해 합계 300점으로 두었습니다. 채점 기준은 글 끝에 정리했습니다.
작업 1 (16점): 환경과 inventory, 연결 #
작업 디렉터리 /home/ansible/exam에 ansible.cfg와 inventory를 작성하세요. inventory에는 관리 노드 node1〜node4가 있어야 하며, node1,node2는 그룹 webservers, node3은 그룹 dbservers, node4는 그룹 balancers에 속합니다. 또한 webservers와 dbservers를 자식으로 갖는 그룹 prod를 만듭니다. ansible.cfg는 이 inventory를 기본으로 쓰고, remote_user는 ansible, privilege escalation은 sudo로 자동 적용되도록 설정합니다.
정답
/home/ansible/exam/ansible.cfg를 작성합니다.
[defaults]
inventory = ./inventory
remote_user = ansible
host_key_checking = False
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False/home/ansible/exam/inventory를 작성합니다.
[webservers]
node1
node2
[dbservers]
node3
[balancers]
node4
[prod:children]
webservers
dbservers구성을 검증합니다.
ansible-inventory --graph
ansible prod --list-hosts해설: [prod:children]는 다른 그룹을 자식으로 묶는 그룹입니다. ansible.cfg의 inventory 값을 상대 경로(./inventory)로 두면 작업 디렉터리에서 실행할 때만 인식되므로, 채점 시 실행 위치를 작업 디렉터리로 두는 점이 함정입니다. become = True를 [privilege_escalation] 섹션에 두어야 모든 플레이에서 별도 선언 없이 root 권한이 적용됩니다.
작업 2 (16점): 환경과 inventory, 연결 #
webservers 그룹에는 변수 package_state: present를, dbservers 그룹에는 변수 db_port: 5432를 적용하세요. 또한 node1 한 대에만 host 변수 server_role: primary를 적용하세요. group_vars와 host_vars 디렉터리 구조로 분리해 정의하고, ad-hoc 명령으로 각 변수가 올바른 호스트에서만 보이는지 확인합니다.
정답
작업 디렉터리 아래에 디렉터리와 변수 파일을 만듭니다.
mkdir -p group_vars host_varsgroup_vars/webservers.yml를 작성합니다.
package_state: presentgroup_vars/dbservers.yml를 작성합니다.
db_port: 5432host_vars/node1.yml를 작성합니다.
server_role: primary변수가 올바른 호스트에서만 보이는지 ad-hoc으로 확인합니다.
ansible node1 -m ansible.builtin.debug -a "var=server_role"
ansible node3 -m ansible.builtin.debug -a "var=db_port"
ansible node2 -m ansible.builtin.debug -a "var=package_state"해설: group_vars/<그룹명>.yml와 host_vars/<호스트명>.yml는 inventory와 같은 디렉터리에 두면 Ansible이 자동으로 로드합니다. 파일명이 그룹,호스트 이름과 정확히 일치해야 하며, 오타가 나면 오류 없이 변수가 빈 채로 넘어가 디버깅이 어렵습니다. host 변수는 group 변수보다 우선순위가 높으므로, node1에 두 값이 겹치면 host_vars가 이깁니다.
작업 3 (20점): 플레이북과 변수, 템플릿 #
webservers 그룹에 httpd를 설치,기동하는 플레이북 web.yml을 작성하세요. httpd 패키지를 설치하고, 서비스를 enabled,started 상태로 두며, /var/www/html/index.html을 "Welcome to {{ inventory_hostname }}" 내용으로 생성합니다. index.html이 바뀌면 httpd를 재시작하는 handler를 두십시오. 플레이북은 두 번 실행해도 멱등해야 합니다.
정답
web.yml을 작성합니다.
---
- name: Configure web servers
hosts: webservers
tasks:
- name: Install httpd
ansible.builtin.dnf:
name: httpd
state: present
- name: Ensure httpd is enabled and started
ansible.builtin.service:
name: httpd
state: started
enabled: true
- name: Deploy index page
ansible.builtin.copy:
content: "Welcome to {{ inventory_hostname }}\n"
dest: /var/www/html/index.html
notify: Restart httpd
handlers:
- name: Restart httpd
ansible.builtin.service:
name: httpd
state: restartedansible-navigator run -m stdout web.yml
ansible-navigator run -m stdout web.yml # changed=0해설: copy 모듈의 content는 짧은 본문을 인라인으로 넣을 때 쓰며, 같은 내용이면 두 번째 실행에서 ok가 나와 멱등합니다. handler는 작업이 changed일 때만 notify로 트리거되므로, 두 번째 실행에서는 index.html이 안 바뀌어 handler도 돌지 않습니다. handler 이름은 notify 값과 정확히 일치해야 호출됩니다.
작업 4 (16점): 플레이북과 변수, 템플릿 #
플레이북 facts.yml을 작성해, 모든 prod 호스트에서 해당 호스트의 총 메모리(MB)와 기본 IPv4 주소를 수집하고, 메모리가 2048MB 미만인 호스트에 대해서만 경고 메시지를 출력하세요. 출력에는 호스트명과 실제 메모리 값이 포함되어야 합니다.
정답
facts.yml을 작성합니다.
---
- name: Report host facts
hosts: prod
tasks:
- name: Show memory and IP
ansible.builtin.debug:
msg: "{{ inventory_hostname }} has {{ ansible_facts['memtotal_mb'] }}MB, IP {{ ansible_facts['default_ipv4']['address'] }}"
- name: Warn on low memory
ansible.builtin.debug:
msg: "WARNING: {{ inventory_hostname }} has only {{ ansible_facts['memtotal_mb'] }}MB"
when: ansible_facts['memtotal_mb'] | int < 2048ansible-navigator run -m stdout facts.yml해설: fact는 플레이 시작 시 gather_facts(기본 true)로 자동 수집되며, ansible_facts['memtotal_mb']처럼 딕셔너리로 접근합니다. 숫자 비교 시 | int 필터를 거치면 문자열,정수 혼동을 막습니다. fact 수집을 끈 플레이라면 ansible.builtin.setup 모듈로 먼저 모아야 변수가 채워집니다.
작업 5 (20점): 플레이북과 변수, 템플릿 #
Jinja2 템플릿 motd.j2와 플레이북 motd.yml을 작성하세요. 모든 prod 호스트의 /etc/motd에, 호스트명,운영체제 배포판과 버전,CPU 개수가 포함된 안내문을 배포합니다. 템플릿은 fact를 참조하며, 내용이 바뀌면 파일이 갱신되어야 합니다.
정답
motd.j2를 작성합니다.
Welcome to {{ ansible_facts['hostname'] }}
OS: {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}
CPUs: {{ ansible_facts['processor_vcpus'] }}
Managed by Ansible. Do not edit manually.motd.yml을 작성합니다.
---
- name: Deploy MOTD from template
hosts: prod
tasks:
- name: Template /etc/motd
ansible.builtin.template:
src: motd.j2
dest: /etc/motd
owner: root
group: root
mode: '0644'ansible-navigator run -m stdout motd.yml
ansible-navigator run -m stdout motd.yml # changed=0해설: template 모듈은 제어 노드의 .j2 파일을 렌더링해 관리 노드에 배포하며, copy와 달리 변수와 제어 흐름을 처리합니다. 렌더링 결과가 같으면 두 번째 실행에서 변경이 없어 멱등합니다. mode는 따옴표로 문자열('0644')로 두어야 8진수 해석 오류를 피합니다.
작업 6 (20점): 제어 흐름과 오류 처리, Vault #
플레이북 users_loop.yml을 작성해, 변수 리스트 app_users에 정의된 사용자 세 명(alice,bob,carol)을 loop로 한 번에 생성하세요. 각 사용자는 보조 그룹 developers에 속하고 셸은 /bin/bash입니다. developers 그룹은 사용자 생성 전에 만들어야 합니다.
정답
users_loop.yml을 작성합니다.
---
- name: Create users with loop
hosts: webservers
vars:
app_users:
- alice
- bob
- carol
tasks:
- name: Ensure developers group exists
ansible.builtin.group:
name: developers
state: present
- name: Create application users
ansible.builtin.user:
name: "{{ item }}"
groups: developers
append: true
shell: /bin/bash
state: present
loop: "{{ app_users }}"ansible-navigator run -m stdout users_loop.yml
ansible-navigator run -m stdout users_loop.yml # changed=0해설: loop는 리스트를 순회하며 item 변수로 각 값을 받습니다. append: true가 없으면 groups가 사용자의 보조 그룹을 통째로 덮어써 기존 그룹이 떨어지는 함정이 있습니다. 그룹 생성 작업을 사용자 생성 앞에 두어, 보조 그룹이 없어 실패하는 일을 막습니다.
작업 7 (20점): 제어 흐름과 오류 처리, Vault #
플레이북 safe_deploy.yml을 작성하세요. block에서 패키지 mariadb-server를 설치하고 mariadb 서비스를 기동하되, 설치 중 실패하면 rescue에서 /var/log/deploy-failed.log에 실패 사실을 기록하고, always에서는 결과와 무관하게 디스크 사용량을 출력합니다. 또한 서비스 상태를 확인하는 command 작업이 출력 문자열에 active가 있을 때만 changed로 보고되지 않도록 changed_when을 false로 두세요.
정답
safe_deploy.yml을 작성합니다.
---
- name: Safe deploy with block/rescue/always
hosts: dbservers
tasks:
- name: Deploy database
block:
- name: Install mariadb-server
ansible.builtin.dnf:
name: mariadb-server
state: present
- name: Start mariadb
ansible.builtin.service:
name: mariadb
state: started
enabled: true
- name: Check service status
ansible.builtin.command: systemctl is-active mariadb
register: svc_status
changed_when: false
rescue:
- name: Record failure
ansible.builtin.copy:
content: "mariadb deploy failed on {{ inventory_hostname }}\n"
dest: /var/log/deploy-failed.log
always:
- name: Report disk usage
ansible.builtin.command: df -h /
register: disk
changed_when: false
- name: Show disk usage
ansible.builtin.debug:
var: disk.stdout_linesansible-navigator run -m stdout safe_deploy.yml해설: block의 작업이 실패하면 rescue로 넘어가고, always는 성공,실패와 무관하게 항상 실행됩니다. command,shell은 항상 changed로 보고되므로, 상태 확인처럼 시스템을 바꾸지 않는 조회에는 changed_when: false를 붙여 멱등성을 지킵니다. rescue가 처리하면 플레이는 실패로 끝나지 않으므로 부분 복구가 가능합니다.
작업 8 (20점): 제어 흐름과 오류 처리, Vault #
Vault로 암호화한 변수 파일 secret.yml을 만들고(변수 db_root_password: S3cret!), 플레이북 vault_use.yml에서 이 변수를 읽어 /root/db_credentials.txt에 mode 0600으로 기록하세요. 실행 시 vault 비밀번호를 파일 vault_pass.txt로 제공한다고 가정합니다.
정답
암호화 변수 파일을 만듭니다.
echo 'changeme' > vault_pass.txt
ansible-vault create --vault-password-file vault_pass.txt secret.yml에디터가 열리면 다음을 입력하고 저장합니다.
db_root_password: "S3cret!"vault_use.yml을 작성합니다.
---
- name: Use a vaulted variable
hosts: dbservers
vars_files:
- secret.yml
tasks:
- name: Write credentials file
ansible.builtin.copy:
content: "root_password={{ db_root_password }}\n"
dest: /root/db_credentials.txt
owner: root
group: root
mode: '0600'vault 비밀번호 파일과 함께 실행합니다.
ansible-navigator run -m stdout vault_use.yml --vault-password-file vault_pass.txt해설: ansible-vault create는 새 암호화 파일을, ansible-vault edit는 기존 파일을 편집합니다. 암호화 변수를 쓰는 플레이북은 실행 시 --vault-password-file이나 --ask-vault-pass를 빼면 복호화 실패로 멈춥니다. 자격 증명 파일은 mode 0600으로 두어 다른 사용자가 읽지 못하게 하는 점이 채점 항목입니다.
작업 9 (20점): role과 collection, system roles #
role apache를 roles/apache 아래에 직접 작성하세요. 이 role은 httpd 설치, 서비스 기동, 그리고 변수 apache_port(기본 80)를 받아 /etc/httpd/conf.d/listen.conf에 Listen {{ apache_port }}를 템플릿으로 배포합니다. 포트가 바뀌면 httpd를 재시작하는 handler를 role 안에 두십시오. 플레이북 use_role.yml에서 webservers에 apache_port: 8080으로 이 role을 적용합니다.
정답
role 뼈대를 만듭니다.
ansible-galaxy init roles/apacheroles/apache/defaults/main.yml를 작성합니다.
apache_port: 80roles/apache/tasks/main.yml를 작성합니다.
---
- name: Install httpd
ansible.builtin.dnf:
name: httpd
state: present
- name: Configure listen port
ansible.builtin.template:
src: listen.conf.j2
dest: /etc/httpd/conf.d/listen.conf
notify: Restart httpd
- name: Ensure httpd is running
ansible.builtin.service:
name: httpd
state: started
enabled: trueroles/apache/templates/listen.conf.j2를 작성합니다.
Listen {{ apache_port }}roles/apache/handlers/main.yml를 작성합니다.
---
- name: Restart httpd
ansible.builtin.service:
name: httpd
state: restarteduse_role.yml을 작성합니다.
---
- name: Apply apache role
hosts: webservers
roles:
- role: apache
apache_port: 8080ansible-navigator run -m stdout use_role.yml
ansible-navigator run -m stdout use_role.yml # changed=0해설: ansible-galaxy init로 만든 role은 tasks,handlers,templates,defaults 디렉터리를 표준 구조로 갖습니다. defaults/main.yml의 변수는 우선순위가 가장 낮아 플레이북에서 넘긴 apache_port: 8080이 이깁니다. role 안의 template 모듈은 roles/apache/templates를 기본 경로로 삼으므로 src에 경로를 적지 않아도 됩니다.
작업 10 (20점): role과 collection, system roles #
collection을 requirements 파일로 설치하세요. collections/requirements.yml에 community.general과 ansible.posix를 명시하고, 이를 작업 디렉터리 아래 collections 경로에 설치합니다. 설치 후 ansible.posix.firewalld 모듈이 사용 가능한지 확인합니다.
정답
collections/requirements.yml을 작성합니다.
---
collections:
- name: community.general
- name: ansible.posix작업 디렉터리 아래 collections에 설치합니다.
ansible-galaxy collection install -r collections/requirements.yml -p ./collections설치된 collection과 모듈을 확인합니다.
ansible-galaxy collection list
ansible-doc ansible.posix.firewalld해설: ansible-galaxy collection install -r은 requirements 파일에 나열된 collection을 한 번에 설치하며, -p로 설치 경로를 지정합니다. ansible.cfg의 collections_path나 작업 디렉터리 아래 collections에 두면 플레이북이 자동으로 인식합니다. 시험에서는 자동화 콘텐츠가 로컬 미러로 제공될 수 있으므로 server 옵션이나 오프라인 경로를 확인하는 점이 함정입니다.
작업 11 (20점): role과 collection, system roles #
rhel-system-roles의 timesync role을 사용해 모든 prod 호스트의 NTP를 구성하세요. NTP 서버는 time.example.com 한 곳을 사용합니다. 플레이북 timesync.yml에서 redhat.rhel_system_roles.timesync role을 호출하고, 변수 timesync_ntp_servers로 서버를 지정합니다.
정답
system roles 패키지가 깔려 있는지 확인합니다.
sudo dnf install -y rhel-system-roles
ansible-galaxy collection list | grep rhel_system_rolestimesync.yml을 작성합니다.
---
- name: Configure NTP with timesync system role
hosts: prod
vars:
timesync_ntp_servers:
- hostname: time.example.com
iburst: true
roles:
- redhat.rhel_system_roles.timesyncansible-navigator run -m stdout timesync.yml
ansible-navigator run -m stdout timesync.yml # changed=0해설: 시스템 롤은 rhel-system-roles 패키지로 제어 노드에 설치되며 redhat.rhel_system_roles collection으로 노출됩니다. timesync_ntp_servers는 단순 문자열이 아니라 hostname,iburst 키를 가진 딕셔너리 리스트라는 점이 함정입니다. 시스템 롤은 내부에서 chrony 설정을 멱등하게 관리하므로, 두 번째 실행에서 changed가 0으로 떨어집니다.
작업 12 (24점): RHCSA 작업 자동화 #
플레이북 accounts.yml을 작성해, 변수 파일에 정의된 사용자 목록을 모든 prod 호스트에 생성하세요. 각 사용자는 이름,UID,암호(이미 해시된 값)를 가지며, loop로 처리합니다. 암호 해시는 작업 8과 같은 방식의 Vault 변수에서 가져온다고 가정하고, 여기서는 변수 srv_users 리스트를 직접 정의해 사용하세요.
정답
accounts.yml을 작성합니다.
---
- name: Provision accounts
hosts: prod
vars:
srv_users:
- name: deploy
uid: 2001
password: "$6$rounds=656000$abcXYZ$hashedvalue1"
- name: backup
uid: 2002
password: "$6$rounds=656000$abcXYZ$hashedvalue2"
tasks:
- name: Create service accounts
ansible.builtin.user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
password: "{{ item.password }}"
state: present
loop: "{{ srv_users }}"
loop_control:
label: "{{ item.name }}"ansible-navigator run -m stdout accounts.yml
ansible-navigator run -m stdout accounts.yml # changed=0해설: user 모듈의 password는 평문이 아니라 SHA-512 해시여야 하며, ansible-vault로 감싼 변수나 password_hash 필터로 생성합니다. 평문을 넣으면 그 문자열 자체가 해시로 저장되어 로그인이 안 됩니다. loop_control.label은 출력에서 해시 같은 긴 값 대신 사용자명만 보여 가독성을 높입니다.
작업 13 (24점): RHCSA 작업 자동화 #
플레이북 storage.yml을 작성해, dbservers 호스트의 빈 디스크 /dev/vdb에 볼륨 그룹 vg_data를 만들고, 그 안에 2G 논리 볼륨 lv_data를 생성한 뒤 xfs로 포맷하고 /data에 영구 마운트하세요. 작업은 멱등해야 합니다.
정답
storage.yml을 작성합니다.
---
- name: Configure LVM storage
hosts: dbservers
tasks:
- name: Create volume group
community.general.lvg:
vg: vg_data
pvs: /dev/vdb
- name: Create logical volume
community.general.lvol:
vg: vg_data
lv: lv_data
size: 2G
- name: Create xfs filesystem
community.general.filesystem:
fstype: xfs
dev: /dev/vg_data/lv_data
- name: Mount the filesystem
ansible.posix.mount:
path: /data
src: /dev/vg_data/lv_data
fstype: xfs
state: mountedansible-navigator run -m stdout storage.yml
ansible-navigator run -m stdout storage.yml # changed=0해설: LVM 자동화는 community.general의 lvg,lvol,filesystem과 ansible.posix.mount를 순서대로 엮습니다. mount 모듈의 state: mounted는 지금 마운트하면서 /etc/fstab에도 등록해 영구 마운트를 만듭니다(mounted와 present의 차이가 함정입니다). 작업 10에서 두 collection을 미리 설치해 둔 점이 여기서 쓰입니다.
작업 14 (24점): RHCSA 작업 자동화 #
플레이북 firewall_selinux.yml을 작성해, webservers 호스트에서 httpd가 비표준 포트 8080을 쓰도록 허용하세요. firewalld에 8080/tcp를 영구 허용하고 즉시 반영하며, SELinux에서 http_port_t에 8080 포트를 추가합니다. ansible.posix.firewalld와 community.general.seport를 사용합니다.
정답
firewall_selinux.yml을 작성합니다.
---
- name: Open port 8080 for httpd
hosts: webservers
tasks:
- name: Allow 8080/tcp in firewalld
ansible.posix.firewalld:
port: 8080/tcp
permanent: true
immediate: true
state: enabled
- name: Add SELinux port label for http
community.general.seport:
ports: 8080
proto: tcp
setype: http_port_t
state: presentansible-navigator run -m stdout firewall_selinux.yml
ansible-navigator run -m stdout firewall_selinux.yml # changed=0해설: firewalld 변경은 permanent: true만 두면 다음 reload까지 적용되지 않으므로 immediate: true를 함께 두어야 지금 바로 열립니다. SELinux는 비표준 포트로 서비스를 띄울 때 http_port_t 같은 포트 타입을 추가하지 않으면 서비스가 바인딩에 실패하므로, seport로 포트 라벨을 미리 등록합니다. 두 모듈 모두 멱등해서 두 번째 실행은 ok로 떨어집니다.
작업 15 (20점): RHCSA 작업 자동화 #
플레이북 cron.yml을 작성해, 모든 prod 호스트의 root crontab에 매일 02:30에 /usr/local/bin/backup.sh를 실행하는 cron job(이름 daily-backup)을 등록하세요. job은 멱등하게 관리되어야 합니다.
정답
cron.yml을 작성합니다.
---
- name: Schedule daily backup
hosts: prod
tasks:
- name: Add daily backup cron job
ansible.builtin.cron:
name: daily-backup
minute: "30"
hour: "2"
job: /usr/local/bin/backup.sh
user: root
state: presentansible-navigator run -m stdout cron.yml
ansible-navigator run -m stdout cron.yml # changed=0해설: cron 모듈의 name은 crontab에 주석으로 기록되어 job을 식별하는 키가 되므로, 같은 name으로 다시 돌리면 중복 없이 갱신만 됩니다. name을 빼면 매 실행마다 같은 줄이 쌓여 멱등성이 깨지는 것이 가장 흔한 함정입니다. minute,hour는 문자열로 두는 편이 안전합니다.
채점 기준 #
각 작업의 배점을 합산해 채점합니다. 합계는 300점이며 210점 이상이 합격권입니다.
| 영역 | 작업,배점 | 소계 |
|---|---|---|
| 환경과 inventory, 연결 | 1(16) , 2(16) | 32 |
| 플레이북과 변수, 템플릿 | 3(20) , 4(16) , 5(20) | 56 |
| 제어 흐름과 오류 처리, Vault | 6(20) , 7(20) , 8(20) | 60 |
| role과 collection, system roles | 9(20) , 10(20) , 11(20) | 60 |
| RHCSA 작업 자동화 | 12(24) , 13(24) , 14(24) , 15(20) | 92 |
| 합계 | (합계) | 300 |
채점은 실제 시험과 같이 결과물 기준입니다. 플레이북을 어떻게 작성했는지가 아니라, 관리 노드에 실제로 만들어진 상태가 요구사항과 일치하는지를 봅니다. 특히 채점 스크립트는 플레이북을 다시 한 번 실행해 멱등성을 확인하므로, 두 번째 실행에서 changed가 남는 작업은 감점됩니다. 한 작업 안에서도 패키지,서비스,파일,포트 같은 항목별로 부분 점수가 나뉘므로, 막히는 항목이 있어도 채울 수 있는 부분은 끝까지 채우는 편이 점수에 유리합니다.
영역별 약점 복습 #
채점 후 점수가 낮은 영역을 아래 표의 해당 글로 돌아가 복습하세요.
| 영역 | 관련 작업 | 복습할 글 |
|---|---|---|
| 환경과 inventory, 연결 | 1, 2 | #2 , #3 , #4 |
| 플레이북과 변수, 템플릿 | 3, 4, 5 | #5 , #6 , #7 |
| 제어 흐름과 오류 처리, Vault | 6, 7, 8 | #8 , #9 , #10 |
| role과 collection, system roles | 9, 10, 11 | #11 , #12 , #13 |
| RHCSA 작업 자동화 | 12, 13, 14, 15 | #14 , #15 , #16 , #17 |
특정 작업에서 시간이 부족했다면 영역 지식보다 손 빠르기 문제일 수 있습니다. 이 경우 #1 셋업과 #18 시간 관리를 다시 읽고, 같은 15개 작업을 시간을 재며 한 번 더 푸십시오. LVM 자동화와 system roles는 한 번 손에 익으면 작업당 소요 시간이 눈에 띄게 줄어듭니다.
시리즈를 마치며 #
#1의 시험 소개에서 출발해 inventory,연결,ad-hoc,플레이북,변수,fact,템플릿,오류 처리,조건부,Vault,role,collection,system roles, 그리고 RHCSA 자동화 4종까지 RHCE 전 영역을 19편으로 통과했습니다. 이 모의고사에서 210점을 넘겼다면 실제 시험장에서도 충분히 합격선을 넘길 수 있는 손이 만들어졌습니다. 축하합니다.
RHCSA 시리즈에서 한 대의 시스템을 손으로 다루는 법을 익히고, 이 RHCE 시리즈에서 여러 대를 Ansible로 자동화하는 역량까지 더하면서 RHEL 자격증 트랙을 완주하셨습니다. RHCSA의 손작업과 RHCE의 멱등한 자동화가 한 몸으로 이어진 지금, 시스템 한 대를 다루는 관리자를 넘어 여러 대를 코드로 다루는 자동화 엔지니어로 발돋움한 것을 축하합니다.