Courseiva
Knowledge + Practice
CertificationsVendorsCareer RoadmapsLabs & ToolsStudy GuidesGlossaryPractice Questions
C
Courseiva

Free IT certification practice questions with explained answers for CCNA, CompTIA, AWS, Azure, Google Cloud, and more.

Certification Practice Questions

CCNA practice questionsSecurity+ SY0-701 practice questionsAWS SAA-C03 practice questionsAZ-104 practice questionsAZ-900 practice questionsCLF-C02 practice questionsA+ Core 1 practice questionsGoogle Cloud ACE practice questionsCySA+ CS0-003 practice questionsNetwork+ N10-009 practice questions
View all certifications →

Product

CertificationsCertification PathsExam TopicsPractice TestsExam Dumps vs Practice TestsStudy HubComparisons

Company

AboutContactEditorial PolicyQuestion Writing PolicyTrust Center

Legal

Privacy PolicyTerms of Service

Courseiva is a free IT certification practice platform offering original exam-style practice questions, detailed explanations, topic-based practice, mock exams, readiness tracking, and study analytics for Cisco, CompTIA, Microsoft, AWS, and other technology certifications.

© 2026 Courseiva. Courseiva is operated by JTNetSolutions Ltd. All rights reserved.

Courseiva is an independent certification practice platform and is not affiliated with, endorsed by, or sponsored by Cisco, Microsoft, AWS, CompTIA, Google, ISC2, ISACA, or any other certification vendor. Vendor names and certification marks are used only to identify the exams learners are preparing for.

HomeCertificationsEX294Exam Questions

Red Hat · Free Practice Questions · Last reviewed May 2026

EX294 Exam Questions and Answers

48real exam-style questions organised by domain, each with the correct answer highlighted and a plain-English explanation of why it's right — and why the others are wrong.

240 min time limit
8 exam domains
OverviewDomain BlueprintStudy GuideAll QuestionsSample by Domain
1. Deploy Ansible Automation Platform2. Manage inventories and credentials3. Manage task execution and roles4. Coordinate rolling updates5. Transform data with filters and plugins6. Create content collections and execution environments7. Implement advanced Ansible automation8. Manage automation security and operations
1

Domain 1: Deploy Ansible Automation Platform

All Deploy Ansible Automation Platform questions
Q1
easyFull explanation →

An organization wants to deploy Ansible Automation Platform 2.x in a highly available configuration. Which component must be deployed in an active-active cluster to ensure controller failover?

A

PostgreSQL database

B

Automation controller

The controller runs the web UI, API, and scheduler; an active-active cluster with a load balancer provides HA.

C

Private Automation Hub

D

Automation mesh

Why: The automation controller is the component that provides the web UI, REST API, and job execution management in Ansible Automation Platform 2.x. For high availability, multiple controller nodes must be deployed in an active-active cluster behind a load balancer, ensuring that if one controller fails, another can immediately take over without service interruption.
Q2
hardFull explanation →

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'

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

D

Set 'playbook-artifact enable' to 'true'

Why: 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'.
Q3
mediumFull explanation →

Which TWO statements are true about deploying Red Hat Ansible Automation Platform using the automation mesh?

A

Execution nodes can be located in different geographic regions.

Automation mesh supports distributed execution across multiple sites.

B

Existing Ansible Tower nodes can be added to the mesh without modification.

C

Automation mesh requires two separate ports for control and data plane traffic.

D

The mesh topology is organized as a parent/child relationship between nodes.

Nodes are defined as parents and children, forming a tree-like structure.

E

All execution nodes must have direct network access to the automation controller.

Why: Option A is correct because the automation mesh is designed to support distributed topologies where execution nodes can be located in different geographic regions. The mesh uses peer-to-peer connections over standard TCP ports, allowing nodes to communicate across network boundaries without requiring a centralized controller in each region.
Q4
hardFull explanation →

A systems administrator is deploying Ansible Automation Platform 2.4 using the provided setup script. The installation fails with the error shown in the exhibit. Based on the exhibit, what is the most likely cause of the failure?

A

The installer requires a local PostgreSQL database; using a remote database is not supported.

B

The database password specified in setup.sh does not match the actual PostgreSQL password.

C

SELinux is blocking the ansible-navigator process from reaching the database.

D

The PostgreSQL service is not running on the database server.

The error 'Connection refused' indicates the PostgreSQL server is not listening on the specified host/port.

Why: The error exhibit indicates that the installer cannot connect to the PostgreSQL database. The most common cause of this failure is that the PostgreSQL service is not running on the database server, preventing the Ansible Automation Platform setup script from establishing a connection. Without the database service active, the installer cannot proceed with the deployment.
Q5
mediumFull explanation →

A company is deploying Red Hat Ansible Automation Platform 2.3 in a hybrid cloud environment. The automation controller is installed on a RHEL 8 server in the on-premises data center. Execution nodes are distributed: four in the same data center, two in a remote branch office connected via VPN, and three in AWS EC2 instances. The VPN connection to the branch office is low-bandwidth and high-latency. The AWS nodes use a direct connect with stable bandwidth. During initial testing, playbooks running on the branch office execution nodes frequently timeout or hang, while on-premises and AWS nodes work fine. The automation mesh topology is configured with all nodes as direct children of the controller. The team wants to minimize latency and ensure reliable execution for the branch office nodes. Which course of action should the administrator take?

A

Deploy an additional automation mesh node in the branch office and make the branch office execution nodes children of that node.

A local mesh node reduces WAN traffic by caching playbook artifacts and handling control plane communication locally.

B

Configure the controller to use the AWS execution nodes for all branch office jobs via a proxy.

C

Increase the `ansible_timeout` setting in the controller configuration to 120 seconds.

D

Reduce the forks value for branch office execution nodes to 1.

Why: Option A is correct because deploying an additional automation mesh node in the branch office creates a local parent for the branch office execution nodes, reducing the number of high-latency, low-bandwidth VPN hops between the controller and those nodes. In the automation mesh, parent-child relationships allow execution nodes to connect through a closer intermediary, minimizing timeouts and improving reliability by keeping control-plane traffic local.
Q6
easyFull explanation →

Which TWO statements are true regarding the deployment of Ansible Automation Platform in a highly available configuration?

A

The automation hub requires an external PostgreSQL database to store collections and execution environments.

B

Execution nodes must have direct network access to the automation controller database.

C

The automation controller requires a PostgreSQL database that must be configured with replication for high availability.

Correct: A highly available automation controller requires a highly available PostgreSQL database.

D

The automation controller can use an embedded SQLite database for production deployments.

E

The automation mesh component is used to provide resilient, fault-tolerant execution across multiple nodes.

Correct: The mesh enables distributed execution and can handle node failures.

Why: Option C is correct because the automation controller in Ansible Automation Platform requires a PostgreSQL database, and for high availability (HA), that database must be configured with replication (e.g., streaming replication or Patroni) to ensure failover and data durability. Without database replication, a single database instance becomes a single point of failure, defeating the purpose of an HA deployment.

Want more Deploy Ansible Automation Platform practice?

Practice this domain
2

Domain 2: Manage inventories and credentials

All Manage inventories and credentials questions
Q1
mediumFull explanation →

An administrator needs to store a secret API token in Ansible Automation Controller so that it can be used in job templates without exposing the token in plain text. Which type of credential should be used?

A

Vault credential

B

Machine credential

Machine credentials can store SSH keys or passwords, but not API tokens directly; however, the token can be stored as a custom credential type or secret. This is the closest built-in type.

C

Network credential

D

Cloud credential

Why: Option B is correct because a Machine credential in Ansible Automation Controller is designed to store SSH keys, passwords, and other authentication secrets for remote hosts. It can securely store an API token as a password field, which can then be referenced in job templates without exposing the token in plain text. This aligns with the requirement to store a secret API token for use in automation jobs.
Q2
hardFull explanation →

A team uses Ansible Automation Controller with multiple organizations. Each organization has its own set of machines that require different SSH keys. The administrator wants to ensure that users from one organization cannot use credentials from another organization. What is the best way to achieve this isolation?

A

Create credentials within each organization and assign organization-level access

Credentials belong to an organization, and users from other organizations cannot see them.

B

Store credentials in separate projects and restrict project access

C

Set 'Use' permission on credentials only for specific users

D

Place users in different teams and restrict credential access by team

Why: In Ansible Automation Controller, credentials are scoped to organizations. By creating credentials within each organization and assigning organization-level access, the administrator ensures that credentials are only visible and usable by members of that organization. This leverages the built-in role-based access control (RBAC) that isolates resources by organization, preventing cross-organization credential access.
Q3
easyFull explanation →

An Ansible playbook uses the `ansible_password` variable to connect to a Windows host. The value is stored in an encrypted Ansible Vault file. Which credential type in Automation Controller would allow the vault password to be supplied at runtime?

A

Cloud credential

B

Machine credential

C

Vault credential

Vault credentials provide the vault password to decrypt vault-encrypted files.

D

Network credential

Why: Option C is correct because Automation Controller's Vault credential type is specifically designed to provide the vault password needed to decrypt Ansible Vault-encrypted variables like `ansible_password`. When a job runs, the controller uses this credential to unlock the vault file, allowing the playbook to access the encrypted value at runtime without exposing the plaintext password.
Q4
mediumFull explanation →

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 }}"}

The env dictionary maps credential inputs to environment variables.

Why: 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`.
Q5
easyFull explanation →

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

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

C

Check the vault credential used in the job template

D

Check the project sync status

Why: 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.
Q6
mediumFull explanation →

Which TWO of the following are valid methods to supply a credential password in Ansible Automation Controller?

A

Prompt on launch (ask for credential on job run)

This allows manual entry at runtime.

B

Set the password via an environment variable in the job template

C

Include the password in a file in the project repository

D

Store the password in plain text in the credential definition

E

Use a Vault credential to decrypt vault-encoded password

The vault credential provides the vault password to decrypt the actual password stored in a vault file.

Why: Option A is correct because Ansible Automation Controller allows credentials to be prompted on launch, meaning the user is asked to enter the password at runtime rather than storing it. This is a secure method for sensitive values that should not be persisted in the controller's database or any configuration file.

Want more Manage inventories and credentials practice?

Practice this domain
3

Domain 3: Manage task execution and roles

All Manage task execution and roles questions
Q1
easyFull explanation →

A systems administrator needs to run a playbook that installs packages on a group of managed nodes. The playbook should run only on nodes that are part of the 'web_servers' group in the inventory. Which approach is best practice?

A

Set 'hosts: web_servers' in the play.

Directly targeting the group is the simplest and most readable approach.

B

Set 'hosts: all' and use '--limit web_servers' when running ansible-playbook.

C

Set 'hosts: localhost' and delegate tasks to web_servers.

D

Set 'hosts: all' and use a 'when' condition to check if the node is in the web_servers group.

Why: Option A is correct because setting 'hosts: web_servers' in the play directly targets only the nodes in that inventory group, which is the simplest and most maintainable approach. This follows Ansible's best practice of declaring the target group explicitly in the playbook rather than relying on runtime flags or conditional logic, ensuring the playbook's intent is clear and portable.
Q2
mediumFull explanation →

A team is writing an Ansible role to configure a web server. They want to include default variables that can be easily overridden by playbook variables. Which directory and file should they use to define these variables?

A

vars/defaults.yml

B

defaults/main.yml

This file contains variables with the lowest precedence, allowing easy override.

C

default_vars/main.yml

D

vars/main.yml

Why: In Ansible roles, default variables are defined in the `defaults/main.yml` file. These variables have the lowest precedence, meaning they can be easily overridden by playbook variables, inventory variables, or any other variable source with higher precedence. This design allows role authors to provide sensible defaults while giving users the flexibility to customize behavior without modifying the role itself.
Q3
hardFull explanation →

During a playbook execution, a task that uses the 'ansible.builtin.copy' module fails with 'Permission denied' on a remote host. The playbook runs as user 'ansible' which is a sudoer without password. Which of the following is the most likely cause and solution?

A

The remote path does not exist. Use 'remote_src: yes' to copy from remote.

B

The local source file is not readable by the user running ansible-playbook. Change permissions on the source file.

C

The task lacks 'become: yes' but has 'become_user: root'. Add 'become: yes' to the task.

Without 'become: yes', become_user is ignored; adding 'become: yes' enables privilege escalation.

D

The remote file is owned by root and the destination directory is not writable by ansible. Use 'become: yes' and set 'owner: ansible'.

Why: The 'Permission denied' error occurs because the task attempts to copy a file to a location that requires root privileges, but the playbook does not use privilege escalation. The user 'ansible' is a passwordless sudoer, so adding 'become: yes' to the task enables sudo, granting the necessary permissions to write to the destination. Option C correctly identifies this missing directive.
Q4
mediumFull explanation →

Which TWO statements about Ansible roles are true?

A

A role can include tasks, handlers, variables, templates, and files.

Roles organize these components in a standard structure.

B

Roles are defined directly inside a playbook using the 'roles' keyword.

C

Roles can be reused across multiple playbooks.

Roles are designed for reusability.

D

Roles can only be invoked using the 'include_role' module.

E

Variables defined in a role's vars/main.yml cannot be overridden by playbook variables.

Why: Option A is correct because Ansible roles are designed to organize automation content into a standardized directory structure that can include tasks, handlers, variables, templates, and files. This modular structure allows for better code reuse and maintainability, as each component is stored in its own subdirectory within the role.
Q5
hardFull explanation →

Which THREE are valid methods to control task execution in Ansible?

A

Using the 'when' conditional

'when' controls task execution based on conditions.

B

Using 'block' to group tasks for error handling

Block with rescue/always controls execution flow on errors.

C

Using 'register' to store task output

D

Using 'loop' to iterate over a list

Loop repeats a task for each item in a list.

E

Using the 'with_items' loop

Why: Option A is correct because the 'when' conditional in Ansible allows you to control whether a task runs based on the evaluation of a condition, such as a variable, fact, or the result of a previous task. This is a primary method for conditional execution, enabling tasks to be skipped when the condition is false, directly controlling task execution flow.
Q6
mediumFull explanation →

Refer to the exhibit. The playbook runs successfully. What will the debug task output?

A

Just the username 'jdoe'.

B

A dictionary with details about the user, such as uid, gid, and groups.

The user module returns a dictionary with user attributes.

C

The entire playbook YAML structure.

D

The string 'true' if the user was created successfully.

Why: The debug task outputs the registered variable from the user module. By default, the user module returns a dictionary containing user account details such as uid, gid, groups, and home directory when the state is 'present'. Since the playbook runs successfully, the registered variable holds this dictionary, making option B correct.

Want more Manage task execution and roles practice?

Practice this domain
4

Domain 4: Coordinate rolling updates

All Coordinate rolling updates questions
Q1
mediumFull explanation →

A company uses Ansible to manage rolling updates of a web server fleet. During a deployment, the playbook fails on one host due to a transient network error, and the rest of the fleet is left in an inconsistent state. Which strategy would best minimize the risk of inconsistency in future rolling updates?

A

Add retries to each task so transient errors are automatically retried.

B

Use a larger serial batch size to complete the rollout faster.

C

Set ignore_errors: yes on all tasks to continue despite failures.

D

Set max_fail_percentage to 0 in the serial block to abort the rollout on any failure.

max_fail_percentage aborts the playbook if failure rate exceeds threshold, preventing inconsistency.

Why: Option D is correct because setting `max_fail_percentage: 0` in a rolling update (using `serial`) tells Ansible to abort the entire playbook run if any single host fails. This prevents the rest of the fleet from being updated, avoiding an inconsistent state where some hosts have the new deployment and others do not. It directly addresses the risk of partial rollouts caused by transient errors.
Q2
hardFull explanation →

An operations team is designing a rolling update for a stateful application that requires quorum (minimum 3 out of 5 nodes online). They plan to use Ansible's serial keyword. Which serial value ensures the update proceeds without breaking quorum while still being efficient?

A

serial: 2

Updating 2 nodes leaves 3 online, maintaining quorum, and is efficient.

B

serial: 1

C

serial: 3

D

serial: 5

Why: Option A is correct because setting serial: 2 ensures that only 2 nodes are taken down at a time during the rolling update. With a quorum requirement of 3 out of 5 nodes, taking down 2 nodes leaves 3 online, maintaining quorum. This is the most efficient value that does not risk breaking quorum.
Q3
easyFull explanation →

Which TWO options are best practices for coordinating rolling updates with Ansible? (Choose exactly two.)

A

Set ignore_errors: yes to ensure the playbook continues even if some hosts fail.

B

Use the serial keyword to update hosts in batches.

serial enables batching, which is the core of rolling updates.

C

Use the default serial setting (all hosts) for simplicity.

D

Set max_fail_percentage to limit the number of failed hosts before aborting.

max_fail_percentage provides a safety threshold to abort on excessive failures.

E

Run all hosts in parallel to minimize total update time.

Why: Option B is correct because the `serial` keyword in Ansible controls how many hosts are updated at a time during a rolling update, allowing you to update hosts in batches to maintain service availability. This is a best practice for coordinating rolling updates as it prevents overwhelming the infrastructure and ensures that a subset of hosts remains operational while others are being updated.
Q4
mediumFull explanation →

Refer to the exhibit. The playbook uses serial: 1 (one host at a time). The update failed on web3.example.com. Based on the output, what is the most likely reason the play did not abort the rollout and how should the playbook be modified to stop on failure?

A

Add retries: 3 to the 'Update Apache config' task.

B

Set ignore_errors: yes on the 'Update Apache config' task.

C

Add max_fail_percentage: 0 to the play to abort on any failure.

max_fail_percentage: 0 aborts the play if any host fails, preventing inconsistent state.

D

Increase the serial value to update multiple hosts at once.

Why: Option C is correct because the play uses `serial: 1` to update one host at a time, but by default Ansible continues to the next host even if a task fails on the current host. Setting `max_fail_percentage: 0` at the play level tells Ansible to abort the entire play immediately if any host fails, which is the intended behavior for a rolling update where a single failure should stop the rollout.
Q5
hardFull explanation →

You are managing a rolling update of a 10-node web application cluster using Ansible. The application requires that at least 8 nodes remain available during the update to handle traffic. You have written a playbook that uses serial: 2 (updates 2 nodes at a time). During a test run, the playbook updates the first batch of 2 nodes successfully, but when it proceeds to the second batch, one of the nodes fails to restart the web service. However, the playbook continues and updates the remaining nodes. At the end, only 7 nodes are healthy, causing performance degradation. You need to ensure that if a batch fails to meet the minimum health requirements, the entire rollout is stopped and no further updates are applied. Which course of action should you take?

A

Add a retry loop to the service restart task with a delay and count of 5.

B

Set ignore_errors: yes on the service restart task to avoid failures stopping the playbook.

C

Use the 'throttle' keyword with a rolling update strategy that includes a post-task health check and set max_fail_percentage to a value that aborts if the healthy node count drops below 8.

throttle and max_fail_percentage combined can enforce health thresholds and abort the rollout when conditions are not met.

D

Increase serial to 3 to complete the update faster and reduce the chance of node failures.

Why: Option C is correct because it uses the `throttle` keyword with a rolling update strategy that includes a post-task health check and sets `max_fail_percentage` to abort the playbook if the healthy node count drops below 8. This ensures that if a batch fails to meet the minimum health requirements, the entire rollout is stopped and no further updates are applied, preventing performance degradation.
Q6
mediumFull explanation →

An Ansible Engineer is planning a rolling update for a web application deployed across 10 nodes. The playbook uses the 'delegate_to' directive to manage load balancer health checks. Which of the following best describes the recommended approach to minimize downtime?

A

Use 'serial: 1' and delegate load balancer disable/enable tasks to localhost, ensuring each node is taken out of rotation before updating.

This ensures each node is removed from the load balancer, updated, and then re-added, minimizing downtime.

B

Run the update playbook with 'serial: 10' to update all nodes at once, then run a separate playbook to update the load balancer.

C

Run the update on each node manually using 'ansible-playbook --limit' and skip load balancer management to save time.

D

Use 'strategy: free' to allow nodes to update independently without controlling the load balancer.

Why: Option A is correct because using 'serial: 1' ensures that only one node is updated at a time, and delegating load balancer disable/enable tasks to localhost (or the Ansible control node) allows the playbook to interact with the load balancer API to remove the node from the pool before the update and re-add it after. This minimizes downtime by ensuring traffic is not sent to a node being updated, while other nodes continue serving requests.

Want more Coordinate rolling updates practice?

Practice this domain
5

Domain 5: Transform data with filters and plugins

All Transform data with filters and plugins questions
Q1
easyFull explanation →

An Ansible playbook needs to extract the first line from a multi-line string variable 'output' and store it in a new variable 'first_line'. Which filter should be used?

A

{{ output | lines | first }}

B

{{ output | split(' ') | first }}

Correct: split into lines then take first.

C

{{ output | first }}

D

{{ output | head(1) }}

Why: Option B is correct because the `split('\n')` filter splits the multi-line string into a list of lines, and the `first` filter extracts the first element. This is the standard Ansible approach to isolate the first line from a string variable.
Q2
mediumFull explanation →

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') }}

Correct JMESPath expression.

Why: 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.
Q3
hardFull explanation →

A team is migrating from static inventory to dynamic inventory using a custom script. The script returns JSON with a group 'webservers' containing hosts. However, the playbook targeting 'webservers' fails with 'no hosts matched'. Which filter or plugin issue is most likely?

A

The playbook uses 'hosts: all' but should use 'hosts: webservers'.

B

The script is not executable.

C

The 'ansible_host' variable is not set in hostvars.

D

The script output is missing the '_meta' key with 'hostvars'.

Dynamic inventory scripts require _meta structure; without it, Ansible may not recognize hosts.

Why: Dynamic inventory scripts must include a `_meta` key with `hostvars` in their JSON output for Ansible to properly resolve host variables and match hosts to groups. Without `_meta`, Ansible cannot associate host-specific variables (like `ansible_host`) with the hosts listed under `webservers`, causing the playbook to see no matched hosts even though the group exists.
Q4
easyFull explanation →

A playbook needs to set a fact 'total_memory' by summing the 'memory_mb' values from a list of servers. Which filter should be used?

A

{{ servers | map(attribute='memory_mb') | sum }}

Correct: map attribute then sum.

B

{{ servers | map('memory_mb') | sum }}

C

{{ servers | sum }}

D

{{ servers | sum(attribute='memory_mb') }}

Why: Option A is correct because it uses the `map` filter with the `attribute` parameter to extract the `memory_mb` value from each dictionary in the list, then pipes the resulting list of integers into the `sum` filter to compute the total. This is the standard Ansible idiom for summing a specific attribute across a list of dictionaries.
Q5
mediumFull explanation →

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.

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

Why: 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.
Q6
mediumFull explanation →

Which TWO filters are used to transform data types in Ansible?

A

list

B

bool

Converts to boolean.

C

float

D

string

E

int

Converts to integer.

Why: In Ansible, the `bool` and `int` filters are specifically designed to convert input values into boolean and integer data types, respectively. These are part of Ansible's Jinja2 filter set for explicit type coercion, enabling tasks to handle variables with the correct data type for conditional logic or arithmetic operations.

Want more Transform data with filters and plugins practice?

Practice this domain
6

Domain 6: Create content collections and execution environments

All Create content collections and execution environments questions
Q1
hardFull explanation →

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

Standard Ansible Galaxy naming convention for collections.

Why: 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.
Q2
mediumFull explanation →

When building an execution environment with ansible-builder, a developer notices that the build process fails with an error about missing dependencies. The developer wants to ensure all required Python packages are installed in the execution environment. Which file should be used to specify additional Python packages?

A

meta/runtime.yml

B

galaxy.yml

C

bindep.txt

D

requirements.txt

Standard file for Python dependencies in execution environments.

Why: In Ansible Builder, the `requirements.txt` file is used to specify additional Python packages that should be installed in the execution environment. When building an execution environment, Ansible Builder reads this file and installs the listed packages via pip, ensuring all required Python dependencies are present.
Q3
easyFull explanation →

A system administrator wants to publish a custom Ansible collection to a private Automation Hub. What is the correct command to build the collection before publishing?

A

ansible-galaxy collection init mycollection

B

ansible-galaxy collection publish ./mycollection-1.0.0.tar.gz

C

ansible-galaxy collection install .

D

ansible-galaxy collection build

Builds a collection tarball from the current directory.

Why: Option D is correct because `ansible-galaxy collection build` is the command that compiles the collection directory into a distributable tarball (e.g., `mycollection-1.0.0.tar.gz`), which is the required artifact for publishing to a private Automation Hub. Without this build step, there is no archive to upload.
Q4
mediumFull explanation →

An organization uses custom Ansible plugins stored in a collection. A junior admin reports that after updating the collection to version 2.0.0, a playbook that uses a custom filter plugin fails with 'undefined filter'. What is the most likely cause?

A

The playbook uses an outdated syntax that is incompatible with the new collection.

B

The filter plugin was placed in the wrong directory inside the collection.

Filter plugins must reside in plugins/filter/ directory.

C

The playbook does not use the fully qualified collection name (FQCN) for the filter.

D

The collection's metadata file galaxy.yml is missing a dependency declaration.

Why: In Ansible collections, filter plugins must reside in the `plugins/filter/` directory within the collection structure. If the plugin is placed in the wrong directory (e.g., `plugins/modules/` or `plugins/lookup/`), Ansible will not load it as a filter, resulting in an 'undefined filter' error. The collection update to version 2.0.0 likely reorganized the directory structure, causing the filter to be misplaced.
Q5
hardFull explanation →

A DevOps engineer is creating an execution environment for a team that needs both Ansible and the 'requests' Python library. The engineer creates an execution environment definition file (EE.yml) with the following content: --- version: 3 images: base_image: name: registry.redhat.io/ansible-automation-platform-22/ee-minimal-rhel8:latest options: package_manager_path: /usr/bin/microdnf dependencies: python: requirements.txt system: bindep.txt

What is missing from this definition to ensure the 'requests' library is installed?

A

The package_manager_path should be /usr/bin/yum.

B

The requirements.txt file must contain 'requests'.

The requirements.txt file is referenced but the content is not shown; it must list requests.

C

The galaxy.yml file must be added to the dependencies section.

D

The base image should be ee-supported-rhel8 instead.

Why: The execution environment definition file (EE.yml) specifies dependencies via external files like requirements.txt for Python packages. To install the 'requests' library, the requirements.txt file must explicitly list 'requests' as a dependency. Without it, the build process will not include the library, regardless of other configuration options.
Q6
hardFull explanation →

Which TWO statements about Ansible content collections are correct?

A

Collections can be installed only from Galaxy.

B

The collection name must be a single word without namespace.

C

Collections can be distributed via Automation Hub or Galaxy.

Both are valid distribution platforms for collections.

D

A collection can contain only roles and playbooks.

E

A collection must have a galaxy.yml file in its root directory.

galaxy.yml is required for metadata.

Why: Option C is correct because Ansible content collections can be distributed via either Red Hat Automation Hub (for certified collections) or Ansible Galaxy (for community collections). This dual distribution model allows organizations to use curated, supported content from Automation Hub while also leveraging community-contributed collections from Galaxy.

Want more Create content collections and execution environments practice?

Practice this domain
7

Domain 7: Implement advanced Ansible automation

All Implement advanced Ansible automation questions
Q1
mediumFull explanation →

An Ansible playbook fails intermittently when deploying web servers. The error message indicates that a required package is not available in the repository. Which approach would best ensure that the required packages are consistently available before the playbook runs?

A

Set 'ignore_errors: yes' on the package installation task and handle the failure later.

B

Add retries and delay to the package installation task.

C

Add a pre_task to run 'dnf update' or 'apt update' before the package installation.

Updating the repository cache ensures the latest package metadata is available.

D

Use the 'get_url' module to download the package from an external source and install it manually.

Why: Option C is correct because the intermittent failure is caused by the package metadata cache being stale or missing. Running 'dnf update' (RHEL/CentOS) or 'apt update' (Debian/Ubuntu) as a pre_task refreshes the repository index, ensuring that the package manager has the latest list of available packages before attempting installation. This directly resolves the 'package not available' error by synchronizing the local cache with the remote repository.
Q2
easyFull explanation →

An administrator wants to reuse a set of tasks that configure a firewall across multiple playbooks. Which Ansible feature should be used to achieve this?

A

Create a role for firewall configuration.

Roles are the standard way to package reusable content.

B

Add the tasks to the inventory file under a group.

C

Define the tasks in a vars file and include it.

D

Define the tasks as handlers and notify them.

Why: A role is the correct Ansible feature for reusing a set of tasks across multiple playbooks. Roles provide a structured, self-contained directory layout for tasks, handlers, variables, templates, and files, allowing the firewall configuration logic to be packaged once and referenced in any playbook via the `roles:` directive or `import_role`/`include_role` modules.
Q3
hardFull explanation →

A playbook uses the 'include_tasks' module to dynamically include tasks based on a variable. The playbook runs successfully on some hosts but fails on others with a 'template error' message. What is the most likely cause?

A

The included task file does not exist on the control node.

B

The variable used in the 'include_tasks' path has a Jinja2 template error.

Template errors occur when Jinja2 syntax is invalid.

C

The included task file has incorrect permissions.

D

The included tasks contain a syntax error.

Why: The 'include_tasks' module dynamically resolves the path to a task file using a variable. If that variable contains a Jinja2 template error (e.g., undefined variable, syntax mistake, or filter misuse), Ansible will fail with a 'template error' message during the variable expansion phase, before the task file is even loaded. This explains why the error occurs only on hosts where the variable's value or context triggers the template failure.
Q4
easyFull explanation →

An Ansible playbook is designed to run on a group of database servers. The administrator wants to ensure that a task runs only on the primary database server, which is defined in the inventory with a variable 'primary: true'. Which conditional should be used?

A

ignore_errors: yes

B

when: primary

The when clause evaluates to true if the variable is truthy.

C

run_once: true

D

delegate_to: "{{ primary }}"

Why: Option B is correct because the `when` conditional in Ansible evaluates a Jinja2 expression to determine whether a task should execute. By using `when: primary`, the task will run only on hosts where the inventory variable `primary` is defined and evaluates to `true` (a truthy value). This directly meets the requirement to target the primary database server.
Q5
mediumFull explanation →

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.

Rescue is executed when any task in the block fails.

C

The playbook fails with an error message.

D

The remaining tasks in the block run, then the rescue section runs.

Why: 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.
Q6
hardFull explanation →

An administrator needs to securely pass a database password to a playbook without exposing it in logs or the command line. Which approach is the most secure?

A

Store the password in an Ansible Vault-encrypted variable file and include it.

Vault encrypts the data, and the vault password is prompted or provided via a vault password file.

B

Set the password in a variable and use 'no_log: true' on tasks that use it.

C

Store the password in a host_vars file with restricted file permissions.

D

Prompt for the password and pass it as an extra variable using -e.

Why: Option A is correct because Ansible Vault encrypts the variable file at rest, and including it via `vars_files` or `include_vars` decrypts it only in memory during playbook execution. This prevents the password from appearing in logs, the command line, or the process table, meeting the security requirement.

Want more Implement advanced Ansible automation practice?

Practice this domain
8

Domain 8: Manage automation security and operations

All Manage automation security and operations questions
Q1
mediumFull explanation →

An Ansible automation controller job template uses a custom credential type that requires a secret token. The token is stored as an extra variable in the job template definition. A security audit reveals the token is visible in plaintext in the job output. Which action should the administrator take to secure the secret?

A

Define the variable in the job template's 'extra variables' field with 'no_log: true' set in the playbook for that variable.

Setting no_log on the variable prevents it from being displayed in logs and job output, meeting the security requirement.

B

Vault-encrypt the variable in the playbook and reference it with {{ vault_var }}.

C

Create a custom credential type that injects the token as an environment variable, and remove the extra variable from the job template.

D

Store the token in a file on the controller with 600 permissions and use 'lookup' in the playbook.

Why: Option A is correct because setting `no_log: true` on the variable in the playbook prevents Ansible from printing the value of that variable in any output, including job logs. This is the standard method to hide sensitive data like tokens when they are passed as extra variables, as it works at the task level to suppress logging of the variable's content.
Q2
hardFull explanation →

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.

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

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.

Why: 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.
Q3
easyFull explanation →

An organization requires that all Ansible playbooks be executed using a specific service account that has limited permissions. The account can only run playbooks from a specific directory. Which approach best enforces this requirement in automation controller?

A

Use an inventory that contains only the allowed hosts.

B

Configure an execution environment that mounts the authorized directory as read-only.

C

Create a project that syncs only the authorized directory, and assign the service account as the only user with execute permissions on that project.

Projects control source of playbooks; RBAC can restrict execution to that project.

D

Assign the service account a machine credential that connects to the controller via SSH.

Why: Option C is correct because Automation Controller (formerly Ansible Tower) uses Projects to manage playbook source code. By creating a Project that syncs only the authorized directory and assigning the service account as the only user with execute permissions on that Project, you restrict the service account to running playbooks exclusively from that directory. This enforces the requirement at the platform level, leveraging role-based access control (RBAC) within the controller.
Q4
hardFull explanation →

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.

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

D

The automation controller is behind a firewall that blocks SSH.

Why: 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.
Q5
mediumFull explanation →

An Ansible playbook uses 'become: yes' to install packages. The playbook works when run manually by the administrator but fails when run from automation controller with 'Missing sudo password'. The administrator has configured a machine credential with the SSH key and the 'Become password' field is blank. What is the most likely issue?

A

The machine credential does not include the become password.

The become password must be supplied in the credential's 'Become password' field when the remote user requires a password for privilege escalation.

B

The become method is set to 'su' instead of 'sudo'.

C

The remote user is not in the sudoers file.

D

The SSH private key is not loaded into the automation controller.

Why: The playbook uses 'become: yes' to escalate privileges, which requires a become password when the remote user's sudo configuration demands password authentication. Since the machine credential's 'Become password' field is blank, Automation Controller cannot supply the password during the privilege escalation step, causing the 'Missing sudo password' error. The administrator's manual run succeeds because the SSH session can prompt interactively for the password, but Automation Controller's non-interactive execution requires the password to be pre-configured in the credential.
Q6
mediumFull explanation →

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.)

A

Set 'no_log: true' on tasks that handle sensitive data.

This prevents the output of those tasks from being displayed.

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.

This prevents task arguments from being displayed, which may contain sensitive values.

E

Use 'tags: never' on sensitive tasks.

Why: 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.

Want more Manage automation security and operations practice?

Practice this domain

Frequently asked questions

How many questions are on the EX294 exam?

The EX294 exam is performance-based — there are no multiple-choice questions. It is a hands-on lab exam completed within 240 minutes. You complete practical tasks in a live or simulated environment. Courseiva practice questions cover the underlying concepts.

What types of questions appear on the EX294 exam?

Hands-on automation tasks using Ansible in a live RHEL environment.

How are EX294 questions organised by domain?

The exam covers 8 domains: Deploy Ansible Automation Platform, Manage inventories and credentials, Manage task execution and roles, Coordinate rolling updates, Transform data with filters and plugins, Create content collections and execution environments, Implement advanced Ansible automation, Manage automation security and operations. Questions are weighted by domain — higher-weight domains appear more on your actual exam.

Are these the actual EX294 exam questions?

No. These are original exam-style practice questions written against the official Red Hat EX294 exam objectives. They are not copied from the real exam. Courseiva focuses on genuine understanding, not memorisation of braindumps.

Ready to practice EX294?

Courseiva tracks your accuracy per domain and routes you toward weak areas automatically. Free, no account required.

Browse all EX294 questionsTake a timed practice test