Red Hat Certified Engineer EX294 (EX294) — Questions 226300

518 questions total · 7pages · All types, answers revealed

Page 3

Page 4 of 7

Page 5
226
MCQhard

A large enterprise manages thousands of servers grouped by data center. They are designing a rolling update that must complete within a maintenance window. Which combination of Ansible strategies best minimizes total update time while maintaining safety?

A.Set serial: 0 to update all hosts simultaneously.
B.Set serial to 10% and max_fail_percentage to 25%.
C.Set forks to 100 and max_fail_percentage to 50.
D.Set serial to 1 to update one host at a time with max_fail_percentage: 0.
AnswerB

Correct. Batch size of 10% updates many hosts in parallel, and 25% failure threshold allows some failures without aborting.

Why this answer

Option B is correct because setting `serial: 10%` updates hosts in batches of 10% of the inventory, which parallelizes the update across many hosts to minimize total time, while `max_fail_percentage: 25%` provides a safety net by aborting the play if more than 25% of the batch fails, preventing a cascade of failures from taking down the entire data center. This combination balances speed and safety for large-scale rolling updates within a maintenance window.

Exam trap

The trap here is that candidates confuse `serial` with `forks` or think that `serial: 0` is a valid way to update all hosts at once, when in fact `serial` must be a positive integer or percentage, and `forks` only controls parallelism within a batch, not the batch size itself.

How to eliminate wrong answers

Option A is wrong because `serial: 0` is not a valid Ansible setting; `serial` accepts an integer or percentage, and setting it to 0 would cause an error or be ignored, and the intent to update all hosts simultaneously would require `serial: 100%` or a very high number, but that eliminates rolling update safety entirely. Option C is wrong because `forks` controls the number of parallel tasks per batch, not the batch size; setting `forks: 100` with a default `serial` of 1 still updates one host at a time, so it does not minimize total update time, and `max_fail_percentage: 50` is too permissive, allowing half the batch to fail before aborting. Option D is wrong because `serial: 1` updates only one host at a time, which is the slowest possible approach and will not complete within a maintenance window for thousands of servers, and `max_fail_percentage: 0` aborts on any single failure, which is overly restrictive and not necessary for safety in a rolling update.

227
MCQeasy

You are an Ansible Tower administrator for a company that uses a dynamic inventory script to pull hosts from AWS. The script has been working for months, but after a recent security update, the job template that uses this inventory fails with the error: 'ERROR! Unable to parse /path/to/inventory/script.py as an inventory source'. The script is executable and the path is correct. What is the most likely cause?

A.The required Python modules (e.g., boto3) are missing in the Tower virtual environment.
B.The inventory source type has been changed to 'Manual' instead of 'Scraped from project'.
C.The script has been deleted from the project directory.
D.The script lacks execute permissions for the Tower service user.
AnswerA

Security update may have changed the environment.

Why this answer

The error 'Unable to parse /path/to/inventory/script.py as an inventory source' typically occurs when the dynamic inventory script fails to execute properly. Since the script is executable and the path is correct, the most likely cause is that the required Python modules (e.g., boto3 for AWS) are missing in the Ansible Tower virtual environment. Tower runs inventory scripts in its own Python virtual environment, and if boto3 is not installed there, the script cannot import it and fails, leading to the parse error.

Exam trap

The trap here is that candidates assume the error is due to file permissions or path issues, but the real cause is a missing Python dependency in the Tower virtual environment, which is a common post-update problem.

How to eliminate wrong answers

Option B is wrong because the inventory source type is not changed to 'Manual' or 'Scraped from project' in this context; the error is about parsing the script, not about the source type setting. Option C is wrong because the script has not been deleted; the error message explicitly states the path to the script, and the path is correct, so the file exists. Option D is wrong because the script already has execute permissions (stated in the question), so lacking permissions for the Tower service user is not the issue.

228
Multi-Selecteasy

Which TWO conditions cause an Ansible rolling update playbook to abort immediately? (Choose exactly two.)

Select 2 answers
A.The failure count in a batch exceeds max_fail_percentage.
B.A task returns 'changed' when 'changed_when: false' is used.
C.A task fails on a host, and 'any_errors_fatal' is set to yes.
D.The playbook runs with the --check flag.
E.A host is unreachable due to network issues.
AnswersA, C

Correct. The playbook aborts when batch failure percentage is exceeded.

Why this answer

Option A is correct because Ansible's rolling update logic uses `max_fail_percentage` to control batch failure tolerance. If the number of failed hosts in a batch exceeds this percentage, the playbook aborts immediately to prevent cascading failures. Option C is correct because setting `any_errors_fatal: yes` causes the entire playbook to abort as soon as any task fails on any host, regardless of batch boundaries.

Exam trap

The trap here is that candidates often confuse 'unreachable' (Option E) with a fatal error, but Ansible treats unreachable hosts as failed hosts that are skipped, not as an immediate abort condition unless explicitly configured with `any_errors_fatal` or `max_fail_percentage`.

229
MCQmedium

An Ansible playbook uses async and poll to run a long-running task. The task reports 'async task did not complete within the requested time'. Which of the following is the most likely cause?

A.the poll interval is set too long
B.the async timeout value is set too short for the task duration
C.the async task requires become: yes
D.the host is unreachable
AnswerB

Correct: the timeout must be greater than the expected task runtime.

Why this answer

Option D is correct because the async timeout value set in the play or task is too short. Options A, B, C are less likely.

230
MCQmedium

A team develops a custom Ansible role 'webserver' that depends on another role 'common'. They want to ensure that when 'webserver' is used, 'common' is automatically installed from the same Galaxy server. Which approach should they use?

A.Add a requirements.yml file in the role's root directory specifying common.
B.Add a dependencies: ['common'] to the role's meta/main.yml file.
C.Use ansible-galaxy install webserver --with-dependencies to install common separately.
D.Include the 'common' role in the playbook before 'webserver'.
AnswerB

Correct: Role dependencies in meta/main.yml are automatically installed.

Why this answer

Option A is correct because role dependencies are declared in the meta/main.yml file using the 'dependencies' key, which causes ansible-galaxy to automatically install dependent roles. Option B relies on a requirements.yml file, which is not automatically processed when using the role. Option C requires manual intervention.

Option D works but does not automate installation of the dependency.

231
Multi-Selectmedium

An Ansible automation engineer is writing a playbook to configure network devices. They need to extract specific data from a JSON structure returned by an API call. Which two filters from the `ansible.utils` collection can be used to manipulate the data?

Select 2 answers
A.to_json
B.ipaddr
C.json_query
D.zip
E.from_json
AnswersB, D

The `ipaddr` filter is part of `ansible.utils` and is used for IP address manipulation.

Why this answer

The `ipaddr` filter from `ansible.utils` is used to manipulate IP addresses, and the `zip` filter from `ansible.utils` is used to combine lists element-wise. The `json_query` filter belongs to `community.general`, not `ansible.utils`. The `to_json` and `from_json` filters are part of `ansible.builtin`, not `ansible.utils`.

232
MCQmedium

An organization wants to share a collection internally across multiple teams while ensuring that each team can only use specific modules from the collection. Which approach best supports this requirement?

A.Use a single collection and annotate modules with metadata to restrict access.
B.Create separate collections for each team and publish them to the private Automation Hub.
C.Store the collection in a Git repository and use branch permissions to hide modules.
D.Publish a single collection with all modules and rely on documentation to indicate which modules are for which team.
AnswerB

Each team gets only the collections they need, enforcing access control.

Why this answer

Option B is correct because it uses separate collections published to a private Automation Hub, which allows each team to access only the specific collection containing the modules they need. This approach leverages Automation Hub's role-based access control (RBAC) to enforce team-specific permissions, ensuring that teams cannot see or use modules from other collections.

Exam trap

The trap here is that candidates may think metadata or documentation can enforce access control, but Ansible's native RBAC is tied to collections and namespaces in Automation Hub, not to individual modules within a collection.

How to eliminate wrong answers

Option A is wrong because annotating modules with metadata does not enforce access restrictions; metadata is for documentation or filtering, not for security or RBAC. Option C is wrong because Git branch permissions control access to the repository source code, not the modules within a collection; once the collection is built and installed, branch permissions have no effect on module visibility. Option D is wrong because relying on documentation does not prevent teams from accessing or using modules intended for other teams; there is no technical enforcement.

233
MCQhard

Refer to the exhibit. The playbook copies all .conf files from the control node to host1. If the playbook runs again on the same host without any changes, which task status is expected?

A.The task will fail because the destination directory already contains files.
B.All items will show 'ok' because files are identical.
C.The task will be skipped because the files already exist.
D.All items will show 'changed'.
AnswerB

The copy module uses checksums; if source and destination are the same, it reports 'ok'.

Why this answer

The copy module uses checksums to detect changes. If the files are identical, the task will report 'ok' (not 'changed'). However, the with_fileglob lookup runs on the control node and will always return the same list.

The copy module will compare each file and report 'ok' if unchanged.

234
MCQhard

As an Ansible Tower administrator, you are tasked with setting up a job template that interacts with multiple cloud providers. The job template uses a custom credential type that includes two fields: 'api_token' (type password) and 'region' (type text). During a test run, the job fails with an error that the 'region' variable is not defined in the playbook. The playbook references {{ region }} and {{ api_token }}. You verified that the credential is assigned to the job template and the values are populated. What is the most likely issue?

A.The playbook uses the variable names without the credential-specific prefix.
B.The credential is assigned to the project instead of the job template.
C.The 'api_token' field is encrypted but the 'region' field is not, causing a parsing error.
D.The 'region' field is defined as 'password' type, so it is hidden.
AnswerA

Custom credential variables are namespaced with the credential name.

Why this answer

Option A is correct because in Ansible Tower/AWX, when a custom credential type is used, the variables defined in the credential's injector configuration are automatically prefixed with the credential name (or a custom namespace) when injected into the job environment. If the injector does not explicitly map the fields to the exact variable names used in the playbook (e.g., `region` and `api_token`), the playbook will fail with an undefined variable error. The most likely issue is that the credential's injector configuration does not set the variables as `{{ region }}` and `{{ api_token }}` without a prefix, or the playbook is expecting the variables without the credential-specific namespace that Tower injects by default.

Exam trap

The trap here is that candidates assume that defining fields in a custom credential type automatically makes them available as playbook variables with the same names, overlooking the critical step of configuring the injector mapping in the credential type definition.

How to eliminate wrong answers

Option B is wrong because credentials are assigned to job templates, not to projects; projects store source code, not runtime credentials. Option C is wrong because the 'password' type only masks input in the UI and does not encrypt the value in a way that would cause a parsing error; both fields are injected as plain text variables. Option D is wrong because the 'region' field is defined as 'text' type in the question, not 'password', and even if it were 'password', the type does not affect variable availability in the playbook.

235
MCQeasy

A DevOps team maintains an Ansible environment using execution environments. They have been using a local execution environment image named 'custom-ee:latest' built with ansible-builder. Recently, they updated the requirements.yml file to include a new collection from Automation Hub. They rebuilt the execution environment using ansible-builder and pushed it to their private registry as 'registry.internal/custom-ee:1.2'. However, when running ansible-navigator on a control node, it still uses the old local image and does not pull the updated one. The ansible-navigator configuration file (ansible-navigator.yml) specifies: execution-environment: image: registry.internal/custom-ee:1.2 enabled: true pull: policy: tag The control node has no prior local image with that tag. What is the most likely reason the new image is not being used?

A.The control node does not have network access to the registry, so it cannot pull the image and falls back to the local 'latest' image.
B.An environment variable such as ANSIBLE_NAVIGATOR_EXECUTION_ENVIRONMENT_IMAGE overrides the configuration file, pointing to the old image.
C.The pull policy 'tag' only pulls if the local image tag differs from the registry tag, and since the local image is 'latest', it compares to '1.2' and pulls, but something else prevents it.
D.The image was rebuilt with a different tag than '1.2', so the registry does not have that tag.
AnswerB

Correct: environment variables take precedence over configuration file settings, causing the old image to be used.

Why this answer

Option C is correct because environment variables override settings in ansible-navigator.yml. The ANSIBLE_NAVIGATOR_EXECUTION_ENVIRONMENT_IMAGE variable likely points to the old image tag. Option A is incorrect because 'tag' policy would pull if the tag differs from local, but no local image exists so it should pull.

Option B is a possible cause but would result in a pull failure, not using the old image. Option D is unlikely as the image was pushed with the correct tag.

236
MCQhard

The debug output shows 'changed' even when the firewall rule already existed. Which filter issue could cause this?

A.The 'changed' key is misspelled as 'change' in the filter.
B.The variable 'fw_result' is undefined because the task failed.
C.The task should use 'immediate: yes' to reload the firewall, otherwise the module always reports changed.
D.The filter 'if' condition is incorrectly evaluating 'fw_result.changed' as a string.
AnswerC

Without immediate, the change is staged but module may still report changed if the rule is not yet active.

Why this answer

C is correct because the `firewalld` module in Ansible, by default, operates in 'offline' mode (immediate: no), meaning it only modifies the permanent configuration without applying changes to the running runtime firewall. Even if a rule already exists in the permanent configuration, the module will report 'changed' because it still attempts to add the rule to the runtime zone unless `immediate: yes` is explicitly set to reload the firewall and synchronize the runtime state. This behavior is specific to how `firewalld` separates permanent and runtime rule sets.

Exam trap

The trap here is that candidates assume Ansible modules are idempotent by default for all states, but `firewalld` requires explicit `immediate: yes` to reconcile runtime and permanent configurations, causing false 'changed' results when only the permanent rule exists.

How to eliminate wrong answers

Option A is wrong because the 'changed' key is a standard return value from Ansible modules, and misspelling it as 'change' would cause a syntax error or undefined variable, not a false positive 'changed' status. Option B is wrong because if the task failed, the variable 'fw_result' would be undefined or contain an error key, but the question states the debug output shows 'changed', implying the task succeeded and the variable is defined. Option D is wrong because the filter 'if' condition evaluating 'fw_result.changed' as a string would cause a type mismatch or logical error, but Ansible's Jinja2 filters automatically coerce boolean values, and the 'changed' key is inherently a boolean, not a string, so this would not produce a false 'changed' result.

237
MCQeasy

Refer to the exhibit. What is the output of the debug task?

A.10.0.0.5
B.[ '192.168.1.10' ]
C.eth0
D.192.168.1.10
AnswerD

Correct IP of eth0.

Why this answer

The `debug` task in Ansible uses the `msg` parameter to display the value of a variable. In the exhibit, the variable `ansible_default_ipv4.address` is referenced, which returns the IPv4 address of the default network interface. Since the host's default interface is eth0 with IP 192.168.1.10, the debug output is that IP address.

Option D correctly shows the output as '192.168.1.10'.

Exam trap

The trap here is that candidates often confuse `ansible_default_ipv4` with `ansible_all_ipv4_addresses` or think the output includes the interface name, leading them to select the interface name (eth0) or a list of all IPs instead of the single default IP.

How to eliminate wrong answers

Option A is wrong because '10.0.0.5' is not the IP address of the default interface (eth0) in this scenario; it might be a secondary IP or unrelated. Option B is wrong because it wraps the IP in a list format with brackets and quotes, but the `msg` parameter outputs a plain string, not a list. Option C is wrong because 'eth0' is the interface name, not the IP address; the `ansible_default_ipv4.address` fact specifically returns the IP address, not the interface name.

238
MCQeasy

You are managing a Kubernetes cluster running a critical stateful application deployed as a StatefulSet with 3 replicas. The application uses persistent volumes with ReadWriteOnce access mode. You need to update the container image from version 1.0 to 1.1. The application's performance degrades if more than one replica is unavailable at any time. The StatefulSet is configured with the default RollingUpdate strategy (partition=0). You have a maintenance window of 30 minutes. The update must be completed within the window with minimal risk. Which of the following approaches should you take?

A.Manually delete each pod and let the StatefulSet recreate them with the new image.
B.Use the default rolling update with partition=0; the StatefulSet will update one pod at a time automatically.
C.Set maxUnavailable to 2 to speed up the rollout, then update the image.
D.Perform a canary update by setting partition to 2, updating one pod, validating, then setting partition to 0.
AnswerB

Correct: The default RollingUpdate strategy for StatefulSet updates one pod at a time, ensuring only one replica is unavailable at any moment, meeting the requirement.

Why this answer

Option B is correct because the default RollingUpdate strategy with partition=0 updates one pod at a time, ensuring that no more than one replica is unavailable at any moment. This matches the application's constraint that performance degrades if more than one replica is unavailable, and the 30-minute window is sufficient for a rolling update of 3 pods.

Exam trap

The trap here is that candidates may think a canary update (Option D) is safer, but they overlook that setting partition to 0 after the canary triggers a full rollout that updates remaining pods concurrently, violating the 'no more than one replica unavailable' constraint.

How to eliminate wrong answers

Option A is wrong because manually deleting pods bypasses the StatefulSet's rolling update logic, potentially causing all pods to be recreated simultaneously, which would violate the requirement that no more than one replica be unavailable at a time. Option C is wrong because setting maxUnavailable to 2 would allow two pods to be unavailable during the update, directly violating the application's constraint. Option D is wrong because setting partition to 2 would initially update only the pod with ordinal 2, but the subsequent step of setting partition to 0 would trigger an update of all remaining pods at once, risking more than one replica being unavailable.

239
MCQmedium

A playbook uses a loop over a list of packages to ensure they are installed. However, the playbook runs slowly because each package is processed individually. Which optimization technique should be used to improve performance?

A.Pass the entire list to the package module's 'name' parameter instead of looping.
B.Use with_items instead of loop; with_items is faster.
C.Set the async parameter on the looped task to run packages in parallel.
D.Use the serial keyword at the play level to increase parallelism.
AnswerA

Many package modules accept a list, reducing task overhead.

Why this answer

Option B is correct because using the 'loop' with the package module installs each package individually; switching to a single call with a list is faster. Option A is wrong because async is for long-running tasks, not parallel package installs. Option C is wrong because serial controls host batching, not per-task parallelism.

Option D is wrong because it's the opposite of performance improvement.

240
Multi-Selectmedium

Which TWO of the following statements about Ansible roles are correct?

Select 2 answers
A.Role names must be prefixed with 'ansible-role-' when published to Ansible Galaxy.
B.Variables in 'defaults/main.yml' have the lowest precedence and can be overridden by inventory variables.
C.Role dependencies are defined in the 'meta/main.yml' file.
D.The 'include_role' module can only be used for static imports.
E.A role's tasks are executed before any 'pre_tasks' defined in the playbook.
AnswersB, C

Correct: defaults have the lowest precedence.

Why this answer

Variables in defaults/main.yml have the lowest precedence and can be overridden by inventory variables. Role dependencies are defined in meta/main.yml. The other options are incorrect: pre_tasks run before roles, include_role is dynamic, and the naming convention is not mandatory.

241
Multi-Selecteasy

An Ansible playbook uses the `fetch` module to retrieve files from managed hosts. Which TWO inventory variables are commonly used to construct unique destination paths for each host?

Select 2 answers
A.dest
B.inventory_hostname
C.hostvars
D.ansible_host
E.group_names
AnswersB, D

The hostname as defined in the inventory file.

Why this answer

The `fetch` module retrieves files from managed hosts and stores them locally. To avoid overwriting files from different hosts, you must use unique destination paths. `inventory_hostname` provides the hostname as defined in the inventory, and `ansible_host` provides the actual IP or FQDN used to connect, both of which are commonly used to create distinct per-host directories or filenames.

Exam trap

The trap here is that candidates confuse `dest` (a module parameter) with an inventory variable, or think `hostvars` can be used directly as a unique identifier without additional filtering.

242
MCQhard

A large-scale Ansible deployment processes a list of thousands of network devices. Using the `subelements` filter to iterate over interfaces is causing very slow playbook execution. Which approach can significantly improve performance?

A.Use a custom filter plugin in Python that uses list comprehensions
B.Use `with_nested` instead
C.Use `set_fact` with loops inside the task
D.Use `with_items` with `json_query` instead
AnswerA

Python-level processing is much faster than Jinja2.

Why this answer

The `subelements` filter in Ansible processes nested data structures by iterating over each parent element and its child elements, which can be extremely slow for large datasets due to the overhead of Jinja2 template evaluation and repeated lookups. A custom filter plugin written in Python using list comprehensions avoids this overhead by executing native Python code directly, which is significantly faster because it operates at the interpreter level without the iterative Jinja2 expansion. This approach reduces the number of tasks and template evaluations, improving performance for thousands of network devices.

Exam trap

The trap here is that candidates often assume `with_nested` or `json_query` are equivalent or faster alternatives, but they fail to recognize that the performance bottleneck is the Jinja2 template engine itself, which a custom Python plugin bypasses entirely.

How to eliminate wrong answers

Option B is wrong because `with_nested` is a deprecated loop style that also performs nested iteration with similar or worse performance than `subelements`, as it relies on Jinja2's `product` filter and does not address the underlying inefficiency. Option C is wrong because using `set_fact` with loops inside a task still involves Jinja2 template evaluation for each iteration, which does not reduce the overhead and can even increase complexity and execution time. Option D is wrong because `with_items` with `json_query` still processes each item individually through Jinja2 and the `json_query` filter (which uses jmespath), and while `json_query` can flatten data, it does not provide the performance gain of a native Python plugin that bypasses the template engine entirely.

243
MCQhard

A DevOps engineer is responsible for coordinating a rolling update of a Red Hat OpenShift Container Platform 4.12 cluster with 10 worker nodes. The cluster hosts a stateful application that uses persistent volumes with ReadWriteOnce access mode. The update involves a minor version upgrade of the cluster from 4.12.0 to 4.12.5. The engineer uses the recommended `oc adm upgrade` command. During the update, after the first worker node is updated, the engineer notices that the node's status shows 'NotReady' and the cluster version operator reports a degraded status. A check of the node logs reveals 'kubelet: Failed to run kubelet: Could not get kubelet config from cluster: could not get config from cluster: context deadline exceeded'. Which action should the engineer take first?

A.Rebuild the node from scratch using the machine config operator.
B.Check the network connectivity between the updated node and the control plane nodes on port 6443.
C.Roll back the entire cluster to version 4.12.0 using the `oc adm upgrade --to=4.12.0` command.
D.Increase the kubelet's `--node-status-update-frequency` parameter on the updated node.
AnswerB

The error suggests a timeout, so network connectivity is the likely cause.

Why this answer

Option B is correct because the error indicates the kubelet cannot communicate with the control plane on port 6443, likely due to a network issue (e.g., firewall, DNS, or routing). Option A is wrong because rolling back the entire cluster is a drastic first step; the issue is likely isolated. Option C is wrong because changing kubelet parameters is not a standard resolution for connectivity problems.

Option D is wrong because rebuilding the node from scratch is unnecessary and time-consuming; the issue is likely resolvable by restoring network connectivity.

244
Multi-Selecteasy

Which TWO filters are commonly used for list manipulation in Ansible? (Select exactly two.)

Select 2 answers
A.`default`
B.`map`
C.`ternary`
D.`select`
E.`regex_replace`
AnswersB, D

Correct; map is used to transform list elements.

Why this answer

Options A and B are correct because `map` applies a function to each element, and `select` filters elements based on a condition. Option C (`regex_replace`) is for string replacement. Option D (`default`) sets default values.

Option E (`ternary`) is a conditional operator.

245
MCQmedium

A DevOps engineer wants to run an Ansible playbook inside a specific execution environment (EE) that includes custom collections. The EE image is stored in a private registry requiring authentication. The engineer has configured a container credential file. Which command will execute the playbook using the EE and the credential file?

A.ansible-navigator run -m stdout --ce docker --container-image registry.example.com/custom-ee --container-auth-file auth.json
B.ansible-navigator run -m stdout --ce docker --container-image registry.example.com/custom-ee --container-auth-file credentials.yml
C.ansible-navigator run --pp never --ce docker --container-image registry.example.com/custom-ee
D.ansible-navigator run -m stdout --pp never --ce docker --container-image registry.example.com/custom-ee --container-credential-file credentials.yml
AnswerA

Correct: --container-auth-file specifies the authentication file for registry access.

Why this answer

Option B is correct because ansible-navigator uses the --container-auth-file option to provide authentication details for the container registry. Option A uses an invalid option --container-credential-file. Option C uses the wrong file format (credentials.yml is not typically used for auth).

Option D lacks authentication entirely.

246
Multi-Selecthard

An Ansible playbook retrieves a list of dictionaries from an API. Each dictionary has keys 'name', 'status', and 'zone'. The playbook needs to filter out entries where 'status' is 'inactive' and then extract only the 'name' values. Which THREE of the following combinations of filters and loops would achieve this?

Select 3 answers
A.{{ data | rejectattr('status', 'equalto', 'inactive') | map(attribute='name') | list }}
B.{{ data | rejectattr('status', 'equalto', 'inactive') | extract('name') | list }}
C.{% for item in data if item.status != 'inactive' %}{{ item.name }}{% endfor %}
D.{{ data | selectattr('status', 'equalto', 'active') | map(attribute='name') | list }}
E.{{ data | selectattr('status != inactive') | map(attribute='name') | list }}
AnswersA, C, D

rejectattr removes entries where status equals 'inactive', then map extracts names.

Why this answer

Option A is correct because `rejectattr` filters out items where `status` equals 'inactive', and then `map(attribute='name')` extracts the `name` values from the remaining dictionaries. The `| list` filter converts the result into a list. This is a standard Jinja2 filter chain in Ansible for filtering and transforming data.

Exam trap

The trap here is that candidates may confuse `rejectattr` with `selectattr` or misuse `extract` instead of `map(attribute=...)`, and also assume that `selectattr` can accept inline comparison expressions like `'status != inactive'` when it actually requires a separate test name and argument.

247
MCQmedium

A DevOps team is developing a collection of Ansible roles to standardize web server deployments. One role, 'webserver-base', configures the firewall and installs common packages. Another role, 'webserver-app', depends on 'webserver-base' and adds application-specific configurations. The team wants to ensure that when 'webserver-app' is applied to a host, 'webserver-base' is automatically applied first. They currently have a 'meta/main.yml' file in 'webserver-app' that lists 'webserver-base' as a dependency. However, when they run a playbook that includes 'webserver-app' in a role list, they notice that 'webserver-base' runs after 'webserver-app' sometimes, causing configuration conflicts. They verify that the dependency is correctly defined and that no other roles are involved. What change should they make to ensure 'webserver-base' always runs before 'webserver-app'?

A.Change the dependency type to 'include_role' in the playbook to control ordering.
B.Set 'static: yes' in the dependency entry in the dependent role's meta/main.yml.
C.Add 'order: before' to the dependency entry in meta/main.yml.
D.Add a 'pre_tasks' section in the playbook to include 'webserver-base' before 'webserver-app'.
AnswerB

This forces the dependency to be resolved statically, ensuring correct order.

Why this answer

By default, role dependencies are executed before the dependent role. The issue described suggests that something is causing the order to be reversed. Option C, using 'static: yes' in the dependency definition, forces Ansible to inline the dependencies at playbook parse time, ensuring the correct order.

Option A is not a valid keyword for dependency ordering. Option B would cause the role to be included multiple times. Option D would run the role explicitly but does not guarantee dependency order if the role is used elsewhere.

248
MCQeasy

A systems administrator is performing a rolling update of a three-node Red Hat Enterprise Linux 8 cluster running a load-balanced web application. The update involves upgrading the httpd package. The administrator uses Ansible to update one node at a time. After updating the first node, the administrator checks the application health and finds that the node is serving requests correctly. The administrator proceeds to update the second node. However, after the second node update completes, the load balancer reports that both the first and second nodes are unavailable. What is the most likely cause?

A.The httpd service on both nodes experienced a segmentation fault after the update.
B.The first node was inadvertently excluded from the load balancer pool by the Ansible playbook.
C.The load balancer was configured to only allow one node to be active at a time.
D.The second node's update triggered a configuration change that disabled the health check endpoint on both nodes.
AnswerD

A shared configuration or package dependency could impact both nodes.

Why this answer

Option C is correct because the update on the second node may have triggered a configuration change (e.g., via a shared config file or package dependency) that also affected the health check endpoint on the first node. Option A is wrong because if the first node were excluded, it would have been unavailable immediately after its update. Option B is wrong because a segmentation fault is unlikely to affect both nodes simultaneously.

Option D is wrong because load balancers typically do not limit active nodes to one; they manage pools of multiple nodes.

249
MCQeasy

An administrator is managing an Ansible Automation Platform deployment that runs job templates against a dynamic inventory sourced from VMware vCenter. The administrator updated the vCenter credentials in Tower after a password rotation. However, subsequent inventory syncs continue to fail with authentication errors. The administrator has confirmed that the new credentials work when tested directly on the controller node using the 'govc' CLI tool. The inventory source is configured to use the updated credential and the update_on_launch flag is set to true. Which action should the administrator take to resolve the issue?

A.Recreate the credential and assign it to the inventory source again.
B.Restart the ansible-tower service.
C.Run the inventory sync with the 'Clear Cache' option enabled.
D.Change the inventory source to use a new name and reconfigure it.
AnswerC

Clearing the cache ensures that stale credential data is removed, allowing the sync to authenticate with the updated credentials.

Why this answer

Option A is correct because clearing the cache forces a fresh inventory sync that discards any cached credentials or data, ensuring the new credentials are used. Option B is incorrect because restarting services is a brute-force approach that may clear cache but is not the targeted solution. Option C is incorrect because recreating the credential is unnecessary; the existing credential is valid.

Option D is incorrect because changing the inventory source name and reconfiguring it is overkill and does not directly address the caching issue.

250
MCQhard

What is the most likely cause of the failure?

A.The --check flag prevents role variable resolution.
B.The nginx role's defaults or vars do not define 'nginx_version'.
C.The host web1 is not configured to use the nginx role.
D.The nginx role was not included in the playbook correctly.
AnswerB

The variable is undefined in the role's defaults or vars files.

Why this answer

The error indicates that Ansible cannot resolve the variable 'nginx_version' during the playbook run. Since the `--check` flag only simulates changes and does not affect variable resolution, the most likely cause is that the nginx role's `defaults/main.yml` or `vars/main.yml` does not define this variable, leaving it undefined and causing the failure.

Exam trap

The trap here is that candidates often assume the `--check` flag is the culprit for any failure during a dry run, but Ansible's check mode still resolves all variables and validates templates, so a missing variable error is not caused by the check flag itself.

How to eliminate wrong answers

Option A is wrong because the `--check` flag does not prevent role variable resolution; it only skips the execution of modules that would make changes, while variable resolution still occurs normally. Option C is wrong because the host web1 does not need to be 'configured to use the nginx role' in a separate step; roles are applied via the playbook's `roles:` directive or `include_role`, and the error is about a missing variable, not role assignment. Option D is wrong because the error message does not indicate a syntax or inclusion issue with the role; it specifically points to an undefined variable, meaning the role was included but its variable definitions are incomplete.

251
MCQmedium

Refer to the exhibit. The playbook fails with an error. What is the most likely cause?

A.import_tasks cannot be used with a loop.
B.import_tasks must be placed in a role.
C.The loop variable should be referenced as '{{ item }}' without quotes.
D.The file names must be literal without templates.
AnswerA

import_tasks is static and loops are only supported with include_tasks.

Why this answer

Option A is correct. import_tasks is static and cannot be used with a loop; include_tasks should be used for dynamic inclusion.

252
MCQhard

A system administrator is managing Ansible Tower and wants to use an Azure Resource Manager credential to provision virtual machines. However, the credential fails authentication with the error '401 Unauthorized'. Which action should the administrator take to resolve the issue?

A.Regenerate the SSH key pair and update the credential.
B.Verify the client secret in the credential matches the one configured in Azure Active Directory.
C.Add the credential as a playbook-level variable instead of a Tower credential.
D.Generate a new API token from Azure and paste it into the credential.
AnswerB

A mismatch in client secret causes 401 errors.

Why this answer

The 401 Unauthorized error when using an Azure Resource Manager credential in Ansible Tower indicates that the authentication token or secret used to authenticate with Azure Active Directory is invalid or mismatched. Option B is correct because verifying that the client secret stored in the Tower credential exactly matches the one configured in Azure Active Directory resolves the authentication failure, as Azure AD uses OAuth 2.0 client credentials flow where the client secret is required for token acquisition.

Exam trap

The trap here is that candidates confuse SSH key authentication (used for Linux hosts) with Azure AD OAuth authentication, leading them to select option A, or they mistakenly think generating a new API token (option D) is the correct fix for Azure credentials.

How to eliminate wrong answers

Option A is wrong because SSH key pairs are used for authentication to Linux hosts via SSH, not for Azure Resource Manager API authentication, which uses OAuth 2.0 tokens and client secrets. Option C is wrong because adding the credential as a playbook-level variable bypasses Tower's credential management and encryption, but the underlying authentication issue (invalid client secret) would persist and still cause a 401 error. Option D is wrong because Azure Resource Manager credentials in Tower require a client ID and client secret, not an API token; generating a new API token is not the correct mechanism for Azure AD service principal authentication.

253
MCQhard

An Ansible rolling update playbook has 'serial: 1' and 'max_fail_percentage: 0'. During the update of a 5-host group, the first host fails. What is the outcome?

A.The play pauses for manual intervention
B.The play retries the failed host
C.The play aborts immediately
D.The play continues with the remaining 4 hosts
E.The play marks the host as unreachable and continues
AnswerC

Any failure with max_fail_percentage: 0 aborts the entire play.

254
Multi-Selecthard

Which TWO of the following are best practices when coordinating rolling updates with Ansible?

Select 2 answers
A.Define a 'max_fail_percentage' to abort the update if too many hosts fail.
B.Use the 'serial' keyword to update a subset of hosts at a time.
C.Use 'strategy: free' to allow hosts to run tasks independently.
D.Use 'gather_facts: no' to speed up the playbook.
E.Set 'any_errors_fatal: true' to stop the update on the first failure.
AnswersA, B

This ensures the update stops if a critical number of hosts fail, preventing widespread issues.

Why this answer

Option A is correct because 'max_fail_percentage' allows you to define a threshold of host failures (as a percentage of the batch size) that, when exceeded, causes Ansible to abort the entire rolling update. This prevents the update from continuing when too many hosts have failed, which could lead to an inconsistent or degraded state across the infrastructure. Option B is correct because the 'serial' keyword controls the number of hosts (or percentage) that Ansible updates in each batch, ensuring that only a subset of hosts is taken out of service at a time, which maintains overall service availability during the rolling update.

Exam trap

The trap here is that candidates often confuse 'any_errors_fatal' (which stops on the first failure globally) with 'max_fail_percentage' (which aborts only after a threshold of failures in a batch), leading them to select option E instead of A.

255
MCQeasy

A playbook includes multiple roles. The administrator wants to skip a specific role during execution. Which technique should they use?

A.Add a condition to each task in the role
B.Use the '--limit' option to exclude hosts
C.Use tags on the role and run with --tags
D.Use tags on the role and run with --skip-tags
AnswerD

--skip-tags excludes tasks with the specified tags.

Why this answer

The --skip-tags command-line option allows skipping tasks or roles that have a specific tag assigned. By tagging the role with a unique tag, the administrator can skip it without modifying the playbook.

256
MCQeasy

A company uses Ansible Automation Platform and wants to ensure that all playbook runs are logged for audit purposes. What is the simplest way to achieve centralized logging of job runs?

A.Use the logging module in each playbook to write to a central syslog.
B.Configure the syslog server in the automation controller settings.
C.Add a playbook callback that sends output to a file on each node.
D.Enable verbose logging in the inventory file.
AnswerB

Centralized logging is a built-in feature of automation controller.

Why this answer

Option B is correct because Automation Controller (formerly Ansible Tower) has a built-in setting under 'System → Logging' where you can configure a syslog server (e.g., using RFC 5424). Once configured, all job runs, playbook output, and audit events are automatically forwarded to that central syslog server without modifying any playbooks or adding custom callbacks. This is the simplest, most centralized, and most maintainable approach for audit logging.

Exam trap

The trap here is that candidates often think they need to modify playbooks (Option A) or write custom callback plugins (Option C) to achieve logging, when the platform already provides a simple, built-in configuration option for centralized syslog forwarding.

How to eliminate wrong answers

Option A is wrong because adding a 'logging' module call to every playbook is not centralized; it requires manual insertion into each playbook, violates the principle of separation of concerns, and does not capture system-level events like job launches or failures. Option C is wrong because a callback plugin that writes to a file on each node creates distributed logs, not centralized logging, and requires custom development and deployment to all nodes. Option D is wrong because enabling verbose logging in the inventory file is not a valid Ansible concept; inventory files do not have a 'verbose' setting, and even if you meant verbosity at the ansible-playbook command level, that only increases output detail locally and does not send logs to a central server.

257
MCQeasy

An Ansible playbook needs to ensure a service is enabled and running on boot. Which combination of parameters should be used with the 'systemd' module?

A.enabled: yes, state: reloaded
B.enabled: yes, state: started
C.enabled: yes, daemon_reload: yes
D.enabled: yes, state: restarted
AnswerB

This ensures the service is enabled and running.

Why this answer

Option B is correct because the 'systemd' module in Ansible requires both 'enabled: yes' to set the service to start on boot and 'state: started' to ensure the service is currently running. This combination directly fulfills the requirement of ensuring a service is enabled and running on boot.

Exam trap

The trap here is that candidates often confuse 'enabled' with 'state' or assume 'daemon_reload' or 'reloaded' can substitute for starting the service, but only the combination of 'enabled: yes' and 'state: started' fully satisfies the requirement for both boot persistence and current running state.

How to eliminate wrong answers

Option A is wrong because 'state: reloaded' only reloads the service's configuration without starting it if it is not running, and it does not guarantee the service is enabled on boot. Option C is wrong because 'daemon_reload: yes' only reloads the systemd manager configuration (e.g., after adding new unit files) but does not start the service or enable it on boot. Option D is wrong because 'state: restarted' restarts the service if it is running but does not ensure it is enabled to start on boot, and it will fail if the service is not already running.

258
MCQhard

After upgrading AAP, an admin notices that all job templates using a custom virtual environment fail with 'No module named 'foo''. The virtual environment was previously working. What should the admin do first?

A.Switch the job template to use an execution environment instead.
B.Reassign the job template to the default virtual environment.
C.Recreate the custom virtual environment and reinstall the 'foo' package.
D.Verify that the credential associated with the job template is valid.
AnswerC

Upgrades can break virtual environments; rebuilding them is a standard fix.

Why this answer

After an AAP upgrade, custom virtual environments are not automatically migrated or preserved; they must be recreated and their packages reinstalled. The 'No module named 'foo'' error indicates that the Python environment no longer contains the required package, so recreating the environment and reinstalling 'foo' is the correct first step to restore functionality.

Exam trap

The trap here is that candidates assume the custom virtual environment persists unchanged after an upgrade, but Red Hat explicitly tests that custom environments must be recreated and packages reinstalled because the upgrade process does not preserve them.

How to eliminate wrong answers

Option A is wrong because switching to an execution environment is a different approach that does not address the root cause—the missing package in the custom virtual environment—and may introduce additional configuration overhead. Option B is wrong because reassigning the job template to the default virtual environment would bypass the custom environment but would not resolve the missing package issue for environments that require 'foo'. Option D is wrong because credential validity is unrelated to Python module availability; the error is a Python import error, not an authentication or authorization failure.

259
MCQmedium

An Ansible playbook sets a variable with a dictionary value in the play's vars and also in group_vars/all. When the play runs, the dictionary in group_vars completely replaces the one in play vars. What is the most likely reason?

A.the playbook uses 'set_fact' which overrides all other vars
B.the play vars dictionary is defined with incorrect YAML syntax
C.the group_vars file uses a different variable name
D.Ansible's default variable precedence uses replacement, not merging, for dictionaries
AnswerD

Correct: unless 'hash_behaviour=merge' is set, later sources replace earlier ones.

Why this answer

Option A is correct because Ansible does not merge dictionaries by default; a variable assignment overwrites entirely. Option B is false (hash_behaviour default is replace). Options C and D are incorrect.

260
Matchingmedium

Match each firewall zone to its default behavior.

Drag a concept onto its matching description — or click a concept then click the description.

Concepts
Matches

Default zone, untrusted network

Private network, slightly trusted

Demilitarized zone, limited access

All traffic accepted

All incoming packets dropped

Why these pairings

Common firewalld zones in RHEL.

261
MCQhard

An automation team is designing a content collection to distribute internal Ansible modules across the organization. The collection should be installed from a private Galaxy server. To minimize namespace conflicts and ensure discoverability, which naming convention should be used for the collection?

A.collection_name.namespace
B.namespace_collection_name
C.namespace-collection_name
D.namespace.collection_name
AnswerD

Standard Ansible Galaxy naming convention for collections.

Why this answer

In Ansible, collections are distributed using a fully qualified collection name (FQCN) in the format `namespace.collection_name`. This naming convention is required by the Ansible Galaxy server and the `ansible-galaxy collection install` command to uniquely identify and install collections, minimizing namespace conflicts and ensuring discoverability across the organization.

Exam trap

The trap here is that candidates may confuse the dot separator with other common naming conventions (like underscores or hyphens used in Python packages or Ansible roles), but Ansible collections strictly require the `namespace.collection_name` format with a dot.

How to eliminate wrong answers

Option A is wrong because `collection_name.namespace` reverses the required order; the namespace must come first, followed by a dot and then the collection name. Option B is wrong because `namespace_collection_name` uses an underscore separator, but Ansible collections require a dot (`.`) as the delimiter between namespace and collection name. Option C is wrong because `namespace-collection_name` uses a hyphen, which is not the correct separator; the dot is the only valid separator in Ansible's FQCN for collections.

262
Multi-Selecthard

Which TWO of the following are correct about Ansible Vault?

Select 2 answers
A.vault encryption is irreversible
B.vault encrypted files cannot be edited in place
C.the vault password can be provided via the '--vault-password-file' option
D.vault can encrypt only specific variable values within a file
E.the vault id can be specified to use multiple vault passwords
AnswersC, E

Correct: this is a common way to automate vault decryption.

Why this answer

Options A and D are correct. Vault password can be provided via a file, and vault id allows using multiple passwords. Option B is false (vault can encrypt whole files).

Option C is false (vault encrypts files, not individual variables without using !vault). Option E is false (encryption is reversible with decryption).

263
MCQhard

You are an automation engineer at a large enterprise. The company uses Ansible Automation Platform 2.x and has a private Automation Hub server. The security team mandates that all execution environments must be built from a hardened base image that has been approved by the security team. The base image is stored in a private container registry at registry.internal.company.com/hardened-ee:latest. You need to create an execution environment that includes a custom collection 'company.tools' which is hosted on the private Automation Hub. Additionally, the execution environment must include the Python library 'cryptography' version 3.4.8. You have created the following files: execution-environment.yml: --- version: 3 images: base_image: name: registry.internal.company.com/hardened-ee:latest options: package_manager_path: /usr/bin/microdnf dependencies: galaxy: requirements.yml python: requirements.txt requirements.yml: --- collections: - name: company.tools source: https://automationhub.company.com/api/galaxy/content/private/ requirements.txt: cryptography==3.4.8 When you run 'ansible-builder build -f execution-environment.yml', the build fails with an error: 'Error: Failed to resolve dependency cryptography==3.4.8'. Based on this scenario, what is the most likely cause of the failure?

A.The requirements.yml file has an incorrect source URL for the private Automation Hub.
B.The base image already includes cryptography but not version 3.4.8, causing a version conflict.
C.The execution-environment.yml is missing the 'system' dependency section for bindep.txt.
D.The package_manager_path should be /usr/bin/dnf instead of microdnf.
AnswerB

The pinned version may conflict with the base image's package, causing pip to fail.

Why this answer

Option B is correct because the error 'Failed to resolve dependency cryptography==3.4.8' indicates a version conflict with the Python cryptography library already present in the hardened base image. The base image likely includes a different version of cryptography, and pip cannot satisfy the pinned version constraint due to conflicts with the pre-installed package. Ansible Builder uses pip to install Python dependencies, and if the base image has a conflicting version, the build fails unless the dependency is unpinned or the base image is adjusted.

Exam trap

The trap here is that candidates often assume the error is due to a misconfigured Automation Hub URL or package manager path, but the specific pip error 'Failed to resolve dependency' points directly to a Python package version conflict with the base image, not to external repository or system package manager issues.

How to eliminate wrong answers

Option A is wrong because the source URL for the private Automation Hub is correctly formatted (https://automationhub.company.com/api/galaxy/content/private/) and would cause a different error (e.g., 'Failed to download collection') if incorrect, not a Python dependency resolution error. Option C is wrong because the 'system' dependency section for bindep.txt is optional and not required for Python library installation; its absence would not cause a pip dependency resolution failure. Option D is wrong because the package_manager_path is correctly set to /usr/bin/microdnf for Red Hat Universal Base Images (UBI) which use microdnf, and using dnf would cause a different error (e.g., 'command not found'), not a Python dependency conflict.

264
MCQmedium

A playbook fails with 'ERROR! 'become' is not a valid attribute for a Play'. What is the most likely cause?

A.The playbook lacks a hosts line
B.The become directive is misspelled
C.become is allowed only in tasks, not plays
D.The playbook uses an older syntax that requires 'sudo'
AnswerD

Older Ansible used 'sudo: yes' instead of 'become: yes'.

Why this answer

Option D is correct because in older versions of Ansible (prior to 2.0), privilege escalation was handled using the 'sudo' keyword at the play level. The error 'become' is not a valid attribute for a Play' indicates that the playbook is using the modern 'become' directive at the play level, but the installed Ansible version (likely 1.x) does not support it. The correct syntax for that version would be 'sudo: yes'.

Exam trap

The trap here is that candidates familiar with modern Ansible assume 'become' is universally valid, forgetting that EX294 covers RHEL 8 which ships with Ansible 2.9, but the question deliberately references an older version to test knowledge of version-specific syntax changes.

How to eliminate wrong answers

Option A is wrong because a missing 'hosts' line would cause a different error ('hosts is required for each play'), not a complaint about 'become'. Option B is wrong because if 'become' were misspelled, Ansible would treat it as an unknown key and likely ignore it or produce a warning, not a fatal error about an invalid attribute. Option C is wrong because 'become' is actually valid at the play level in Ansible 2.0+; the error occurs only when the Ansible version is too old to recognize it.

265
Drag & Dropmedium

Drag and drop the steps to configure a logical volume (LV) using LVM on a new disk in the correct order.

Drag steps to the numbered slots on the right, or tap a step then tap a slot.

Steps
Order

Why this order

LVM workflow: PV -> VG -> LV -> filesystem -> mount.

266
MCQhard

A playbook uses ansible.builtin.import_playbook to include other playbooks. The administrator needs to pass variables to the imported playbook. Which approach is valid?

A.Use ansible.builtin.include_vars inside the imported playbook
B.Set variables using set_fact before the import
C.Use group_vars or host_vars
D.Add a 'vars' block to the import_playbook statement
AnswerD

import_playbook: other.yml vars: { key: value } is the correct syntax.

Why this answer

When using import_playbook, variables can be passed using the 'vars' keyword within the import statement. This makes the variables available throughout the imported playbook.

267
Drag & Dropmedium

Drag and drop the steps to configure a systemd service to start automatically at boot in the correct order.

Drag steps to the numbered slots on the right, or tap a step then tap a slot.

Steps
Order

Why this order

Systemd service: create unit file, reload, enable, start, verify status.

268
Multi-Selecthard

An Ansible playbook repeatedly uses the same pattern: check if a service is running, if not start it, and then verify it's running. Which three Ansible features can be used to reduce code duplication? (Choose three.)

Select 3 answers
A.Using 'include_vars' to reuse variable files.
B.Using a role with multiple tasks and handlers.
C.Using 'debug' module to output the status.
D.Creating a custom filter plugin to encapsulate the logic.
E.Using 'include_tasks' with a loop to include a common task file.
AnswersB, D, E

Correct: Roles encapsulate tasks, handlers, and variables for reuse.

Why this answer

Options B, D, and E are correct. B (custom filter plugin) can encapsulate logic, D (roles) can group tasks, and E (include_tasks with loop) can reuse a task file. Option A is for variables, not logic.

Option C is for debugging, not reuse. Therefore, B, D, and E are correct.

269
MCQhard

A company manages a large infrastructure of 10,000 servers using Ansible. The Ansible control node runs on a powerful machine with 32 cores and 64GB RAM. Recently, a playbook that processes server facts and generates a compliance report has become extremely slow, taking over 6 hours to complete. The playbook uses several `set_fact` tasks with complex jinja2 filters including `selectattr`, `map`, `json_query`, and `combine`. The inventory is stored in a dynamic inventory script that returns JSON. The team suspects that the filter operations are causing performance bottlenecks, especially when creating large data structures. A junior engineer suggests splitting the playbook into multiple plays and using `delegate_to` to distribute processing across managed nodes. Another suggests using the `ansible.builtin` module instead of filters. The senior architect recommends converting the heavy filter logic into a custom action plugin. What is the most effective approach to significantly reduce the execution time while maintaining functionality?

A.Distribute the processing across managed nodes using `delegate_to` and loop over hosts.
B.Use `ansible.builtin` modules to replace filter operations; for example, use `add_host` and `group_by` to structure data.
C.Convert the heavy filter logic into a custom Python action plugin that runs on the control node and performs data transformation efficiently.
D.Use `with_items` and `with_nested` loops instead of filters, as loops are faster.
AnswerC

Action plugins run natively in Python, bypassing Jinja2 overhead.

Why this answer

Option C is correct because custom action plugins execute Python code directly on the control node, bypassing the Jinja2 templating engine entirely. This eliminates the overhead of parsing complex filters like `json_query` and `combine` for every host, which is the primary bottleneck when processing large data structures across 10,000 servers. Action plugins also have full access to Ansible's internal APIs, allowing efficient in-memory data transformations without the serialization/deserialization costs of `set_fact`.

Exam trap

The trap here is that candidates assume `delegate_to` or `ansible.builtin` modules are general-purpose performance fixes, when in fact the bottleneck is the Jinja2 filter evaluation on the control node, which only a custom plugin or module can bypass.

How to eliminate wrong answers

Option A is wrong because `delegate_to` moves task execution to managed nodes, but the filter operations still run in Jinja2 on the control node when the task is processed; distributing the playbook across nodes adds network latency and does not reduce the CPU-bound filter overhead. Option B is wrong because `ansible.builtin` modules like `add_host` and `group_by` are designed for inventory manipulation, not for complex data transformations; they cannot replace the logic of `selectattr`, `map`, or `json_query` without significant workarounds that would still rely on Jinja2 filters internally. Option D is wrong because `with_items` and `with_nested` are loop constructs that actually increase task execution time by iterating over items sequentially, and they do not accelerate filter evaluation; in fact, using loops with filters often compounds the performance issue.

270
MCQmedium

A playbook uses the 'block' and 'rescue' keywords to handle errors. The block contains three tasks. The first task fails. What happens next?

A.The rescue section runs and retries the failed task.
B.The rescue section runs immediately after the failure.
C.The playbook fails with an error message.
D.The remaining tasks in the block run, then the rescue section runs.
AnswerB

Rescue is executed when any task in the block fails.

Why this answer

In Ansible, when a task inside a `block` fails, the `rescue` section is executed immediately after the failure, without running any remaining tasks in the block. This is analogous to a try-catch mechanism in programming: the block is the 'try', and the rescue is the 'catch'. Option B correctly describes this behavior.

Exam trap

The trap here is that candidates often confuse `block`/`rescue` with a simple retry mechanism or assume that all tasks in the block must complete before error handling, but Ansible's behavior is to immediately jump to rescue on the first failure.

How to eliminate wrong answers

Option A is wrong because the rescue section does not retry the failed task; it runs a separate set of tasks to handle the error, and retry logic would require a `until` loop or `retries` parameter on the task itself. Option C is wrong because the playbook does not fail immediately; the rescue section is designed to catch the error and continue execution, preventing a playbook failure unless the rescue itself fails. Option D is wrong because the remaining tasks in the block are skipped once a task fails; the rescue runs immediately, not after the block completes.

271
MCQmedium

An administrator wants to create a custom credential type to store a third-party API key. The API key must be passed to the playbook as an environment variable `MY_API_KEY`. What is the correct Injector configuration in the custom credential type definition?

A.file: {MY_API_KEY: "{{ api_key }}"}
B.env: {"MY_API_KEY": api_key}
C.extra_vars: {MY_API_KEY: "{{ api_key }}"}
D.env: {MY_API_KEY: "{{ api_key }}"}
AnswerD

The env dictionary maps credential inputs to environment variables.

Why this answer

Option D is correct because the Injector configuration for a custom credential type in Ansible Automation Platform uses the `env` key to map credential inputs to environment variables. The syntax `env: {"MY_API_KEY": "{{ api_key }}"}` correctly references the input field `api_key` using Jinja2 templating and assigns it to the environment variable `MY_API_KEY`, which the playbook can then access via `ansible_env.MY_API_KEY`.

Exam trap

The trap here is that candidates often confuse `env` with `extra_vars` or forget the Jinja2 templating syntax, leading them to pick Option B (missing braces) or Option C (incorrect injector type).

How to eliminate wrong answers

Option A is wrong because `file` is not a valid Injector key; it is used for file-based credential types (e.g., SSH keys) but not for environment variables. Option B is wrong because it omits the required Jinja2 braces around the variable reference (`api_key` instead of `{{ api_key }}`), which would cause the literal string 'api_key' to be passed rather than the credential input value. Option C is wrong because `extra_vars` is used to inject variables into the playbook's variable space, not as environment variables; it would set `MY_API_KEY` as an Ansible variable, not an environment variable.

272
Multi-Selectmedium

Which THREE of the following are valid attributes of the ansible.builtin.service module?

Select 3 answers
A.state
B.enabled
C.pattern
D.name
E.runlevel
AnswersA, B, D

Correct: state controls whether the service is started/stopped.

Why this answer

Options A, B, and C are correct. state, enabled, and name are valid parameters. runlevel and pattern are not standard parameters of the service module.

273
MCQeasy

An administrator notices that during a rolling update, the playbook seems to hang after updating the first host. The playbook uses serial: 5. What is the most likely cause?

A.The playbook has an infinite loop.
B.One of the hosts in the batch is taking too long to complete its tasks.
C.The SSH control path is exhausted.
D.The max_fail_percentage is set too high.
AnswerB

Correct. A slow host delays the entire batch because Ansible waits for all hosts in the batch.

Why this answer

When `serial: 5` is set, Ansible processes hosts in batches of five. If one host in the batch takes an unusually long time to complete its tasks (e.g., due to a slow network, a hanging service restart, or a long-running command), the entire batch will appear to hang because Ansible waits for all hosts in the current batch to finish before proceeding to the next batch. This is the most likely cause of the observed behavior during a rolling update.

Exam trap

Red Hat often tests the misconception that `serial` controls parallelism across all hosts (like `forks`), but the trap here is that `serial` batches hosts sequentially, so a single slow host in a batch blocks the entire batch from completing, causing the playbook to appear to hang.

How to eliminate wrong answers

Option A is wrong because an infinite loop would cause the playbook to run indefinitely on a single host, not hang after updating the first host in a batch; the playbook would continue looping on that host without progressing. Option C is wrong because SSH control path exhaustion would typically manifest as SSH connection failures or errors, not a hang after the first host completes; it is a connection pooling issue, not a batch processing delay. Option D is wrong because `max_fail_percentage` controls how many hosts can fail before Ansible aborts the playbook; a high value would allow more failures, not cause a hang, and it does not affect the timing of task completion within a batch.

274
MCQeasy

An Ansible Tower administrator needs to add a single host to an existing inventory. The host has a static IP address and requires SSH access with a specific username and private key. Which of the following is the correct approach?

A.Add the host to an inventory group using the 'Add Group' option and specify the host details there.
B.Use the 'Add Host' form and in the 'Credentials' field, select the appropriate SSH credential from the drop-down.
C.Create a new credential first, then add the host directly within the credential definition.
D.Navigate to the inventory, click 'Add Host', enter the hostname and IP, and optionally define variables. Then create a credential for SSH and associate it with the host through a job template.
AnswerD

This is the standard method to add a host in Tower.

Why this answer

Option D is correct because in Ansible Tower, a host is added to an inventory via the 'Add Host' form, where you enter the hostname and IP address and optionally define variables. SSH credentials are not directly associated with a host; instead, they are created separately and then linked to the host through a job template, which uses the credential to authenticate when running playbooks against that host.

Exam trap

The trap here is that candidates mistakenly think SSH credentials can be directly assigned to a host in the inventory UI, when in reality credentials are associated at the job template level to maintain separation of concerns and reusability.

How to eliminate wrong answers

Option A is wrong because the 'Add Group' option is for creating or modifying groups within an inventory, not for adding a host; host details are not specified within a group definition. Option B is wrong because the 'Add Host' form does not have a 'Credentials' field; credentials are managed separately and associated at the job template level, not directly on the host. Option C is wrong because a credential definition does not include host details; credentials are reusable objects that contain authentication information (username, private key) and are not tied to a specific host during creation.

275
MCQhard

A company has deployed Ansible Automation Platform with a single automation controller node. The operations team uses a workflow that includes three job templates: A, B, and C, each requiring different credentials. Recently, the workflow started failing intermittently with errors such as 'Timeout' and 'Connection refused' on certain hosts. The inventory is dynamic from a cloud provider. The administrator checks that the credentials are valid and the hosts are online. The job execution history shows that the failures occur only when the workflow attempts to run job template B on a subset of hosts that are located in a different subnet. Job templates A and C run fine on all hosts. What is the most likely cause and the best course of action?

A.The hosts in the problematic subnet are not reachable due to a firewall; add those hosts to a separate inventory and use a different cloud credential.
B.The credential used by job template B is associated with an incorrect SSH key for those hosts; create a new credential for that subnet and update the job template.
C.The automation controller does not have network access to the problematic subnet; install a second automation controller node in that subnet and configure clustering.
D.The job template B requires a sudo escalation that is not configured on those hosts; update the playbook to use become_method: su.
AnswerB

Incorrect SSH key causes connection refused; separate credentials per subnet can resolve.

Why this answer

Option B is correct because the intermittent failures on a specific subnet, despite valid credentials and online hosts, strongly indicate that the SSH key or credential used by job template B is not accepted by those hosts. Since job templates A and C work fine on all hosts, the issue is credential-specific, not network-wide. Creating a new credential with the correct SSH key for that subnet and updating job template B resolves the authentication failure.

Exam trap

The trap here is that candidates confuse network-level connectivity issues (firewall, routing) with authentication-level failures, assuming 'Connection refused' always means a firewall block rather than an SSH key rejection or credential mismatch.

How to eliminate wrong answers

Option A is wrong because adding hosts to a separate inventory with a different cloud credential does not address SSH key mismatch; cloud credentials are for API authentication to the cloud provider, not for host-level SSH access. Option C is wrong because if the automation controller lacked network access to the subnet, job templates A and C would also fail on those hosts, but they run fine; clustering does not fix credential issues. Option D is wrong because sudo escalation method (become_method) does not cause 'Timeout' or 'Connection refused' errors; those are network or authentication errors, not privilege escalation failures.

276
MCQeasy

A junior admin is troubleshooting why a job template fails with 'Permission denied' when connecting to a target host. The job template uses a machine credential that appears correct. What is the first thing to check?

A.Verify the inventory contains the correct host IP
B.Check the credential's username and private key / password
C.Check the vault credential used in the job template
D.Check the project sync status
AnswerB

The error suggests the credentials are not accepted by the target host.

Why this answer

The error 'Permission denied' during SSH connection to a target host indicates an authentication failure. Since the machine credential appears correct, the most immediate cause is that the username or private key/password stored in the credential is incorrect or mismatched. This is the first thing to check because the credential directly controls authentication to the target host.

Exam trap

The trap here is that candidates often confuse 'Permission denied' with a network or inventory issue, leading them to check the inventory or project sync instead of the credential's authentication details.

How to eliminate wrong answers

Option A is wrong because verifying the inventory host IP addresses connectivity issues (e.g., wrong host or unreachable), not authentication failures; 'Permission denied' is an SSH-level error, not a network reachability error. Option C is wrong because vault credentials are used to decrypt sensitive data within Ansible, not for SSH authentication to target hosts; they do not affect the 'Permission denied' error. Option D is wrong because project sync status relates to retrieving playbook content from a source control repository, not to SSH authentication; a failed sync would cause a different error (e.g., 'project not found'), not 'Permission denied'.

277
MCQhard

A company uses Ansible Tower and has defined a custom inventory script. The inventory returns JSON with nested groups. The playbook needs to list all hosts from a specific group 'webservers' that are not in the 'drain' subgroup. Which combination of filters correctly extracts these hosts?

A.{{ groups['webservers'] | symmetric_difference(groups['drain']) }}
B.{{ groups['webservers'] | intersect(groups['drain']) }}
C.{{ groups['webservers'] | union(groups['drain']) }}
D.{{ groups['webservers'] | difference(groups['drain']) }}
AnswerD

difference returns elements in first list not in second.

Why this answer

Option D is correct because the `difference` filter in Ansible returns the elements of the first list that are not present in the second list. This directly matches the requirement: all hosts in the 'webservers' group that are not in the 'drain' subgroup.

Exam trap

The trap here is that candidates confuse `difference` with `symmetric_difference` (option A) or `intersect` (option B), often misreading the requirement as 'hosts not in drain' versus 'hosts in both groups'.

How to eliminate wrong answers

Option A is wrong because `symmetric_difference` returns elements that are in either list but not in both, which would include hosts in 'drain' but not in 'webservers' — not the required set. Option B is wrong because `intersect` returns only hosts that are in both groups, which is the exact opposite of what is needed. Option C is wrong because `union` combines all unique elements from both groups, giving all hosts from 'webservers' and 'drain' without exclusion.

278
Multi-Selecthard

Which TWO Ansible playbook parameters directly control the number of host failures allowed before aborting a rolling update?

Select 2 answers
A.max_fail_percentage
B.any_errors_fatal
C.throttle
D.serial
E.ignore_errors
AnswersA, B

Sets the maximum percentage of failed hosts before abort.

Why this answer

Option A is correct because `max_fail_percentage` directly specifies the maximum percentage of hosts that can fail during a rolling update before Ansible aborts the entire batch. Option B is correct because `any_errors_fatal` causes the playbook to stop immediately if any host in the current batch fails, effectively limiting failures to zero before aborting the rolling update.

Exam trap

Red Hat often tests the distinction between `serial` (batch size) and `max_fail_percentage` (failure threshold), causing candidates to mistakenly think `serial` controls failure tolerance when it only controls concurrency.

279
MCQhard

Refer to the exhibit. An administrator runs a playbook in check mode and receives the shown output. What should be done to fix the failure while maintaining idempotency?

A.Modify the deploy role to use the force parameter when copying files.
B.Add a task in the apache role to create the /var/www/html directory using the file module.
C.Run the playbook without check mode to force the deployment.
D.Add a pre_task in the playbook to create /var/www/html before roles execute.
AnswerB

The apache role should ensure the document root exists before deploying files.

Why this answer

The deploy role fails because /var/www/html does not exist. The apache role should ensure the directory exists, typically by including a task to create it. Adding a file module task in the apache role to create /var/www/html would fix the issue.

280
MCQhard

A Red Hat Ansible Automation Platform deployment uses automation mesh to manage remote nodes across a high-latency WAN. An administrator notices that some job runs fail intermittently due to connection timeouts. The administrator wants to improve reliability without changing network infrastructure. Which configuration change is most effective?

A.Increase the 'timeout' value in the [defaults] section of ansible.cfg to 60 seconds.
B.Increase the 'retries' parameter for each task.
C.Increase the 'forks' value in ansible.cfg to 50.
D.Set 'async: 600' and 'poll: 10' in the playbook.
AnswerA

This extends the connection timeout, accommodating high-latency links.

Why this answer

Option A is correct because increasing the 'timeout' value in the [defaults] section of ansible.cfg extends the SSH connection timeout, which directly addresses intermittent failures caused by high-latency WAN links. This change allows Ansible to wait longer for a remote node to respond before aborting the connection, improving reliability without altering network infrastructure.

Exam trap

The trap here is that candidates often confuse connection timeouts with task execution failures, leading them to choose retries (Option B) or async (Option D), which do not address the root cause of SSH connection drops on high-latency links.

How to eliminate wrong answers

Option B is wrong because increasing the 'retries' parameter for each task only retries the task execution after a failure, but does not address the underlying connection timeout issue; the initial connection would still fail before any retry logic applies. Option C is wrong because increasing the 'forks' value to 50 increases parallelism, which can exacerbate network congestion and timeout issues on a high-latency WAN, making reliability worse. Option D is wrong because setting 'async: 600' and 'poll: 10' is designed for long-running tasks that should run in the background without blocking, not for fixing connection timeouts; it does not affect the SSH connection timeout that causes the intermittent failures.

281
Multi-Selecteasy

An Ansible playbook that installs packages and configures services is not idempotent. Which two practices should be implemented to make it idempotent? (Choose two.)

Select 2 answers
A.Use notify handlers to restart services only on change.
B.Use the command module with the 'creates' parameter.
C.Use state=present for package installation.
D.Use check_mode: yes to preview changes.
E.Set always_run: yes on tasks.
AnswersB, C

creates makes the command run only if a specified file is missing, ensuring idempotency.

Why this answer

Options A and B are correct. Using state=present for package installation ensures the package is installed only if not present, making it idempotent. Using the command module with the 'creates' parameter ensures the command runs only if the specified file does not exist.

Options C, D, and E do not directly address idempotency.

282
Multi-Selecteasy

Which TWO filters can be used to conditionally select elements from a list based on a test? (Select exactly two.)

Select 2 answers
A.map
B.combine
C.reject
D.select
E.flatten
AnswersC, D

Returns elements for which the test is false.

Why this answer

In Ansible, the `reject` filter removes elements from a list that match a given condition, effectively selecting only those that do not match. The `select` filter does the opposite: it keeps elements that match the condition. Both are used for conditional selection from a list based on a test, making C and D correct.

Exam trap

The trap here is that candidates may confuse `map` with `select` because both iterate over lists, but `map` transforms elements while `select`/`reject` filter them based on a test.

283
Multi-Selecteasy

Which two statements about Ansible roles are correct? (Select exactly 2.)

Select 2 answers
A.Roles must have a meta/main.yml file.
B.Roles are a type of playbook.
C.Roles can include tasks, handlers, variables, and defaults.
D.Roles cannot be used with include_role.
E.Roles can be installed from Galaxy.
AnswersC, E

Roles have a standard directory structure for these components.

Why this answer

Options A and D are correct. Roles can contain tasks, handlers, variables, and defaults. Roles can be installed from Ansible Galaxy.

Option B is false because roles can be used with include_role. Option C is false because meta/main.yml is optional. Option E is false because roles are not playbooks.

284
MCQeasy

In an Ansible playbook, the 'strategy' parameter is set to 'free'. What behavior does this strategy produce?

A.Playbook runs tasks on hosts in batches of 1.
B.Strategy is deprecated and replaced by 'linear'.
C.All hosts run the same task at the same time, then move to the next task.
D.Each host runs through the playbook independently of other hosts.
AnswerD

Free strategy allows hosts to run tasks as fast as they can, not waiting for others.

Why this answer

Option A is correct. The 'free' strategy allows each host to run through the playbook independently without waiting for other hosts. Option B (linear) is the default where hosts wait at each task.

Option C (serial) batches hosts. Option D is not a valid strategy.

285
MCQhard

A DevOps engineer is troubleshooting an Ansible Automation Platform deployment where ansible-navigator fails to run a playbook, showing the error 'Error: Unable to pull execution environment image'. The ansible-navigator configuration file is shown in the exhibit. Which change should the engineer make to resolve the issue?

A.Set 'mode' to 'interactive' instead of 'stdout'
B.Change the execution-environment image to 'registry.redhat.io/ansible-automation-platform-24/ee-minimal-rhel8:latest'
C.Change 'pull policy' from 'missing' to 'always'
D.Set 'playbook-artifact enable' to 'true'
AnswerC

Setting policy to 'always' forces a pull attempt each time, which can resolve pull failures due to missing or outdated images.

Why this answer

Option C is correct because the error 'Unable to pull execution environment image' indicates that the image specified in the ansible-navigator configuration cannot be retrieved from the registry. Setting the 'pull policy' to 'always' forces ansible-navigator to attempt a fresh pull of the execution environment image every time, which can resolve transient network issues, authentication problems, or stale local image caches that cause the pull to fail when the policy is 'missing'.

Exam trap

The trap here is that candidates may assume the error is due to an incorrect image name or missing authentication, but the question specifically tests understanding of the 'pull policy' behavior and how it interacts with local image caching and registry connectivity.

How to eliminate wrong answers

Option A is wrong because setting 'mode' to 'interactive' instead of 'stdout' changes how ansible-navigator displays output but does not affect the ability to pull an execution environment image; the error is related to image retrieval, not output mode. Option B is wrong because changing the execution-environment image to a different valid image (registry.redhat.io/ansible-automation-platform-24/ee-minimal-rhel8:latest) does not address the root cause of the pull failure; if the current image is correct but unreachable, a different image will also fail unless the underlying connectivity or authentication issue is resolved. Option D is wrong because setting 'playbook-artifact enable' to 'true' controls whether playbook artifacts (e.g., logs) are saved, which has no impact on the ability to pull an execution environment image.

286
MCQmedium

An Ansible automation team is designing a playbook to manage network devices. They need to ensure that the playbook can handle transient network failures by retrying failed tasks a specific number of times with a delay between retries. Which approach should they use?

A.Set `max_fail_percentage` in the play to 0 and use `ignore_errors: yes` with a rescue block.
B.Use the `throttle` keyword to limit concurrent tasks and rely on idempotency.
C.Set `serial: 1` on the play to ensure only one host is processed at a time and rely on idempotency.
D.Use the `until` loop with `retries` and `delay` parameters on the task.
AnswerD

The `until` loop with `retries` and `delay` retries the task until a condition is met or retries are exhausted, ideal for transient failures.

Why this answer

The `until` loop with `retries` and `delay` parameters is the correct approach because it allows a task to be retried a specified number of times with a configurable pause between attempts, directly addressing transient network failures. This is a built-in Ansible feature for handling intermittent issues without additional error-handling constructs.

Exam trap

The trap here is that candidates confuse concurrency controls (`serial`, `throttle`) or error-handling directives (`ignore_errors`, `max_fail_percentage`) with the retry mechanism, which is specifically implemented via the `until` loop with `retries` and `delay` parameters.

How to eliminate wrong answers

Option A is wrong because `max_fail_percentage` controls the percentage of hosts that can fail before the play aborts, not task retries; combining `ignore_errors: yes` with a rescue block would suppress errors but not implement retry logic. Option B is wrong because the `throttle` keyword limits the number of concurrent task executions, which is unrelated to retrying failed tasks. Option C is wrong because `serial: 1` processes hosts one at a time to control rolling updates or concurrency, not to retry tasks on failure.

287
Multi-Selectmedium

An automation controller administrator must ensure that a playbook's output does not expose sensitive data. Which TWO actions should be taken? (Choose exactly two.)

Select 2 answers
A.Set 'no_log: true' on tasks that handle sensitive data.
B.Set 'stdout_callback = actionable' in ansible.cfg.
C.Use 'name: "Sensitive task"' but keep the task body visible.
D.Add 'display_args_to_stdout = false' to the execution environment's ansible.cfg.
E.Use 'tags: never' on sensitive tasks.
AnswersA, D

This prevents the output of those tasks from being displayed.

Why this answer

Setting 'no_log: true' on tasks that handle sensitive data (Option A) is the correct approach because it prevents Ansible from printing task arguments and output to the console or log files, ensuring that sensitive information like passwords or API keys are not exposed. This directive is a built-in Ansible feature specifically designed for security-sensitive operations.

Exam trap

The trap here is that candidates often confuse reducing output verbosity (Option B) with actually hiding sensitive data, not realizing that 'no_log' is the only mechanism that explicitly redacts task arguments and results from all output channels.

288
MCQeasy

A user wants to use a collection from Automation Hub. Which command downloads and installs the collection to the default collections path?

A.ansible-pull collection install
B.ansible-playbook collection install
C.ansible-collection install
D.ansible-galaxy collection install
AnswerD

Correct command for installing collections.

Why this answer

The correct command to download and install a collection from Automation Hub to the default collections path is `ansible-galaxy collection install`. This command uses the `ansible-galaxy` utility, which is the standard tool for managing Ansible roles and collections, and the `collection install` subcommand specifically handles collection installation from configured sources like Automation Hub or Ansible Galaxy.

Exam trap

The trap here is that candidates confuse the `ansible-galaxy` command with other Ansible executables like `ansible-playbook` or `ansible-pull`, or assume a non-existent command like `ansible-collection` exists, because the exam tests precise knowledge of which tool handles collection management.

How to eliminate wrong answers

Option A is wrong because `ansible-pull` is used for pulling and applying playbooks from a repository in a reverse mode, not for installing collections; it does not have a `collection install` subcommand. Option B is wrong because `ansible-playbook` is used to execute playbooks, not to manage collections; it has no `collection install` subcommand. Option C is wrong because `ansible-collection` is not a valid Ansible command; the correct utility is `ansible-galaxy`.

289
Matchingmedium

Match each Ansible module to its primary function.

Drag a concept onto its matching description — or click a concept then click the description.

Concepts
Matches

Manage packages via YUM

Copy files to remote hosts

Manage system services

Deploy Jinja2 templates

Manage user accounts

Why these pairings

These modules are commonly used in Ansible for system administration.

290
MCQhard

A playbook uses an Ansible collection that includes a custom module. The module's documentation is missing. What is the best way to locate the module's source code?

A.Run ansible-doc <module name>.
B.Search the Ansible Galaxy website.
C.Navigate to the collection's plugin directory on the control node.
D.Look in the roles directory.
AnswerC

Source code is in the collection's modules subdirectory.

Why this answer

Option D is correct because the source code is in the collection's plugin directory on the control node. Option A may not find it if it's local. Option B may not show source without docs.

Option C is wrong because roles are separate.

291
MCQeasy

An administrator wants to reuse a set of tasks across multiple playbooks. Which Ansible approach is most appropriate?

A.Encrypting the tasks with Ansible Vault.
B.Creating a role with tasks in tasks/main.yml.
C.Using ansible-doc to document the tasks.
D.Writing a custom module in Python.
AnswerB

Correct: Roles encapsulate tasks, variables, handlers, and are designed for reuse across playbooks.

Why this answer

Option B is correct because roles are the standard mechanism for reusable content. Option A is overkill for simple task reuse. Option C is for documentation, not reuse.

Option D is for encryption, not reuse. Therefore, B is correct.

292
MCQeasy

An automation team wants to securely store SSH private keys for use in playbooks. Which Ansible feature should they use?

A.Ansible Collections
B.Ansible Vault
C.Ansible Fact Cache
D.Ansible Galaxy
AnswerB

Ansible Vault encrypts sensitive data.

Why this answer

Ansible Vault is the correct feature for securely storing SSH private keys because it encrypts sensitive data at rest using AES-256, allowing keys to be decrypted at runtime when a vault password or key is provided. This enables playbooks to reference encrypted SSH key files without exposing plaintext credentials in version control or on disk.

Exam trap

The trap here is that candidates might confuse Ansible Vault with Ansible Galaxy, assuming Galaxy provides security features because it is a central repository, but Galaxy only distributes content and has no encryption or secure storage capabilities.

How to eliminate wrong answers

Option A is wrong because Ansible Collections are a distribution format for packaging and sharing automation content (roles, modules, plugins), not a mechanism for encrypting or securing sensitive data like SSH keys. Option C is wrong because Ansible Fact Cache stores gathered system facts (e.g., IP addresses, OS version) in a backend like Redis or Memcached to improve performance, and it does not provide encryption or secure storage for secrets. Option D is wrong because Ansible Galaxy is a public hub for sharing Ansible content (roles, collections) and a command-line tool for downloading them, with no built-in encryption or secure storage capability for SSH private keys.

293
MCQmedium

A playbook uses the 'debug' module to print a variable 'myvar' which is a list of dictionaries. The output shows 'VARIABLE IS UNDEFINED' despite the variable being defined earlier. Which filter issue is most likely?

A.The debug task uses 'var: myvar' instead of 'msg: "{{ myvar }}"'.
B.The playbook uses 'set_fact' with quotes around the variable name.
C.The variable contains a fact that is only available on the control node.
D.The variable is defined in a role but the playbook uses include_role incorrectly.
AnswerD

If the variable is defined inside a role but not exposed to the play, it will be undefined.

Why this answer

Option D is correct because when a variable is defined inside a role but the playbook uses `include_role` incorrectly (e.g., without `tasks_from` or with a static import instead of dynamic include), the variable may not be available in the play's variable scope. The `debug` module then reports 'VARIABLE IS UNDEFINED' because the variable was never loaded into the play's namespace. This is a common scoping issue with role variables and dynamic includes.

Exam trap

The trap here is that candidates often assume any variable defined earlier in the playbook is globally accessible, but Ansible's variable scoping with `include_role` is dynamic and does not automatically propagate role-internal variables to the parent play.

How to eliminate wrong answers

Option A is wrong because using `var: myvar` is the correct way to print a variable with the debug module; `msg: "{{ myvar }}"` would also work but is not a filter issue. Option B is wrong because `set_fact` with quotes around the variable name (e.g., `set_fact: "myvar=..."`) is syntactically valid and does not cause an undefined variable error. Option C is wrong because facts available only on the control node (like `ansible_facts`) are still accessible via `debug` if gathered; the error 'VARIABLE IS UNDEFINED' is not caused by control-node-only facts.

294
Multi-Selecteasy

Which TWO elements can be used to include external task files in a playbook?

Select 2 answers
A.import_tasks
B.include_tasks
C.include_vars
D.add_host
E.include_role
AnswersA, B

import_tasks statically includes a task file.

Why this answer

import_tasks and include_tasks are the two directives to include external task files. import_tasks is static and processed at parse time, while include_tasks is dynamic and processed at runtime.

295
MCQeasy

A user wants to authenticate against Ansible Automation Controller using LDAP. They configure the LDAP settings in the controller UI. After saving, they test the connection and it succeeds. However, when an LDAP user tries to log in, they get an authentication failure. What is the most likely issue?

A.The user is not a member of the required LDAP group that is mapped to a team.
B.The user has not been mapped to an organization within the LDAP configuration.
C.The controller is case-sensitive and the user entered username in wrong case.
D.The LDAP server is configured to use TLS, but the controller uses SAML.
AnswerB

Without organization mapping, the user cannot access the controller.

Why this answer

In Ansible Automation Controller, LDAP users must be explicitly mapped to an organization within the LDAP configuration. Without this mapping, the user is authenticated by the LDAP server but the controller has no authorization context (e.g., organization membership) to allow login. Option B correctly identifies this missing organization mapping as the most likely cause.

Exam trap

The trap here is that candidates assume a successful LDAP connection test implies full authentication and authorization are working, but the test only validates the LDAP bind, not the organization mapping required for user login.

How to eliminate wrong answers

Option A is wrong because group membership mapping to teams is optional and not required for basic LDAP authentication; a user can log in without being in any team. Option C is wrong because while the controller is case-sensitive for usernames, a successful LDAP connection test indicates the LDAP server is reachable and configured correctly, and the authentication failure is more likely due to authorization mapping, not case sensitivity. Option D is wrong because TLS and SAML are unrelated protocols; TLS secures the LDAP connection, while SAML is a separate SSO protocol that would be configured independently, not causing an LDAP authentication failure.

296
Matchingmedium

Match each Ansible fact variable to its description.

Drag a concept onto its matching description — or click a concept then click the description.

Concepts
Matches

Fully qualified domain name

OS family (e.g., RedHat)

Total memory in MB

Number of CPU cores

Default IPv4 interface info

Why these pairings

Common facts gathered by Ansible setup module.

297
MCQmedium

A playbook uses the 'uri' module to query an API and registers the result. The API returns a JSON with a nested field 'data.users[0].name'. Which expression correctly extracts that name?

A.{{ result | json_query('data.users.0.name') }}
B.{{ result | json_query("data.users[0].name") }}
C.{{ result.data.users[0].name }}
D.{{ result | json_query('data.users[0].name') }}
AnswerD

Correct JMESPath expression.

Why this answer

Option D is correct because the `json_query` filter uses JMESPath syntax, which requires dot-separated indices (e.g., `data.users[0].name`) and the query string must be quoted. The `uri` module registers the JSON response as a dictionary, so `result` is the top-level object. The expression `{{ result | json_query('data.users[0].name') }}` correctly applies the JMESPath query to extract the nested field.

Exam trap

Red Hat often tests the distinction between Jinja2 native dot notation (which requires the data to be already parsed into a dictionary) and the `json_query` filter (which uses JMESPath syntax), leading candidates to pick option C when the response is still a raw HTTP object.

How to eliminate wrong answers

Option A is wrong because `json_query` expects a JMESPath expression, and `data.users.0.name` uses a dot before the index `0`, which is invalid JMESPath syntax (indices must be in brackets, e.g., `[0]`). Option B is wrong because the JMESPath query string is enclosed in double quotes inside the Jinja2 template, which can cause parsing issues or be misinterpreted as a string literal; single quotes are the standard for filter arguments. Option C is wrong because `result.data.users[0].name` attempts to access the nested field directly via Jinja2 dot notation, but the `uri` module returns a JSON string that must be parsed into a dictionary first; `result` is the raw response object, not the parsed JSON, so this fails unless `result.json` is used.

298
Multi-Selecteasy

Which TWO methods can be used to limit the hosts that a job template runs against when launching a job? (Choose exactly two.)

Select 2 answers
A.Assigning a specific credential to the job template.
B.Using the 'Tags' field to include only certain tasks.
C.Using the 'LIMIT' field in the job template or at launch time.
D.Selecting a specific group in the 'Jobs' section during launch.
E.Setting the 'Source Control Branch' in the project.
AnswersC, D

This is the primary method to restrict hosts.

Why this answer

Option C is correct because the 'LIMIT' field in Ansible Tower/AWX allows you to restrict the execution of a job template to a specific subset of hosts in the inventory, either by host name, group name, or pattern. This can be set in the job template definition or overridden at launch time, providing flexible targeting without modifying the inventory structure.

Exam trap

The trap here is that candidates confuse the 'Tags' field (which filters tasks within a playbook) with host limiting, or mistakenly think credentials or source control branches affect which hosts are targeted, when in fact only inventory patterns and the 'LIMIT' field control host selection.

299
MCQmedium

An administrator needs to restrict access to an inventory so that only members of the 'WebTeam' can update its host variables and group memberships. Other users should be able to view the inventory but not modify it. Which role-based access control (RBAC) configuration should be applied?

A.Create a job template and assign 'WebTeam' the 'execute' role
B.Make the 'WebTeam' organization administrators and assign others the 'read' role on the organization
C.Assign the 'WebTeam' the 'admin' role on the inventory and others the 'read' role
D.Assign the 'WebTeam' the 'use' role on the inventory and others the 'read' role
AnswerC

Admin role on inventory allows full management; read role allows viewing.

Why this answer

Option C is correct because in Ansible Tower/AWX, the 'admin' role on an inventory grants full update permissions (including host variables and group memberships), while the 'read' role provides view-only access. This directly satisfies the requirement that only WebTeam members can modify the inventory, and others can only view it.

Exam trap

The trap here is confusing the 'use' role with 'write' or 'admin' roles, as candidates often assume 'use' allows modifications, but 'use' only permits associating the inventory with a job template, not editing its contents.

How to eliminate wrong answers

Option A is wrong because a job template with an 'execute' role controls who can run a job, not who can update inventory host variables or group memberships; it does not provide inventory modification permissions. Option B is wrong because making WebTeam organization administrators grants them broad administrative rights across the entire organization, not just the inventory, which violates the principle of least privilege and could allow unintended modifications to other resources. Option D is wrong because the 'use' role on an inventory allows a user to use the inventory in a job template (i.e., associate it with a job), but it does not grant permission to update host variables or group memberships; only 'admin' or 'write' roles provide those modification capabilities.

300
MCQhard

A managed node is not responding to Ansible automation. The administrator verifies that the node is reachable via SSH and that the SSH key is correctly deployed. However, 'ansible all -m ping' fails with 'UNREACHABLE'. The automation controller uses a custom execution environment. What is the most likely cause?

A.The SSH private key has incorrect permissions on the controller.
B.The remote user specified in the credential does not have sudo access.
C.The custom execution environment is missing the 'python3' or 'python' package.
D.The automation controller is behind a firewall that blocks SSH.
AnswerC

Ansible requires Python on the control node (execution environment) to execute modules; missing Python causes unreachable errors.

Why this answer

Option C is correct because the custom execution environment is a container image that must contain the Python interpreter (python3 or python) for Ansible to execute modules on the managed node. When the environment lacks Python, the 'ansible -m ping' module cannot be transferred and executed, resulting in an 'UNREACHABLE' status despite SSH connectivity being verified.

Exam trap

The trap here is that candidates often assume 'UNREACHABLE' always indicates a network or SSH issue, but EX294 tests the understanding that Ansible requires Python on the managed node, and a custom execution environment may lack it, causing a false unreachable status.

How to eliminate wrong answers

Option A is wrong because the administrator verified that the SSH key is correctly deployed, and incorrect permissions on the private key would cause an SSH authentication failure, not an 'UNREACHABLE' status after SSH connectivity is confirmed. Option B is wrong because sudo access is not required for the 'ping' module, which only tests Python availability and does not escalate privileges. Option D is wrong because the administrator verified that the node is reachable via SSH, which would fail if a firewall blocked SSH traffic.

Page 3

Page 4 of 7

Page 5

All pages