Red Hat Certification

EX294 — RHCE Engineer Study Guide

60 practice questions with correct answers and detailed explanations. Use this guide to review concepts before taking the practice exam.

▶ Take Practice Exam 60 questions  ·  Free  ·  No registration

About the EX294 Exam

The Red Hat RHCE Engineer (EX294) certification validates professional expertise in Red Hat technologies. This study guide covers all 60 practice questions from our EX294 practice test, complete with correct answers and explanations to help you understand each concept thoroughly.

Review each question and explanation below, then test yourself with the full interactive practice exam to measure your readiness.

60 Practice Questions & Answers

Q1 Easy

You need to configure a system to automatically mount an NFS share at boot time. Which file must you edit to ensure the mount persists across reboots?

  • A /etc/auto.mount
  • B /etc/mount.conf
  • C /etc/mtab
  • D /etc/fstab ✓ Correct
Explanation

/etc/fstab is the static filesystem table used by the system to automatically mount filesystems at boot time. /etc/mtab is dynamic and only reflects currently mounted filesystems.

Q2 Medium

When using Ansible to manage multiple hosts, you want to execute a task only on hosts matching a specific pattern. Which inventory construct allows you to group hosts by characteristics?

  • A Host variables only
  • B Host aliases in /etc/hosts
  • C Groups defined in the inventory file ✓ Correct
  • D Dynamic inventory scripts
Explanation

Groups in the inventory file allow you to organize hosts by characteristics and target them with patterns like [webservers] or [databases]. This enables selective execution of tasks across matched groups.

Q3 Medium

You are configuring SELinux and need to temporarily disable it without restarting the system. Which command accomplishes this task?

  • A selinux --disable
  • B sestatus -d
  • C setenforce 0 ✓ Correct
  • D semanage enforcing
Explanation

The setenforce command temporarily sets SELinux mode to permissive (0) or enforcing (1) without requiring a reboot. Permanent changes require editing /etc/selinux/config.

Q4 Medium

In an Ansible playbook, you need to include sensitive data like passwords without storing them in plain text. What is the recommended approach?

  • A Use ansible-vault to encrypt sensitive files and specify the vault password at runtime ✓ Correct
  • B Store passwords in environment variables and reference them with {{ ansible_env.PASS }}
  • C Use a separate unencrypted configuration file with restricted file permissions only
  • D Encode passwords with base64 in the playbook variables
Explanation

ansible-vault is the standard tool for encrypting sensitive data in playbooks and variable files. It allows encrypted content to be checked into version control safely while still being accessible during playbook execution.

Q5 Medium

You configure a service to start automatically with systemd. After making changes to the service unit file, what must you do to ensure systemd recognizes the changes?

  • A Execute systemctl refresh-units
  • B Restart the entire system
  • C Reload the service with systemctl reload myservice
  • D Run systemctl daemon-reload before restarting the service ✓ Correct
Explanation

systemctl daemon-reload instructs systemd to reload its unit configuration files from disk. This must be done after modifying unit files but before restarting the service for changes to take effect.

Q6 Easy

When using Ansible roles, where should you place files that are copied to remote hosts unchanged during role execution?

  • A roles/myrole/files/ ✓ Correct
  • B roles/myrole/handlers/
  • C roles/myrole/templates/
  • D roles/myrole/vars/
Explanation

The files/ directory in a role contains static files that are copied to remote hosts using the copy module without any variable substitution or templating.

Q7 Medium

You need to configure firewall rules to allow traffic on port 443 while maintaining persistence across reboots. Which approach is correct for firewalld?

  • A firewall-cmd --permanent --add-port=443/tcp && firewall-cmd --reload ✓ Correct
  • B firewall-cmd --add-port=443/tcp --permanent
  • C firewall-cmd --zone=public --add-port=443/tcp and edit /etc/firewalld/firewall.conf
  • D firewall-cmd --add-port=443/tcp && firewall-cmd --runtime-to-permanent
Explanation

Using --permanent flag modifies the persistent configuration, but changes don't take effect immediately. You must use --reload to reload the firewall rules from disk for the new rules to become active.

Q8 Hard

In Ansible, you create a playbook that uses a variable defined in a role's defaults/main.yml. At what point in the variable precedence hierarchy does this value get evaluated?

  • A Only evaluated if the variable is not defined elsewhere
  • B Lowest precedence, overridden by nearly all other variable sources ✓ Correct
  • C Medium precedence, after inventory variables but before task variables
  • D Highest precedence, overriding all other sources
Explanation

Role defaults have the lowest precedence in Ansible's variable hierarchy and can be overridden by inventory variables, group variables, host variables, and task variables.

Q9 Medium

You need to ensure that a critical service restarts automatically if it crashes unexpectedly. Which systemd directive in the service unit file accomplishes this?

  • A AutoRestart=true
  • B Restart=always ✓ Correct
  • C FailureAction=restart
  • D RestartPolicy=onFailure
Explanation

The Restart= directive controls systemd's automatic restart behavior. Setting it to 'always' ensures the service restarts regardless of exit code, while other values like 'on-failure' provide more conditional restart behavior.

Q10 Medium

When configuring a user account via Ansible, you want to set the default shell to /bin/bash and ensure the home directory is created. Which module parameters achieve both goals?

  • A shell=/bin/bash and home=/home/username
  • B login_shell=/bin/bash and ensure_home=present
  • C shell=/bin/bash and createhome=yes ✓ Correct
  • D default_shell=/bin/bash and create_home_dir=true
Explanation

The user module in Ansible accepts the 'shell' parameter to set the login shell and the 'createhome' parameter to create the home directory if it doesn't exist.

Q11 Hard

You configure SSH key-based authentication and place a public key in ~/.ssh/authorized_keys. After setting permissions to 600, SSH still denies key-based login. What is the most likely issue?

  • A The ~/.ssh directory permissions are incorrect ✓ Correct
  • B The public key file must have permissions 644 instead
  • C The SSH service must be restarted to recognize the new key
  • D The private key on the client has permissions 600 instead of 400
Explanation

SSH requires the ~/.ssh directory to have permissions 700 (rwx------) and authorized_keys to have 600 (rw-------). If ~/.ssh has incorrect permissions, SSH will reject key-based authentication as a security measure.

Q12 Easy

In a playbook, you use the debug module to display variable values during execution. What is the primary use case for this module in production environments?

  • A To print all variables before each task executes
  • B To troubleshoot issues and verify that variables contain expected values at specific points ✓ Correct
  • C To permanently log all variable changes to a file
  • D To encrypt sensitive variable values before displaying them on screen
Explanation

The debug module is used to display messages and variable values during playbook execution, primarily for troubleshooting and verification purposes. It helps confirm that variables have expected values at specific execution points.

Q13 Medium

You need to deploy the same configuration to 50 servers but with slight variations per server. Which Ansible feature best supports this requirement while maintaining code reusability?

  • A Executing a shell script via Ansible to generate configurations dynamically
  • B Using inventory variables and the template module to generate configuration files with variable substitution ✓ Correct
  • C Creating 50 separate playbooks with hardcoded values
  • D Manually copying configuration files to each server after running a generic playbook
Explanation

Combining inventory variables (per-host or per-group) with the template module allows you to maintain a single configuration template that generates different outputs for each server based on its variables.

Q14 Hard

When configuring log rotation with logrotate, which configuration option ensures that compressed log files are retained for a specific number of days?

  • A rotate 7 with compress
  • B compress-days 30
  • C maxage 30 ✓ Correct
  • D maxcompressdays 30
Explanation

The 'maxage' option in logrotate specifies the maximum number of days to keep rotated log files. The 'rotate' option specifies how many rotated logs to keep, and 'compress' enables compression of rotated logs.

Q15 Medium

You create an Ansible task that registers the output of a command in a variable. Later, you need to extract a specific field from this output. Which approach is most appropriate?

  • A Use the set_fact module to manually parse the output string character by character
  • B Store the output in a file and use the slurp module to read it back
  • C Use a filter like | json_query or | regex_search to parse the registered variable ✓ Correct
  • D Re-run the command with grep to extract the specific field
Explanation

Ansible filters like json_query for JSON output or regex_search for pattern matching allow you to elegantly extract specific fields from registered command output without re-executing the command.

Q16 Hard

In SELinux, what does the context label 'unconfined_u:unconfined_r:unconfined_t:s0' indicate about a process?

  • A The process is running in a restricted sandbox with minimal permissions
  • B The process has been temporarily disabled and requires reactivation
  • C The process is running unconfined with minimal SELinux restrictions applied ✓ Correct
  • D The process is in a transition state and waiting for policy enforcement
Explanation

The unconfined domain (unconfined_t) indicates a process that operates with minimal SELinux restrictions. Most user processes and system services run with more specific confined domains for security.

Q17 Hard

You configure a network bond using NetworkManager for redundancy. After creating the bond0 interface, what is the next step to ensure both underlying interfaces are enslaved to the bond?

  • A Use nmcli to add the physical interfaces to the bond connection and activate it ✓ Correct
  • B Use ifenslave command to bind physical interfaces to the bond manually
  • C Edit /etc/sysconfig/network-scripts/ifcfg-eth0 and add MASTER=bond0
  • D Reboot the system to activate the bond configuration
Explanation

With NetworkManager, you use nmcli to add physical interfaces as slaves to the bond connection. For example: 'nmcli connection add type ethernet ifname eth0 master bond0 slave-type bond' and similar for each interface.

Q18 Easy

An Ansible playbook uses the copy module to deploy a configuration file. You need the file to be processed by Jinja2 for variable substitution before copying. Which module should you use instead?

  • A copy module with process=jinja2 option
  • B template module with src and dest parameters ✓ Correct
  • C shell module with j2 renderer enabled
  • D script module to run a Jinja2 processor
Explanation

The template module is specifically designed to process files through Jinja2 and substitute variables, providing the same copy functionality as the copy module but with variable interpolation support.

Q19 Medium

You need to restrict a user's cron job execution. Which approach is most secure and maintainable in a Red Hat environment?

  • A Add the username to /etc/cron.deny file
  • B Delete the user's crontab entries directly
  • C Set file permissions on crontab to 000 for that user
  • D Use /etc/cron.allow to explicitly permit only authorized users to create cron jobs ✓ Correct
Explanation

Using /etc/cron.allow with an explicit whitelist is more secure and maintainable than /etc/cron.deny. When /etc/cron.allow exists, only users listed in it can schedule cron jobs, providing better access control.

Q20 Hard

When configuring a service with systemd, you need it to wait for network availability before starting. Which directive accomplishes this?

  • A After=network.target
  • B DependsOn=network.service
  • C After=network-online.target Wants=network-online.target ✓ Correct
  • D Requires=network-online.target
Explanation

To ensure a service waits for network availability, use both 'After=network-online.target' (ordering dependency) and 'Wants=network-online.target' (soft dependency) to ensure the target is reached before the service starts.

Q21 Easy

In Ansible, you want to execute a task only if a variable has a specific value. Which conditional syntax is correct?

  • A when: variable == 'value' ✓ Correct
  • B if: variable equals 'value'
  • C condition: variable is 'value'
  • D only_when: variable matches 'value'
Explanation

Ansible uses the 'when' keyword with standard Jinja2 conditional expressions. The syntax 'when: variable == "value"' is the correct way to conditionally execute a task based on variable value.

Q22 Medium

You need to monitor log files for specific error patterns and send alerts. Which tool is most appropriate for this task in a Red Hat environment?

  • A Configuring rsyslog rules with a script action to alert on pattern matches ✓ Correct
  • B Using grep with a cron job to search logs periodically
  • C Using tail -f in a loop and manually checking for errors
  • D Implementing a centralized log aggregation solution with log parsing rules
Explanation

rsyslog allows you to define rules that match log patterns and execute scripts to send alerts. This is more efficient than periodic grep execution and provides real-time pattern matching for error detection.

Q23 Easy

An Ansible playbook deploys packages using the yum module. You want to ensure that a package is installed but don't require a specific version. Which state value is appropriate?

  • A state=installed
  • B state=available
  • C state=latest
  • D state=present ✓ Correct
Explanation

state=present installs the package if it's not present but doesn't upgrade it if a newer version is available. state=latest would upgrade to the newest version, while 'installed' and 'available' are not valid yum module states.

Q24 Hard

You configure a firewall rule that must apply to a specific network interface. Which firewalld zone configuration approach is most appropriate?

  • A Edit /etc/firewalld/zones/public.xml to hardcode the interface name
  • B Create a custom zone and assign the interface to it using firewall-cmd --zone=custom --add-interface=eth0 --permanent ✓ Correct
  • C Apply rules directly to the interface using iptables -i eth0 for persistence
  • D Use firewall-cmd --add-interface=eth0 to the default zone without specifying a zone
Explanation

Firewalld zones allow you to group interfaces and apply rules per zone. Creating a custom zone and assigning an interface to it via firewall-cmd with --permanent ensures the configuration persists across reboots and is properly managed by firewalld.

Q25 Hard

In a disaster recovery scenario, you need to verify that file permissions were preserved in a backup. Which tar option enables extended attributes and SELinux contexts to be backed up?

  • A --extended-attributes option for all metadata
  • B --acls option for access control lists
  • C --selinux and --xattr options together ✓ Correct
  • D --preserve-permissions only
Explanation

The --selinux flag preserves SELinux contexts while --xattr (or --xattrs) preserves extended attributes. Using both together ensures complete metadata preservation during backup and restoration.

Q26 Medium

You configure an Ansible handler that should run after multiple tasks. When does this handler execute?

  • A Only if explicitly called with include_tasks
  • B Immediately after the first task that notifies it
  • C In a separate handler block between task sections
  • D At the very end of the playbook, after all tasks have completed ✓ Correct
Explanation

Handlers execute at the end of the current play block, after all tasks have run. This allows multiple tasks to notify the same handler, which then executes only once at the end, improving efficiency.

Q27 Medium

You need to configure a managed node to use a specific DNS server. Which Ansible module is best suited for this task?

  • A lineinfile to edit /etc/resolv.conf
  • B networkmanager_dns to set DNS servers
  • C template to deploy a custom resolv.conf file
  • D nmcli with state present ✓ Correct
Explanation

The nmcli module is the recommended way to manage NetworkManager connections, including DNS configuration on modern RHEL systems. Using lineinfile on /etc/resolv.conf is not idempotent as the file is managed by NetworkManager.

Q28 Easy

Which of the following best describes the purpose of ansible-inventory command?

  • A To validate the syntax of playbooks before execution
  • B To encrypt sensitive data in inventory files automatically
  • C To display and test inventory sources without running tasks ✓ Correct
  • D To generate dynamic inventory scripts from templates
Explanation

The ansible-inventory command lists hosts and groups from inventory sources, useful for debugging inventory configuration. It does not validate playbook syntax, encrypt data, or generate scripts.

Q29 Medium

You are writing a role that manages firewall rules. The role should support both firewalld and iptables backends. What is the best approach to implement this?

  • A Always prefer firewalld and fail if it is not installed on the target system
  • B Use conditional logic with when statements based on detected service availability
  • C Create separate playbooks for each firewall backend and document the choice
  • D Create a variable that allows users to specify the firewall backend and use it in conditionals ✓ Correct
Explanation

Using a variable makes the role flexible and reusable across different environments. This follows the principle of making roles parameterizable while conditional logic based on detection can handle edge cases.

Q30 Easy

When using Ansible vault to encrypt a variable file, what command encrypts an existing unencrypted YAML file?

  • A ansible-vault create secrets.yml
  • B ansible-vault lock secrets.yml
  • C ansible-vault secure secrets.yml
  • D ansible-vault encrypt secrets.yml ✓ Correct
Explanation

The encrypt subcommand encrypts an existing plaintext file. The create command is used to create a new encrypted file from scratch, while lock and secure are not valid vault subcommands.

Q31 Medium

You need to ensure that a handler runs only once during a play, even if multiple tasks trigger it. Which handler attribute accomplishes this?

  • A idempotent: true
  • B listen: unique
  • C run_once: true ✓ Correct
  • D once: per_play
Explanation

The run_once directive on a handler ensures it executes only once per play, regardless of how many tasks notify it. The listen attribute is for handler naming, not for controlling execution frequency.

Q32 Hard

Which Ansible module is used to manage SELinux file contexts and ensure they persist across reboots?

  • A semanage to configure SELinux policies directly
  • B selinux_fcontext to apply contexts to specific files
  • C selinux to set the global SELinux mode
  • D sefcontext to manage file context mappings ✓ Correct
Explanation

The sefcontext module manages SELinux file context mappings in the policy, making changes persistent. The selinux module controls global mode, and direct semanage calls are not idempotent in Ansible.

Q33 Medium

When configuring a role to deploy a web application, you want to ensure sensitive credentials are never logged. What mechanism prevents logging of specific variables?

  • A Use the silent: true option in the play definition
  • B Set no_log: true on tasks using sensitive variables ✓ Correct
  • C Register variables with the hidden_from_logs attribute
  • D Define variables with the prefix secret_ to auto-hide them
Explanation

The no_log: true parameter on a task prevents that task's output from appearing in logs. Variable naming conventions and special attributes do not automatically hide logs; no_log is the proper mechanism.

Q34 Easy

You are troubleshooting a playbook that uses multiple loops. Which variable provides the current iteration index in a loop?

  • A loop.index ✓ Correct
  • B item.index
  • C loop.counter
  • D ansible_loop_index
Explanation

The loop.index variable contains the current iteration number (1-based indexing) when using the loop keyword. Other options are not valid Ansible loop variables.

Q35 Medium

A playbook needs to gather facts about target systems but only for hosts that will actually run tasks. Which play-level setting optimizes this behavior?

  • A gather_facts: conditional
  • B gather_facts: lazy
  • C gather_facts: smart ✓ Correct
  • D gather_facts: minimal
Explanation

The smart setting gathers facts only on hosts that are included in the play after any host filtering. This optimizes performance when using limits or conditionals that exclude some hosts.

Q36 Hard

You must create a role that manages packages, but the package names differ between RHEL 8 and RHEL 9. What is the recommended approach?

  • A Create a variables file for each version in the role's vars directory and include the appropriate one ✓ Correct
  • B Define package lists in group_vars based on RHEL version groups in inventory
  • C Use separate tasks with when conditions checking ansible_distribution_version
  • D Use the package module with a variable that is set based on os_family
Explanation

Using version-specific variable files in the role's vars directory keeps role logic clean and reusable. While conditionals work, separating variable definitions is more maintainable.

Q37 Easy

When using the copy module to deploy configuration files, which parameter ensures the deployed file has specific ownership and permissions?

  • A Copy the file with correct context, then use handlers to set permissions
  • B owner, group, and mode parameters in a single task ✓ Correct
  • C force: yes with owner and group parameters
  • D Use copy with backup: yes and then apply file permissions separately
Explanation

The copy module accepts owner, group, and mode parameters directly, allowing idempotent file deployment with correct ownership and permissions in one task.

Q38 Hard

You are implementing a role that should fail fast if certain critical variables are not defined. Which validation approach is best?

  • A Rely on Jinja2 undefined variable errors during template rendering
  • B Use assert module at the beginning of the role to validate required variables ✓ Correct
  • C Use the mandatory: true option in role defaults
  • D Add fail tasks with a message checking each variable with when conditions
Explanation

The assert module provides a clean, reusable way to validate multiple conditions and fail with informative messages. The mandatory option does not exist; relying on rendering errors produces poor error messages.

Q39 Hard

Which strategy in an Ansible playbook allows tasks to run in parallel across different hosts while respecting serial batches?

  • A strategy: free with serial: N ✓ Correct
  • B strategy: parallel with max_forks
  • C strategy: linear with async and poll
  • D strategy: batch with throttle
Explanation

The free strategy runs tasks in parallel per host without waiting for all hosts to complete each task, and serial batches hosts in groups. Linear strategy waits for all hosts per task; async is for background jobs.

Q40 Medium

You need to ensure that a configuration file is deployed with content from a template, but only if the file does not exist. Which approach is most idempotent?

  • A Use template module with a stat task to check existence first, then template with when
  • B Use template module with force: no parameter
  • C Use copy module with a Jinja2 template as src
  • D Use the template module without any condition; it is idempotent by default ✓ Correct
Explanation

The template module is idempotent by default and will only modify files if content changes. If you want to skip existing files, use force: false (not 'no'); however, the template module handles all scenarios appropriately without conditions.

Q41 Hard

When writing a complex playbook, you need to stop execution if a critical task fails, but allow other plays to continue. Which play-level option achieves this?

  • A max_fail_percentage: 0 ✓ Correct
  • B ignore_errors: true at the play level
  • C any_errors_fatal: true
  • D continue_on_error: yes
Explanation

Setting max_fail_percentage: 0 stops the play if any host fails, preventing progression to the next task but allowing other plays to run. any_errors_fatal stops all plays; ignore_errors allows continuation within the play.

Q42 Medium

You are designing a role for database configuration. The role needs to work with both PostgreSQL and MySQL. Where should database-specific variables be stored?

  • A In separate vars/postgresql.yml and vars/mysql.yml files, included via role prerequisites
  • B Directly in the role's main tasks file with when conditions
  • C In group_vars for each database type group in the inventory
  • D In defaults/main.yml with a conditional include of vars files ✓ Correct
Explanation

The standard approach is to store default variables in defaults/main.yml and conditionally include database-specific variable files from vars/ based on a role variable. This keeps the role self-contained and reusable.

Q43 Medium

Which of the following correctly uses the block statement to handle multiple related tasks with a single error handler?

  • A block: allows you to retry tasks automatically without specifying retry count
  • B block: requires all tasks inside to complete before moving to the next block
  • C block: can contain only idempotent tasks and will skip non-idempotent ones
  • D block: creates a group of tasks that can share rescue and always sections for unified error handling ✓ Correct
Explanation

Blocks group tasks and allow a single rescue section (error handler) and always section to apply to all tasks in the block. Retry is a separate mechanism; blocks do not enforce completion order or idempotency.

Q44 Medium

You need to configure the sudoers file to allow specific commands without passwords. Which module is safest for this task?

  • A copy with src pointing to a sudoers.d configuration snippet ✓ Correct
  • B lineinfile to append lines to /etc/sudoers
  • C visudo with a custom configuration file in /etc/sudoers.d/
  • D template to deploy a complete sudoers file
Explanation

Files in /etc/sudoers.d/ are validated by sudo itself and are safer than editing /etc/sudoers directly. Using copy to deploy a pre-validated sudoers.d snippet is the recommended approach. visudo is not an Ansible module.

Q45 Easy

When using Ansible to manage systemd units, which module parameter ensures a service is enabled to start at boot and is currently running?

  • A enabled: always with state: active
  • B state: started with enabled: yes in a single systemd task ✓ Correct
  • C state: started and enabled: yes in separate tasks
  • D daemon: started with enabled: persistent
Explanation

The systemd module accepts both state: started (ensures service is running) and enabled: yes (ensures it starts at boot) in a single idempotent task. These can be combined in one module call.

Q46 Hard

You are implementing error handling in a playbook using blocks. A rescue section should handle specific errors, but others should fail the playbook. What is the best approach?

  • A Use block with rescue and rethrow unhandled errors using fail in the rescue
  • B Use multiple rescue blocks with fail tasks that check the error message
  • C Use a single rescue block with fail and when conditions to check ansible_failed_result
  • D Separate blocks by error type so each block can have its own rescue with specific handling ✓ Correct
Explanation

Organizing blocks by error type allows each block's rescue section to handle only expected errors for that block's logic. Other blocks can fail naturally. Multiple rescue blocks in one block is not possible; there is only one rescue per block.

Q47 Medium

Which approach ensures that a role's default variables can be overridden by inventory-level variables without modifying the role?

  • A Use vars_prompt to allow interactive variable entry at playbook runtime
  • B Create a role parameter that pulls variables from a specified group_vars path
  • C Define variables in defaults/main.yml and ensure inventory variables are loaded with higher precedence ✓ Correct
  • D Store all variables in the role's vars/ directory and document override instructions
Explanation

Ansible's variable precedence automatically gives inventory variables (group_vars, host_vars) higher priority than role defaults, allowing role reuse with environment-specific overrides without modification.

Q48 Medium

You need to register the output of a task and use it in a subsequent task only if the first task succeeded. Which construct best handles this?

  • A Use register and check changed_when to trigger the next task
  • B Use async to run the task and poll the result in the next task
  • C Store output in a variable and use failed_when to control continuation
  • D Use register with a when condition checking the result status in the next task ✓ Correct
Explanation

Registering output and then using when conditions to check the result status (e.g., when: previous_task.rc == 0) is the standard conditional approach. changed_when affects reporting, not execution flow.

Q49 Medium

When deploying a role that manages system services, how should you handle the case where a service does not exist on all distributions?

  • A Ignore errors and continue, assuming the service exists on relevant systems
  • B Register the output and use failed_when to identify missing services gracefully
  • C Check ansible_service_mgr and conditionally skip the service task
  • D Use a stat module to check if the service executable exists before managing it ✓ Correct
Explanation

Using the stat module to check for service existence before attempting to manage it is the most reliable approach. This allows conditional logic without assuming service availability across all distributions.

Q50 Easy

You are documenting a role for team use. Which file in a role directory serves as the primary documentation for the role's purpose and usage?

  • A CHANGELOG.md with version history and feature details
  • B README.md in the role root directory ✓ Correct
  • C meta/documentation.yml with YAML-formatted role metadata
  • D docs/index.md with a standard documentation structure
Explanation

The README.md file in the role's root directory is the standard location for role documentation, describing purpose, variables, examples, and usage. The meta/ directory contains role metadata, not user documentation.

Q51 Medium

You need to configure a firewall rule to allow incoming traffic on port 8080 for a web application. Which firewalld command would you use to add this rule permanently?

  • A firewall-cmd --zone=public --permanent --add-port=8080/tcp && firewall-cmd --reload ✓ Correct
  • B firewall-cmd --permanent --add-port=8080/tcp && firewall-cmd --reload
  • C firewall-cmd --add-service=http --permanent
  • D firewall-cmd --add-port=8080/tcp
Explanation

The --permanent flag ensures persistence across reboots, --zone=public specifies the zone, and --reload applies the changes immediately. Using --add-port with both permanent flag and reload is the correct method.

Q52 Medium

When using Ansible handlers, which statement best describes their primary purpose?

  • A Handlers provide error handling and task retry mechanisms for failed operations.
  • B Handlers are triggered by notify directives and execute only if the notifying task changed something. ✓ Correct
  • C Handlers execute before any other tasks to set up the environment.
  • D Handlers allow you to conditionally skip tasks based on variable values.
Explanation

Handlers are special tasks that only run when notified by another task and only if that task reported a change, making them ideal for actions like service restarts.

Q53 Hard

You are troubleshooting an Ansible playbook that references a variable defined in a vars_files directive, but the variable is not being recognized. Which of the following is the most likely cause?

  • A The vars_files directive only works when used at the role level, not at the play level.
  • B Variables from vars_files cannot be used in conditionals or loops.
  • C The vars_files list is evaluated after all tasks execute.
  • D The YAML file path in vars_files is incorrect or the file contains syntax errors that prevent loading. ✓ Correct
Explanation

If vars_files cannot load the specified file due to incorrect path or YAML syntax errors, the variables will be undefined. Verify the file path and validate YAML syntax.

Q54 Easy

A system administrator needs to implement role-based access control (RBAC) for Ansible Tower. Which of the following best describes the purpose of RBAC in this context?

  • A RBAC simplifies playbook syntax by automatically assigning roles to every task.
  • B RBAC automatically encrypts all credentials stored in the Tower database.
  • C RBAC allows fine-grained permission assignment so users can only access and execute playbooks relevant to their role. ✓ Correct
  • D RBAC prevents all users except administrators from viewing any automation data.
Explanation

RBAC in Ansible Tower enables organizations to control which users can view, modify, and execute specific projects, inventories, and job templates based on their organizational roles.

Q55 Hard

You have a task that conditionally registers a variable based on the previous task's result. However, the registered variable needs to be available to tasks in subsequent plays. What is the best approach?

  • A Use set_fact to copy the registered variable into a fact that persists across plays. ✓ Correct
  • B Move the task to a role's main.yml so it is available globally.
  • C Use the register keyword with the scope parameter set to global.
  • D Registered variables are automatically available across all plays in a playbook.
Explanation

Registered variables are only available within the current play. To make them available across plays, convert them to facts using set_fact, which persists for the entire playbook execution.

Q56 Medium

Which SELinux context component is responsible for defining what a process can do?

  • A The level component
  • B The user component
  • C The role component
  • D The type component ✓ Correct
Explanation

In SELinux contexts (user:role:type:level), the type component defines the domain and determines what processes can access. User and role are also important but type is the primary enforcement mechanism.

Q57 Hard

You need to create a custom SELinux policy module for a third-party application. Which command sequence would you use to compile and install the policy?

  • A checkmodule -M -m -o myapp.mod myapp.te && semodule_package -o myapp.pp -m myapp.mod && semodule -i myapp.pp ✓ Correct
  • B audit2allow -a -M myapp && semodule -i myapp.pp
  • C semanage fcontext -a -t myapp_t /opt/myapp && restorecon -Rv /opt/myapp
  • D semanage module -a myapp.te && restorecon -Rv /opt/myapp
Explanation

The correct sequence is: compile the type enforcement file (.te) into a module (.mod), package it into a policy package (.pp), and install it with semodule -i. This is the standard method for custom policy creation.

Q58 Medium

When configuring a system to use Kerberos authentication with Ansible, which of the following best describes the authentication flow?

  • A Ansible collects the user's password and sends it directly to the Kerberos server for verification.
  • B The Kerberos server generates SSH keys that Ansible uses for passwordless authentication.
  • C Ansible bypasses local authentication and relies entirely on network-based PAM modules.
  • D A Kerberos ticket-granting ticket (TGT) is obtained and used to authenticate Ansible connections without transmitting passwords. ✓ Correct
Explanation

Kerberos uses ticket-based authentication where a TGT is obtained once and then used for service authentication, avoiding password transmission and enabling single sign-on capabilities.

Q59 Easy

You are using Ansible to manage multiple environments (dev, staging, production) with different variables for each. What is the recommended approach to organize this?

  • A Create separate playbooks for each environment with hardcoded variables in each playbook.
  • B Store all variables in a single vars.yml file with conditional blocks based on the environment.
  • C Define all environment-specific variables as command-line arguments when running ansible-playbook.
  • D Use separate inventory files for each environment with corresponding group_vars and host_vars directories. ✓ Correct
Explanation

Separate inventory files with group_vars/host_vars directories is the Ansible best practice for managing multiple environments, keeping configurations organized, scalable, and maintainable.

Q60 Medium

A playbook task uses the command module to execute a shell script, but the script requires environment variables to function properly. Which approach is most appropriate?

  • A Create a pre-task that runs 'export VAR=value' to set environment variables for all subsequent tasks.
  • B Add the environment keyword to the task with a dictionary of required environment variables. ✓ Correct
  • C Modify the script itself to read variables from a configuration file instead of using environment variables.
  • D Use the shell module instead of command and export variables in the command string.
Explanation

The environment keyword in Ansible tasks allows you to pass environment variables directly to that task without affecting the global shell environment, which is the cleanest and most reliable approach.

Ready to test your knowledge?

You've reviewed all 60 questions. Take the interactive practice exam to simulate the real test environment.

▶ Start Practice Exam — Free