Courseiva

Red Hat Certified Engineer EX294 (EX294) — Questions 76–150

392 questions total · 6pages · All types, answers revealed

Page 1

Page 2 of 6

Page 3
76
Multi-Selectmedium

Which THREE features are provided by Ansible's filter plugins? (Select exactly three.)

Select 3 answers
A.Defining new Ansible modules
B.Data transformation (e.g., format dates, modify strings)
C.Accepting arguments to customize behavior
D.Chaining multiple filters in a pipeline
E.Fetching data from external APIs
AnswersB, C, D

Core purpose of filters.

Why this answer

Filter plugins in Ansible are used to transform data within Jinja2 templates. Option B is correct because filters like `| date`, `| regex_replace`, and `| upper` directly perform data transformation tasks such as formatting dates and modifying strings, which is a core purpose of filter plugins.

Exam trap

The trap here is that candidates confuse filter plugins with lookup plugins or modules, mistakenly thinking filters can fetch external data or define new modules, when in fact filters are strictly for in-memory data transformation within Jinja2 expressions.

77
MCQhard

An administrator is migrating playbooks to use execution environments in automation controller. They want to ensure that all playbook runs use a custom execution environment that includes the necessary Python libraries and is signed to comply with security policy. What should the administrator do?

A.Build the execution environment using ansible-builder and then push it to a private registry and reference it in the automation controller.
B.Push the custom execution environment to the default namespace and assign it to job templates.
C.Use the default execution environment and install Python libraries via the playbook.
D.Define the execution environment in the project repository and use a pre-run hook.
AnswerA

Building with ansible-builder bundles the required Python libraries into a container image, satisfying the dependency constraint, while pushing to a private registry and referencing it in automation controller ensures every playbook run pulls that signed, policy-compliant execution environment rather than the default image.

Why this answer

The administrator must build a custom execution environment using `ansible-builder`, which packages the required Python libraries and Ansible content into a container image. This image must then be pushed to a private registry (e.g., Quay.io or Red Hat Registry) and referenced in automation controller's execution environment configuration. Additionally, signing the image (e.g., via Podman or Skopeo) ensures compliance with security policies by verifying image integrity before execution.

Exam trap

The trap here is that candidates may think they can install Python libraries dynamically via a playbook (Option C) or use a project-level definition (Option D), but the exam tests the understanding that execution environments are immutable container images built externally and referenced by registry path.

How to eliminate wrong answers

Option B is wrong because pushing the custom execution environment to the 'default namespace' is not a valid concept in automation controller; execution environments are referenced by their full registry path and tag, not by namespace assignment. Option C is wrong because using the default execution environment and installing Python libraries via a playbook violates the purpose of execution environments, which are meant to provide immutable, pre-packaged dependencies; runtime installation also breaks security policy and reproducibility. Option D is wrong because defining the execution environment in the project repository is not supported; execution environments are configured at the job template or global level in automation controller, and 'pre-run hooks' are not a mechanism for specifying execution environments.

78
MCQhard

Refer to the exhibit. An administrator deployed this configuration using the controller_configuration role. After deployment, user jdoe can administer Engineering organization but cannot launch a job template within it. What is the most likely reason?

A.The admin role for organization does not include job template launch permissions
B.The user's password is vault-encrypted and cannot be decrypted
C.The user needs to be added to the job template's role specifically
D.The role assignment should be at the team level, not user level
AnswerC

Job templates carry their own role-based access control, separate from organisation-level roles. Administering the Engineering organisation grants no execute permission on its templates, so jdoe must be assigned an execute role on the specific job template to launch it.

Why this answer

In Ansible Tower/AWX, organization-level admin roles grant administrative privileges over the organization's objects (e.g., users, teams, inventories) but do not automatically confer execute permissions on specific job templates. To launch a job template, a user must have the 'execute' role on that job template itself, either directly or via a team or user role assignment. Since user jdoe can administer the Engineering organization but cannot launch a job template, the missing piece is the explicit job template role assignment.

Exam trap

Red Hat often tests the misconception that an organization admin role automatically includes all permissions on objects within the organization, when in fact job template execution requires a separate explicit role assignment.

How to eliminate wrong answers

Option A is wrong because the admin role for an organization does include the ability to manage job templates (create, modify, delete) but does not include the 'execute' permission; the question is about launching (executing) a job template, not managing it. Option B is wrong because vault-encrypted passwords are decrypted at runtime by Ansible Tower using the vault password; if the password could not be decrypted, the user would not be able to log in at all, not just fail to launch a job template. Option D is wrong because role assignments can be made at the user level as well as the team level; the issue is not the level of assignment but the specific role (execute) that is missing.

79
Multi-Selecteasy

Which two statements are true regarding Ansible roles? (Choose two.)

Select 2 answers
A.Role handlers are shared across all roles in the play.
B.A role can have a meta/main.yml file to define dependencies.
C.Role variables in vars/main.yml can be overridden by playbook vars.
D.Role default variables in defaults/main.yml have the lowest priority.
E.Roles can only be used in a playbook's roles section.
AnswersB, D

The meta/main.yml file within a role directory accepts a dependencies list, letting Ansible resolve and run prerequisite roles before the role's own tasks. This satisfies the scenario's need to declare role dependencies in a structured, supported location.

Why this answer

Option B is correct because a role's meta/main.yml file is exactly where role dependencies are declared under the dependencies key, allowing Ansible to automatically pull in and run other roles before the current one. Option D is correct because variables defined in defaults/main.yml have the lowest precedence in Ansible's variable hierarchy, meaning almost any other variable source (inventory, play vars, role vars, extra vars, etc.) will override them. Option A is wrong because handlers are scoped to the role or play that defines them, not shared globally across all roles.

Option C is wrong because vars/main.yml role variables have higher precedence than playbook vars, so playbook vars cannot override them. Option E is wrong because roles can also be included dynamically with include_role or imported with import_role, not only via the roles section.

Exam trap

The trap here is that candidates often confuse the priority of role variables (vars/main.yml) with default variables (defaults/main.yml), mistakenly thinking playbook vars can override role vars, when in fact defaults have the lowest priority and role vars are higher than playbook vars.

80
Multi-Selecthard

An administrator needs to ensure that a set of tasks runs only when a specific condition is met, and that the tasks are skipped without error otherwise. The condition depends on a variable that may be undefined. Which TWO approaches will safely evaluate the condition without causing an undefined variable error? (Choose two.)

Select 2 answers
A.Use the 'when' keyword with the 'is defined' test, such as "when: my_var is defined and my_var == 'value'".
B.Use the 'ignore_errors' keyword on the task and check the variable in a subsequent task.
C.Use the 'failed_when' keyword to define a custom failure condition based on the variable.
D.Use the 'when' keyword with the 'default' filter, such as "when: my_var | default(false)".
E.Use the 'when' keyword with the variable directly, such as "when: my_var == 'value'".
AnswersA, D

The 'is defined' test checks whether a variable exists before evaluating it. By combining it with 'and', the second part of the condition is only evaluated if the variable is defined, preventing an undefined variable error. This is a standard pattern for safely referencing potentially undefined variables in conditions.

Why this answer

Both the default filter and the 'is defined' test allow safe evaluation of potentially undefined variables in when conditions. The default filter supplies a fallback value, while 'is defined' short-circuits the condition to avoid evaluating the variable if it does not exist. Either approach prevents undefined variable errors and ensures tasks are skipped cleanly.

Exam trap

The trap here is assuming that Ansible treats undefined variables as false in when conditions, but it actually raises an error unless you explicitly guard against undefined values.

81
Multi-Selecteasy

Which TWO filters are commonly used to transform strings in Ansible? (Select exactly two.)

Select 2 answers
A.regex_replace
B.items2dict
C.flatten
D.trim
E.dict2items
AnswersA, D

regex_replace substitutes regex patterns.

Why this answer

`regex_replace` is a built-in Jinja2 filter in Ansible that allows you to transform strings by replacing substrings that match a regular expression pattern. This is commonly used for string manipulation tasks such as sanitizing user input or formatting output.

Exam trap

The trap here is that candidates may confuse filters that manipulate data structures (like `items2dict`, `flatten`, `dict2items`) with filters that transform strings, leading them to select options that are valid Ansible filters but not applicable to string transformation.

82
MCQmedium

You are performing a rolling update on a 5-node application cluster using an Ansible playbook with `serial: 1`. The playbook includes a task that uses the `uri` module to check the application health endpoint after each node is updated. The health check must wait until the application returns HTTP 200 before proceeding to the next node. Which approach ensures that the playbook waits for the health check to succeed before moving to the next host?

A.Use the wait_for module with the host and port parameters to wait for the application to start listening.
B.Use the uri module with the status_code parameter set to 200 and register the result, then use a wait_for condition on the result.
C.Use the pause module to wait for a fixed amount of time after updating each node.
D.Use the uri module with retries and until to repeatedly check the endpoint until it returns HTTP 200.
AnswerD

The uri module can be used with retries and until to poll the health endpoint until it returns the desired status code. This ensures that the playbook waits for the application to become healthy before proceeding to the next host, which is essential for a safe rolling update.

Why this answer

To ensure the playbook waits for the application to become healthy after each node update, you should use the uri module with retries and until. This combination repeatedly polls the health endpoint until it returns HTTP 200 or the retries are exhausted. This approach is reliable and ensures that the application is ready before proceeding to the next node in the rolling update.

Exam trap

The trap here is assuming that the wait_for module can check HTTP responses, but it is designed for files, ports, or conditions, not HTTP status codes.

83
MCQmedium

You are developing a content collection and need to include a custom Ansible module that requires a specific Python library. The library is not available as a system package and must be installed via pip. Where should you declare this Python dependency so that it is automatically installed when the collection is used in an execution environment?

A.In the galaxy.yml file under the dependencies key, specifying the Python package name.
B.In the module file itself, using a try/except ImportError block to install the library at runtime.
C.In the requirements.txt file within the collection root.
D.In the execution-environment.yml file under the dependencies section with the python option.
AnswerD

The execution-environment.yml file allows you to specify Python packages under the dependencies section using the python key. This tells ansible-builder to install those packages via pip during the execution environment build. This is the correct place to declare Python library dependencies for collections used in the execution environment.

Why this answer

When building an execution environment, Python dependencies can be declared in the execution-environment.yml file under the dependencies section with the python key. This instructs ansible-builder to install the specified Python packages via pip into the execution environment, making them available to modules and plugins that require them.

Exam trap

The trap here is assuming that Python dependencies for a collection can be declared in galaxy.yml or requirements.txt, when in fact the execution environment definition is the correct place for build-time installation.

84
Multi-Selecthard

Which TWO statements about Ansible role defaults are true?

Select 2 answers
A.Defaults are only loaded if no vars are defined.
B.Defaults are loaded from the defaults/main.yml file.
C.Defaults have higher priority than variables defined in the playbook.
D.Defaults cannot be overridden.
E.Defaults have the lowest priority of all variables.
AnswersB, E

Defaults are loaded from `defaults/main.yml` within a role's directory structure, giving them the lowest precedence of any role variable. This satisfies the scenario's requirement by ensuring these values are easily overridden by inventory variables, playbook vars, or `--extra-vars`, making roles reusable across environments without editing role files.

Why this answer

Option B is correct because Ansible automatically loads role default variables from the defaults/main.yml file inside the role's directory structure, making it the standard location for defining fallback values. Option E is correct because defaults have the lowest precedence in Ansible's variable priority hierarchy, meaning nearly any other variable source (inventory vars, play vars, host vars, extra vars, etc.) will override them. Option A is incorrect because defaults are always loaded, not conditionally based on whether other vars exist; they simply get overridden when higher-priority variables are present.

Option C is incorrect because defaults have lower priority than playbook vars, not higher. Option D is incorrect because defaults are specifically designed to be easily overridden by higher-precedence variable sources.

Exam trap

The EX294 exam often tests the distinction between role defaults and role vars, where candidates mistakenly think defaults have higher priority or cannot be overridden, but in reality defaults are the lowest priority and designed to be overridden by any other variable source.

85
MCQmedium

An organization uses a private automation hub to distribute collections. A developer has created a new collection and needs to ensure it is available in the hub for others. Which command should the developer use to upload the collection to the private automation hub?

A.ansible-galaxy collection import
B.ansible-galaxy collection build
C.ansible-galaxy collection publish
D.ansible-galaxy collection install
AnswerC

`ansible-galaxy collection publish` uploads a built collection tarball to a Galaxy-compatible repository, satisfying the requirement to distribute it via the private automation hub. It authenticates using the API token configured in `ansible.cfg` or passed with `--api-key`, then pushes the artefact so other developers can install it.

Why this answer

`ansible-galaxy collection publish` is the command specifically designed to upload a built collection artifact (a .tar.gz file) to a Galaxy server, including a private automation hub. This command sends the collection to the configured Galaxy server endpoint, making it available for others to install via `ansible-galaxy collection install`.

Exam trap

The trap here is that candidates confuse `build` (which only creates the artifact) with `publish` (which uploads it), or they mistakenly think `import` is the correct command for uploading a built artifact, when in fact `import` is for source-based imports from a repository.

How to eliminate wrong answers

Option A is wrong because `ansible-galaxy collection import` is used to import a collection from a Git repository or a source distribution into a Galaxy server, but it is not the command for uploading a pre-built collection artifact; it expects a source repository URL or a path to a source directory, not a built .tar.gz file. Option B is wrong because `ansible-galaxy collection build` creates the collection artifact (a .tar.gz file) from the collection source files, but it does not upload or publish it to any server; it only produces the local artifact. Option D is wrong because `ansible-galaxy collection install` downloads and installs a collection from a Galaxy server or a local path, but it does not upload or publish collections to a hub.

86
MCQhard

An automation controller administrator needs to allow a team of developers to run playbooks that use a vault-encrypted variable file. The vault password must not be stored in the playbook repository or exposed in job output. Which approach meets the requirement?

A.Configure the job template to prompt for the vault password at launch time.
B.Set the vault password as an environment variable named ANSIBLE_VAULT_PASSWORD on the automation controller host.
C.Store the vault password in an Ansible vault credential and attach it to the job template.
D.Embed the vault password in the playbook as an encrypted variable using ansible-vault encrypt_string.
AnswerC

Automation controller supports vault credentials that securely store the vault password. When attached to a job template, the controller injects the password at runtime without exposing it in the playbook repository or job output. This is the intended secure method for supplying vault passwords to jobs.

Why this answer

Automation controller vault credentials securely store secrets and inject them into jobs without exposing them in the repository or job output. Attaching such a credential to a job template provides the vault password at runtime, enabling decryption of vaulted files while keeping the secret centralized and auditable.

Exam trap

The trap here is thinking that embedding an encrypted password in the playbook or using host environment variables is a secure way to supply a vault password to automation controller.

87
MCQhard

What is the effect of the `filter_plugins` setting in `ansible.cfg`?

A.It sets the directory for filter plugins but only for the current playbook.
B.It configures the path for lookup plugins, not filter plugins.
C.It replaces the default search path for filter plugins with the specified directory.
D.It adds the directory to the default search path for filter plugins.
AnswerD

The filter_plugins directive appends directories to Ansible's default search path for filter plugins, letting custom Jinja2 filters be located alongside built-ins. It does not enable or disable plugins; it only extends where the controller looks when resolving filter names.

Why this answer

The `filter_plugins` setting in `ansible.cfg` adds the specified directory to the default search path for filter plugins, not replacing it. Ansible searches default locations like `~/.ansible/plugins/filter` and the `filter_plugins` directory relative to the playbook, in addition to any directories specified by this setting. Therefore, option D is correct.

Exam trap

The trap is that candidates often assume `filter_plugins` replaces the default search path (option C), but it actually adds to it. This misunderstanding arises because some Ansible configuration settings override defaults, but `filter_plugins` is additive.

How to eliminate wrong answers

Option A is wrong because `filter_plugins` is not limited to the current playbook; it applies globally to all playbooks run with that configuration file. Option B is wrong because `filter_plugins` specifically configures the path for filter plugins, not lookup plugins (which are configured by `lookup_plugins`). Option D is wrong because the setting replaces the default search path, not adds to it; to add a directory, you would need to use a colon-separated list or rely on the default search order.

88
MCQhard

An Ansible playbook fails intermittently due to a service not starting in time. The administrator wants to configure a task to retry until the service confirms it is running. Which Ansible feature should be used?

A.Until loop with retries and delay.
B.Failed_when with conditional retry.
C.Block and rescue to catch failure.
D.Async with poll interval.
AnswerA

An until loop with retries and delay repeatedly runs the task until its condition evaluates true, pausing between attempts. This directly satisfies the intermittent-startup constraint: the service check is re-evaluated after each delay, so transient timing failures no longer abort the playbook.

Why this answer

The 'until' loop in Ansible repeatedly retries a task until a specified condition evaluates to true, and it can be combined with 'retries' and 'delay' to control how many attempts are made and how long to wait between them. This is the idiomatic way to handle a service that takes time to start, such as waiting for a port to open or a status command to succeed. It directly addresses intermittent timing failures without failing the playbook prematurely.

Exam trap

EX294 often tests the difference between retry mechanisms ('until' with retries/delay) and error-handling constructs ('block'/'rescue', 'failed_when'), so candidates who pick a recovery construct instead of a polling loop get it wrong.

How to eliminate wrong answers

Option B is wrong because 'failed_when' only redefines what constitutes a failure — it does not provide a retry mechanism by itself, so it cannot wait for a service to come up. Option C is wrong because 'block' and 'rescue' handle error recovery after a failure, not repeated polling until success; they are for exception handling, not retry loops. Option D is wrong because 'async' with a poll interval runs a task asynchronously and checks on it, but it is designed for long-running tasks, not for condition-based retries of a service check.

89
MCQhard

A company uses Ansible Vault to encrypt sensitive data in playbooks. They have multiple environments (dev, test, prod) and use a separate vault password file for each environment. The passwords are stored in files named 'vault-pass-dev', 'vault-pass-test', and 'vault-pass-prod'. To run a playbook against the test environment, they use the command 'ansible-playbook site.yml -i test -e @test-vars.yml --vault-id test@vault-pass-test'. This runs successfully from the command line. However, when they define the same vault-id in an Ansible Tower credential and attempt to run the job, the job fails with 'ERROR! Decryption failed (no vault secrets would be found that could decrypt the vault encrypted file)' for a vault-encrypted variable file that was encrypted with a different vault ID (e.g., 'dev'). The team expects that Tower would use the provided vault credential to decrypt all vault-encrypted files. Which change should be made to ensure correct decryption in Tower?

A.Add multiple vault credentials to the job template, one for each vault ID used in the project.
B.Enter all vault passwords separated by commas in the 'VAULT PASSWORD' field of a single credential.
C.Re-encrypt all files with the same vault ID (e.g., 'default') to simplify the setup.
D.Change the vault password file to contain the password for the vault ID that was used to encrypt the file.
AnswerA

Tower matches each vault credential to a single vault ID, so a test credential cannot decrypt dev-encrypted files. Adding one credential per vault ID lets Tower supply every required secret, satisfying the multi-environment decryption constraint that the CLI handled via repeated --vault-id flags.

Why this answer

In Ansible Tower, each vault credential is associated with a single vault ID and password. To decrypt files encrypted with different vault IDs, you must attach multiple vault credentials to the job template, each corresponding to a vault ID used in the project. This allows Tower to try each credential until decryption succeeds.

The command-line success with a single vault-id works because only files encrypted with that ID are decrypted; files with other IDs would fail unless multiple --vault-id options are provided.

Exam trap

EX294 often tests the misconception that a single vault credential can decrypt all vault-encrypted files regardless of vault ID, leading candidates to overlook the need for multiple credentials.

How to eliminate wrong answers

Option B is wrong because the VAULT PASSWORD field in a single credential accepts only one password, not a comma-separated list; multiple passwords require multiple credentials. Option C is wrong because re-encrypting all files with the same vault ID reduces security and does not address the requirement to support multiple environments with separate passwords. Option D is wrong because changing the vault password file to contain the password for the file's vault ID would only work if that file is the only one, but the project uses multiple vault IDs; it does not solve the need for multiple credentials.

90
MCQmedium

A playbook must connect to hosts using a non-default SSH private key stored at /home/student/.ssh/prod_key and a non-default remote user 'deploy'. The inventory file should apply these settings to all hosts in the 'production' group without editing the playbook. Which inventory variable combination is correct?

A.[production:vars] private_key_file=/home/student/.ssh/prod_key remote_user=deploy
B.[production:vars] ansible_ssh_private_key_file=/home/student/.ssh/prod_key ansible_user=deploy
C.[production:vars] ssh_private_key_file=/home/student/.ssh/prod_key user=deploy
D.[production:vars] ansible_ssh_key=/home/student/.ssh/prod_key ansible_remote_user=deploy
AnswerB

The ansible_ssh_private_key_file variable tells Ansible which private key to use for SSH authentication, and ansible_user sets the remote login name. Defining both under a [production:vars] section applies them to every host in the production group, exactly matching the requirement without playbook changes.

Why this answer

Ansible uses connection variables prefixed with ansible_ to override SSH behavior. ansible_ssh_private_key_file specifies the key, and ansible_user sets the remote user. Placing them in a group vars section applies them to all hosts in that group, satisfying the scenario without modifying the playbook.

Exam trap

The trap here is using plausible but incorrect variable names such as private_key_file or ansible_remote_user instead of the actual Ansible connection variables.

91
MCQhard

The build fails with a DNS resolution error for `registry.redhat.io`. Which troubleshooting step is most likely to resolve the issue?

A.Run `podman login registry.redhat.io` to authenticate.
B.Restart the container runtime service.
C.Verify DNS settings in `/etc/resolv.conf` or configure a custom DNS server for the container runtime.
D.Use the `--no-cache` flag to force a fresh build.
AnswerC

The DNS resolution failure means the container runtime cannot resolve registry.redhat.io, so checking /etc/resolv.conf or configuring a custom DNS server for the runtime restores name resolution. This addresses the constraint directly, unlike authentication or firewall changes.

Why this answer

A DNS resolution error for `registry.redhat.io` indicates that the container runtime (e.g., Podman) cannot resolve the registry's hostname to an IP address. This is a network/DNS issue, not an authentication or caching problem. Verifying or correcting DNS settings in `/etc/resolv.conf` or configuring a custom DNS server for the container runtime directly addresses the root cause by ensuring the host or container runtime can resolve the registry's FQDN.

Exam trap

The trap here is that candidates confuse DNS resolution errors with authentication or cache issues, leading them to choose `podman login` or `--no-cache` instead of recognizing that DNS must work before any network communication can occur.

How to eliminate wrong answers

Option A is wrong because `podman login` authenticates to the registry, but DNS resolution occurs before authentication; if the hostname cannot be resolved, authentication is irrelevant. Option B is wrong because restarting the container runtime service does not fix underlying DNS configuration issues; it only restarts the daemon without changing network or resolver settings. Option D is wrong because `--no-cache` forces a fresh build by ignoring cached layers, but it does not affect DNS resolution; the build will still fail if the registry hostname cannot be resolved.

92
MCQeasy

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
D.Network credential
AnswerC

A Vault credential stores the Ansible Vault password separately from machine credentials, letting Automation Controller decrypt vault-encrypted variables such as ansible_password at runtime. It satisfies the requirement to supply the vault password without embedding it in the playbook.

Why this answer

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.

Exam trap

The trap here is that candidates confuse the credential type used to authenticate to the target host (Machine credential) with the credential type needed to decrypt the vault file containing the host's password, leading them to select Option B instead of C.

How to eliminate wrong answers

Option A is wrong because Cloud credentials are used to authenticate against cloud providers (e.g., AWS, Azure, GCP) and have no mechanism to supply a vault password for decrypting Ansible Vault files. Option B is wrong because Machine credentials provide SSH keys or username/password for connecting to target hosts, not the vault password needed to decrypt encrypted variables stored in vault files. Option D is wrong because Network credentials are used for network device authentication (e.g., via SSH or API tokens) and do not support supplying vault passwords for Ansible Vault decryption.

93
MCQeasy

An administrator wants to run a playbook with a different user for a specific host. Which variable should be set?

A.ansible_user
B.ansible_user_id
C.ansible_ssh_user
D.ansible_remote_user
AnswerA

Correct variable to set SSH user.

Why this answer

Ansible_user sets the remote user for SSH connections to the target host. Option B (ansible_user_id) is a fact variable that returns the UID of the user running the task on the remote host, not the connection user. Option C (ansible_ssh_user) is a deprecated alias for ansible_user.

Option D (ansible_remote_user) is also a deprecated alias.

94
Drag & Dropmedium

Drag and drop the steps to configure a container using Podman with a custom Dockerfile in the correct order.

Drag or tap steps into the slots.

Steps
Order
1Step 1
2Step 2
3Step 3
4Step 4

Why this order

Podman workflow: create Dockerfile, build image, list images, run container, verify.

95
MCQhard

A developer is creating a new content collection named `acme.automation` and wants to ensure that the collection is structured correctly for distribution. After running `ansible-galaxy collection init acme.automation`, which directory should contain the custom Ansible modules that the collection will provide?

A.`roles/modules/`
B.`plugins/modules/`
C.`modules/`
D.`library/`
AnswerB

In an Ansible collection, custom modules are placed in the `plugins/modules/` directory. This is the standard location that Ansible searches when resolving modules from a collection. After initializing with `ansible-galaxy collection init`, the directory structure includes `plugins/modules/` by default, ready for module files. Placing modules here ensures they are discoverable and usable in playbooks via the collection's fully qualified name.

Why this answer

Ansible collections organize plugins by type. Modules are a type of plugin and belong in `plugins/modules/`. This structure allows Ansible to load modules from the collection namespace.

Other directories like `roles/` or `library/` serve different purposes and are not scanned for collection modules. Using the correct directory is essential for the collection to work as intended.

Exam trap

The trap here is confusing the collection plugin directory structure with legacy role or playbook directory layouts.

96
MCQhard

An administrator has a requirements.yml file specifying roles from multiple sources: a public Galaxy server, a private Git repository, and a local path. They want to install all roles into the roles directory of the current project. Which command will achieve this?

A.ansible-galaxy collection install -r requirements.yml
B.ansible-galaxy install -r requirements.yml --roles-path ./roles
C.ansible-galaxy install -r requirements.yml -p .
D.ansible-galaxy role install --force -r requirements.yml
AnswerB

The `-r` flag reads every entry in requirements.yml, resolving Galaxy, Git and local sources in one pass, while `--roles-path ./roles` overrides the default install location so roles land in the project's own roles directory rather than the user-level path — satisfying the stem's requirement to install all roles locally.

Why this answer

The command 'ansible-galaxy install -r requirements.yml --roles-path ./roles' installs roles from a requirements file into the specified roles directory. The '--roles-path' option (or '-p') sets the destination, and '-r' specifies the requirements file. This meets the requirement to install all roles into the roles directory of the current project.

Exam trap

EX294 often tests the distinction between 'ansible-galaxy install' and 'ansible-galaxy collection install', and the correct use of '--roles-path' versus '-p' with the right directory, causing candidates to choose commands that install to the wrong location.

How to eliminate wrong answers

Option A is wrong because 'ansible-galaxy collection install' is for collections, not roles, and it does not use '--roles-path'. Option C is wrong because '-p .' sets the roles path to the current directory, not the 'roles' subdirectory, so roles would be installed in the project root, not in 'roles'. Option D is wrong because 'ansible-galaxy role install --force -r requirements.yml' lacks the '--roles-path' option, so it installs to the default system roles path, not the project's roles directory.

97
MCQmedium

Given a list of dictionaries `users` with keys `name` and `role`, a playbook needs to create a list of names where role is 'admin'. Which expression achieves this?

A.{{ users | selectattr('role', 'equalto', 'admin') | map(attribute='name') | list }}
B.{{ users | map(attribute='name') | selectattr('role', 'equalto', 'admin') | list }}
C.{{ users | json_query("[?role=='admin'].{name: name}") }}
D.{{ users | selectattr('role', 'equalto', 'admin') | list }}
AnswerA

The expression chains selectattr to filter dictionaries whose 'role' equals 'admin', then map extracts the 'name' attribute, and list materialises the result. This satisfies the requirement to produce a list of names, since selectattr alone would return whole dictionaries rather than the names.

Why this answer

It first uses `selectattr` to filter the list of dictionaries, keeping only those where `role` equals `'admin'`, then applies `map(attribute='name')` to extract the `name` values from the filtered dictionaries, and finally converts the result to a list with the `list` filter. This produces a list of names for admin users.

Exam trap

Red Hat often tests the order of filter chaining: candidates mistakenly apply `map` before `selectattr`, not realizing that `map` transforms the data structure, making subsequent attribute-based filtering impossible.

How to eliminate wrong answers

Option B is wrong because it applies `map(attribute='name')` before `selectattr`, which extracts names from all users first, turning the list into a list of strings; then `selectattr` tries to filter a list of strings by a `role` attribute, which does not exist on strings, so the filter returns an empty list. Option C is wrong because `json_query` with the JMESPath expression `[?role=='admin'].{name: name}` returns a list of dictionaries with a single key `name`, not a list of plain names; to get a list of names, the expression should be `[?role=='admin'].name`. Option D is wrong because it only filters the list to dictionaries where `role` is `'admin'` but does not extract the `name` attribute, so the result is a list of dictionaries, not a list of names.

98
MCQeasy

What is the purpose of the 'meta: flush_handlers' task?

A.Restart services immediately
B.Clear the handler queue
C.Wait for handlers to complete
D.Force handlers to run immediately
AnswerD

The meta: flush_handlers task interrupts the current play and executes all handlers notified so far, rather than waiting until the end of the play. This forces immediate handler execution at that point in the task sequence.

Why this answer

The 'meta: flush_handlers' task in Ansible is used to force any pending handler notifications to run immediately at that point in the play, rather than waiting until the end of the play. This is correct because it ensures that handlers triggered by earlier tasks execute right away, which is essential when subsequent tasks depend on the state changes those handlers make (e.g., restarting a service before configuring it further).

Exam trap

The trap here is that candidates confuse 'flush_handlers' with simply waiting for handlers to complete (Option C), not realizing that flush_handlers actively forces immediate execution of the handler queue, rather than passively waiting for the default end-of-play execution.

How to eliminate wrong answers

Option A is wrong because 'restart services immediately' is not a direct purpose of flush_handlers; handlers may include restarts, but flush_handlers forces all pending handlers to run, not just restarts. Option B is wrong because 'clear the handler queue' is the opposite of what flush_handlers does—it executes the queue, not empties it without execution. Option C is wrong because 'wait for handlers to complete' describes a passive behavior, whereas flush_handlers actively triggers execution of pending handlers at that point in the play.

99
MCQmedium

An Ansible playbook includes a role that defines default variables in 'defaults/main.yml' and role variables in 'vars/main.yml'. A playbook sets the same variable in the play's 'vars' section. Which variable value takes precedence?

A.Role defaults
B.Inventory group vars
C.Role vars
D.Play vars
AnswerD

Play vars outrank both role defaults and role vars in Ansible's precedence order, sitting above role vars/main.yml and far above defaults/main.yml. Because the play explicitly sets the variable, that value overrides the role's defaults and vars, satisfying the stem's precedence question.

Why this answer

In Ansible, variable precedence is hierarchical, and play vars (set directly in the play's `vars` section) have a higher priority than role defaults and role vars. Specifically, play vars override role vars, which in turn override role defaults. Therefore, when the same variable is defined in all three locations, the play vars value takes precedence.

Exam trap

Red Hat often tests the misconception that role vars override play vars because they are defined inside the role, but the actual precedence places play vars above role vars, so candidates must memorize the full variable precedence order to avoid this trap.

How to eliminate wrong answers

Option A is wrong because role defaults have the lowest precedence among the listed options; they are meant to be easily overridden by any other variable source. Option B is wrong because inventory group vars have a lower precedence than play vars; they are overridden by play vars when both define the same variable. Option C is wrong because role vars have a higher precedence than role defaults but are still overridden by play vars, which sit higher in the variable precedence order.

100
MCQmedium

A playbook must read a vault-encrypted variable file named secrets.yml and also use a vault password stored in a file named vault_pass.txt. The playbook is executed with the command `ansible-playbook site.yml --vault-password-file vault_pass.txt`. The file secrets.yml was encrypted with the same password. During execution, the task that uses a variable from secrets.yml fails with an error indicating the variable is undefined. What is the most likely reason?

A.The vault password file must be passed with --vault-id instead of --vault-password-file.
B.The vault password file must have permissions of 0600, otherwise Ansible ignores it.
C.The vault-encrypted variable file must be included with vars_files in the playbook, not merely present in the same directory.
D.The variable file must be decrypted to plaintext before it can be used in a playbook.
AnswerC

Ansible does not automatically load variable files from the playbook directory. To use variables from secrets.yml, the playbook must explicitly include it, typically via vars_files: - secrets.yml. Without that inclusion, the variables are never loaded, causing an undefined variable error even though decryption succeeds.

Why this answer

Variables from a vault-encrypted file are only available to a play if the file is explicitly loaded, commonly through vars_files or include_vars. Merely placing the encrypted file alongside the playbook and supplying the vault password does not make its variables available, so the task referencing them fails with an undefined variable error.

Exam trap

The trap here is assuming that Ansible automatically loads vault-encrypted variable files from the playbook directory once a vault password is supplied.

101
MCQmedium

An administrator maintains a project directory with an inventory file `inventory.ini` that contains a group `db_servers` with hosts `db1.example.com` and `db2.example.com`. The playbook `site.yml` must run only against these two hosts, but the inventory also contains other groups. The administrator wants to avoid modifying the inventory file and instead use a command-line option to limit execution to `db_servers`. Which command should be used?

A.ansible-playbook -i inventory.ini site.yml --limit db_servers
B.ansible-playbook -i inventory.ini site.yml --start-at-task db_servers
C.ansible-playbook -i inventory.ini site.yml -e "target=db_servers"
D.ansible-playbook -i inventory.ini site.yml --tags db_servers
AnswerA

The --limit option restricts execution to the specified subset of hosts. Using the group name db_servers correctly targets only hosts in that group. This is the intended mechanism to override the play's host pattern without editing the inventory. The command assumes the playbook's hosts directive matches a broader pattern, but --limit applies on top. It is the correct approach for the scenario.

Why this answer

The --limit option is the correct way to restrict a playbook run to a subset of hosts defined in the inventory, such as a group. It overrides the play's host pattern without modifying the inventory or playbook. The other options either pass variables, control task execution, or filter tags, none of which select hosts.

Thus, only --limit db_servers targets the intended group.

Exam trap

The trap here is confusing host-limiting options with task-limiting or variable-passing options, assuming that any extra flag can restrict execution to a group.

102
MCQeasy

What is the output of the following playbook task? ```yaml - name: Example task debug: msg: "{{ ['apple', 'banana'] | map('upper') | first }}" ```

A.'APPLE'
B.An error because map expects a list of strings.
C.['APPLE', 'BANANA']
D.'apple'
AnswerA

The `map('upper')` filter applies the upper filter to every element, yielding `['APPLE', 'BANANA']`, then `first` returns the initial element, `'APPLE'`. This satisfies the stem's requirement to evaluate the chained filters in sequence and report the resulting string output.

Why this answer

The playbook task likely uses a filter that extracts only the first element after applying `map('upper')`. For example, `{{ ['apple', 'banana'] | map('upper') | first }}` would output 'APPLE'. The `map` filter applies the `upper` filter to each element, but the `first` filter selects only the first item, resulting in the string 'APPLE'.

Candidates may mistakenly think the entire list is returned, but this task explicitly retrieves a single element.

Exam trap

The trap here is that candidates may think `map` returns a list directly, but it returns a generator, and they might also confuse the output format (single string vs. list) or incorrectly assume an error occurs when the input is not a list of strings.

How to eliminate wrong answers

Option B is wrong because `map` does not require a list of strings; it can accept any iterable, and the `upper` filter works on strings within the list, so no error occurs. Option C is wrong because the output is `['APPLE', 'BANANA']`, not `['APPLE', 'BANANA']` as a single string—this option is actually correct if the question's expected output is a list, but the question states A is correct, so C is considered wrong in this context. Option D is wrong because `map` with `upper` converts all elements to uppercase, not lowercase, so the output is not `'apple'`.

103
MCQmedium

The inventory above is used in a job template in Automation Controller. The job template also has a machine credential assigned that specifies username 'root' and an SSH key. When the job runs against host web1, which username will Ansible use to connect?

A.admin (from inventory host variable)
B.The username set in the job template's 'extra variables'
C.The first defined username in the credential chain
D.root (from credential)
AnswerA

Inventory host variables take precedence over the machine credential's username when Ansible resolves connection parameters for a host. The web1 host variable ansible_user set to admin therefore overrides root, satisfying the precedence rule demonstrated in the inventory.

Why this answer

Ansible uses a specific precedence order for determining the connection user. When a host variable (like `ansible_user: admin`) is defined in the inventory for host web1, it overrides the username set in the job template's machine credential. The credential's username ('root') acts only as a fallback if no `ansible_user` is defined at the host or group level.

Exam trap

The trap here is that candidates assume the credential's username is always used, forgetting that inventory host variables (like `ansible_user`) override credential settings, a common point of confusion in Ansible's variable precedence hierarchy.

How to eliminate wrong answers

Option B is wrong because extra variables in the job template do not directly set the connection username; they are used for playbook variables, not for the SSH user unless explicitly referenced via `ansible_user` in the extra vars. Option C is wrong because there is no 'credential chain' that selects the first username; Ansible uses a deterministic precedence: host vars > group vars > credential username > default (current user). Option D is wrong because the credential's username ('root') is overridden by the host variable `ansible_user: admin` defined in the inventory for web1.

104
MCQeasy

What is the purpose of the 'vars' keyword under the httpd role inclusion?

A.Set variables for the common role
B.Define new variables for the playbook
C.Set variables for all roles in the play
D.Override default variables for that role
AnswerD

Passing `vars` under a role inclusion overrides that role's default variables for the current play only, without editing the role's `defaults/main.yml`. This satisfies the scenario's need to customise role behaviour per host or play while keeping the role reusable and unmodified.

Why this answer

The 'vars' keyword under a role inclusion in Ansible allows you to override the default variables defined within that specific role. This is done at the point of inclusion, providing role-specific variable overrides without affecting other roles or the playbook's global variable scope.

Exam trap

The trap here is that candidates often confuse the 'vars' keyword under a role inclusion with setting global playbook variables, but it only overrides variables for that specific role instance.

How to eliminate wrong answers

Option A is wrong because 'vars' under a role inclusion does not set variables for the common role; it only affects the specific role being included. Option B is wrong because 'vars' does not define new variables for the playbook as a whole; it only provides variables to the included role. Option C is wrong because 'vars' under a single role inclusion does not set variables for all roles in the play; each role inclusion can have its own 'vars' block, and they are isolated to that role.

105
MCQmedium

An Ansible playbook needs to dynamically include a set of variables based on the environment (dev/staging/prod). The developer wants to use a variable from a lookup plugin that returns a YAML file path. Which lookup plugin is most appropriate for fetching a file’s contents?

A.env
B.pipe
C.file
D.template
AnswerC

Lookup plugin 'file' reads a file's content as a string.

Why this answer

The `file` lookup plugin is the most appropriate for fetching the contents of a file from the control node, as it reads the entire file and returns its content as a string. This is ideal for dynamically including variable files based on environment (e.g., `{{ lookup('file', 'vars/{{ env }}.yml') }}`), allowing the playbook to load environment-specific YAML data.

Exam trap

Red Hat often tests the distinction between lookup plugins that read from the control node vs. remote host, and the trap here is confusing the `file` lookup (control node) with the `slurp` module (remote host) or assuming `template` can read raw file contents without rendering.

How to eliminate wrong answers

Option A is wrong because the `env` lookup plugin retrieves the value of an environment variable from the control node's shell, not the contents of a file. Option B is wrong because the `pipe` lookup plugin executes a command on the control node and returns its stdout, which is not designed for reading file contents directly. Option D is wrong because the `template` lookup plugin processes a Jinja2 template file and returns the rendered output, not the raw contents of a static YAML file.

106
MCQmedium

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

With become enabled, Ansible escalates via sudo, which needs the privilege password when NOPASSWD is not configured. The blank Become password field in the machine credential leaves sudo without credentials, producing the 'Missing sudo password' error.

Why this answer

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.

Exam trap

Red Hat often tests the distinction between SSH authentication (private key) and privilege escalation (become password) in Automation Controller, tempting candidates to focus on SSH key issues when the error clearly points to the missing become password.

How to eliminate wrong answers

Option B is wrong because the error message explicitly mentions 'sudo', and the default become method in Ansible is 'sudo'; changing to 'su' would produce a different error or require different configuration. Option C is wrong because if the remote user were not in the sudoers file, the error would typically be 'user is not in the sudoers file' or a permission denied message, not 'Missing sudo password'. Option D is wrong because the playbook runs successfully when executed manually by the administrator, proving the SSH key works; the issue is specifically with the become password, not the SSH authentication.

107
MCQhard

A developer is creating a new content collection and wants to include a custom module that requires the `requests` Python library. The collection will be used in an execution environment. Where should the developer declare this Python dependency so that it is automatically installed when the execution environment is built?

A.In a `requirements.txt` file at the root of the collection.
B.In the collection's `meta/runtime.yml` file under `requires_ansible`.
C.In the `execution-environment.yml` file under the `dependencies` section with a `python` key.
D.In the collection's `galaxy.yml` file under a `dependencies` key.
AnswerC

The `execution-environment.yml` file is the central place to define all dependencies for an execution environment, including Python packages. Under the `dependencies` section, you can specify a `python` list that includes `requirements.txt` or direct package names. This ensures `ansible-builder` installs the required Python libraries during the image build. This is the correct location for declaring `requests`.

Why this answer

Python dependencies for an execution environment are declared in the `execution-environment.yml` file under the `dependencies` section, using the `python` key to list packages or a requirements file. This allows `ansible-builder` to install them during the build process. Other files like `galaxy.yml` or `meta/runtime.yml` serve different purposes and do not trigger Python package installation.

Exam trap

The trap here is assuming that a `requirements.txt` file at the collection root is automatically used by `ansible-builder`, when actually the execution environment definition must explicitly reference it.

108
MCQeasy

A systems administrator needs to use a different SSH private key for a group of hosts in an Ansible inventory. Which inventory variable should be set at the group level?

A.ansible_ssh_key
B.ansible_ssh_private_key_file
C.ansible_ssh_key_file
D.ansible_private_key
AnswerB

ansible_ssh_private_key_file is the inventory variable that specifies the SSH private key used for authentication. Setting it at group level applies that key to every host in the group, satisfying the requirement to use a different key for those hosts.

Why this answer

`ansible_ssh_private_key_file` is the Ansible inventory variable that specifies the path to the SSH private key file for a host or group. When set at the group level, it applies to all hosts in that group, allowing the administrator to use a different key for authentication without modifying individual host definitions.

Exam trap

The trap here is that candidates confuse the variable name with similar-sounding but invalid options like `ansible_ssh_key` or `ansible_private_key`, forgetting that Ansible requires the exact `ansible_ssh_private_key_file` syntax to specify a private key file path.

How to eliminate wrong answers

Option A is wrong because `ansible_ssh_key` is not a valid Ansible variable; the correct variable name includes `private_key_file` to indicate the file path. Option C is wrong because `ansible_ssh_key_file` is not a recognized variable; Ansible uses `ansible_ssh_private_key_file` to avoid ambiguity with public keys. Option D is wrong because `ansible_private_key` omits the `ssh` connection plugin prefix and the `file` suffix, making it an invalid variable that Ansible will ignore.

109
MCQhard

An Ansible playbook uses a rolling update strategy with serial: 1. After the first host is updated, the playbook stops and shows 'PLAY RECAP' with only one host. What is the most likely reason?

A.the playbook has a 'failed_when' condition that stops execution
B.the inventory contains only one host
C.the play uses 'delegate_to' incorrectly
D.the playbook does not have any task that triggers the next batch, and 'serial' only controls concurrency, not retry
AnswerB

Correct. If the inventory contains only one host, the playbook will run on that host and then finish, producing a PLAY RECAP with exactly one host. This is the most likely reason given the behavior described.

Why this answer

The `serial: 1` directive in Ansible limits concurrency to one host at a time, but the playbook will still process all hosts in the inventory. If the playbook stops after the first host and shows PLAY RECAP with only one host, the most likely reason is that the inventory contains only one host. With a single host, the play executes on that host and then finishes.

Option B accurately identifies this scenario.

Exam trap

In the Red Hat RHCE exam, examinees may overthink the behavior of 'serial' and forget to check the inventory size. The trap is assuming 'serial: 1' somehow stops the playbook, whereas the real cause is often a single-host inventory.

How to eliminate wrong answers

Option A is wrong because a `failed_when` condition would cause the playbook to fail on a specific task, but it would not stop the playbook after the first host unless combined with `any_errors_fatal` or `max_fail_percentage`; even then, the 'PLAY RECAP' would show the failed host, not just one host. Option B is wrong because if the inventory contained only one host, the playbook would still run and show a 'PLAY RECAP' with that single host, which is expected behavior, not a reason for stopping after the first host in a multi-host scenario. Option C is wrong because incorrect `delegate_to` usage might cause tasks to run on the wrong host or fail, but it would not cause the playbook to stop after the first host and show a 'PLAY RECAP' with only one host; it would either fail or complete on all hosts.

110
MCQhard

You maintain a variable inventory_hostnames that is a list of FQDN strings such as 'web01.example.com'. A template must produce a new list containing only the hostname portion before the first dot for each entry, preserving order. Which Jinja2 expression using Ansible filters achieves this?

A.{{ inventory_hostnames | join('.') | regex_replace('\\..*$', '') }}
B.{{ inventory_hostnames | select('match', '^[^.]*') | list }}
C.{{ inventory_hostnames | map(attribute='split') | list }}
D.{{ inventory_hostnames | map('regex_replace', '^(.*?)\..*$', '\\1') | list }}
AnswerD

The map filter applies regex_replace to every element, and the pattern captures everything before the first literal dot while discarding the remainder. Wrapping with list materializes the generator so the template renders a proper list. This preserves input order and returns only the hostname portion, which matches the requirement without needing an explicit loop in the template.

Why this answer

Transforming each element of a list while preserving order is best done with map combined with a transformation filter. regex_replace with a capture group extracts the portion before the first dot for every FQDN, and list materializes the generator so the template emits an actual list. Selecting or joining would either leave the strings unchanged or collapse the collection, so mapping is the appropriate technique.

Exam trap

The trap here is confusing select, which filters elements by a test, with map, which transforms each element.

111
Multi-Selectmedium

Which TWO statements are true about Ansible content collections?

Select 2 answers
A.Collections can be installed from Automation Hub, Galaxy, or a Git repository.
B.Collections cannot contain playbooks.
C.A role stored in a collection can be referenced by its short name without the collection prefix.
D.Execution environments are required to use collections.
E.Fully qualified collection names (FQCN) help avoid naming conflicts.
AnswersA, E

Collections are distributed as tarballs or Git repositories, so installation works from Automation Hub, Galaxy, or a Git URL via `ansible-galaxy collection install`. This satisfies the stem's requirement that content can be sourced from multiple locations, including private Git repositories, rather than being limited to a single distribution channel.

Why this answer

Option A is correct because Ansible collections can be installed from multiple sources, including Automation Hub (Red Hat's certified content repository), Ansible Galaxy (the public community hub), and directly from a Git repository using ansible-galaxy collection install with a git URL or a requirements.yml entry specifying type: git. Option E is correct because Fully Qualified Collection Names (FQCN), such as ansible.builtin.copy or community.general.ufw, namespace each module, role, and plugin under its collection, preventing collisions when different collections define content with the same short name. Option B is wrong because collections may contain playbooks in their playbooks/ directory alongside roles, modules, and plugins.

Option C is wrong because a role inside a collection must be referenced with its FQCN (for example, my_namespace.my_collection.my_role) or via the collections keyword in a playbook, not by its bare short name. Option D is wrong because execution environments are an optional containerized packaging mechanism for dependencies, not a prerequisite for using collections.

Exam trap

The trap here is that candidates often assume collections cannot contain playbooks (option B) or that execution environments are mandatory (option D), but the EX294 exam expects you to know that collections can include playbooks and that EEs are optional for basic collection usage.

112
MCQeasy

A template must display the value of a variable named app_port. If app_port is undefined, the template should render the number 8080 instead of failing. Which expression accomplishes this using an Ansible filter?

A.{{ app_port | ternary(8080) }}
B.{{ app_port | default(omit) }}
C.{{ app_port | mandatory(8080) }}
D.{{ app_port | default(8080) }}
AnswerD

The default filter returns the supplied fallback value when the preceding variable is undefined. Here, if app_port has not been set, the template renders 8080; if it is defined, its actual value is used. This is the standard Ansible approach for providing safe fallbacks in templates and avoids undefined variable errors during rendering.

Why this answer

Providing a fallback for an undefined variable in a template is exactly what the default filter handles. When app_port is absent from the variable namespace, default(8080) supplies the specified value, allowing the template to render successfully. Other filters either raise errors, produce non-numeric placeholders, or require conditional arguments, so they do not meet the requirement.

Exam trap

The trap here is confusing default, which supplies a fallback, with mandatory, which forces an error when a variable is missing.

113
MCQmedium

A team uses Ansible to update a database cluster with one primary and two replicas. The goal is zero downtime. Which update order is the safest?

A.Update replicas first, then the primary.
B.Update in random order.
C.Update all nodes simultaneously.
D.Update the primary first, then replicas.
AnswerA

Updating replicas first keeps the primary serving traffic throughout, so no write outage occurs. Each replica is drained from the load balancer, patched, and rejoined before touching the next. Only after both replicas run the new version is the primary failed over and updated, satisfying the zero-downtime constraint.

Why this answer

Updating replicas first ensures that if the update introduces a regression, it affects only the read-only replicas, which can be quickly rolled back without impacting write availability. Once replicas are confirmed healthy, the primary is updated and a controlled failover (e.g., using `patronictl switchover` or `repmgr standby switchover`) promotes a replica to primary, minimizing downtime to seconds. This order aligns with the principle of reducing blast radius and maintaining quorum in a cluster.

Exam trap

The trap here is that candidates assume updating the primary first is safer because it is the 'source of truth,' but in a clustered environment with zero-downtime requirements, updating replicas first is the standard practice to preserve write availability and allow safe rollback.

How to eliminate wrong answers

Option B is wrong because updating in random order risks updating the primary first, causing a write outage if the update fails, and may break replication consistency if replicas are updated before the primary without a controlled failover. Option C is wrong because updating all nodes simultaneously can cause a complete cluster outage if the update introduces a bug, and it violates the zero-downtime requirement by potentially losing quorum or causing split-brain scenarios. Option D is wrong because updating the primary first forces a failover to a replica that still runs the old version, which may be incompatible with the updated primary's data format or replication protocol, leading to replication lag or cluster instability.

114
MCQeasy

A playbook uses the 'block' feature to group tasks and includes a 'rescue' section. If a task inside the block fails, what happens?

A.The rescue tasks run, and then the entire playbook fails.
B.The rescue tasks run, and the play continues with the next task after the block.
C.The rescue tasks are ignored and the play fails immediately.
D.The block is re-executed after rescue.
AnswerB

When a task inside a block fails, Ansible executes the rescue section, then continues the play with tasks following the block. The failure is handled rather than aborting the run, so subsequent plays and tasks proceed normally.

Why this answer

In Ansible, when a task inside a `block` fails, the `rescue` section is executed to handle the failure. After the rescue tasks complete successfully, the play continues with the next task after the block, not from the beginning of the block. This behavior allows for error recovery without terminating the entire play.

Exam trap

The trap here is that candidates often confuse `rescue` with a retry mechanism, thinking it re-executes the block, or they assume that any failure in the block immediately fails the entire play, ignoring the rescue capability.

How to eliminate wrong answers

Option A is wrong because after the rescue tasks run, the play does not fail; it continues with the next task after the block, unless the rescue tasks themselves fail. Option C is wrong because the rescue tasks are not ignored; they are specifically designed to run when a task in the block fails, and the play does not fail immediately unless the rescue tasks also fail. Option D is wrong because the block is not re-executed after rescue; the rescue section runs once, and then execution proceeds to the task after the block.

115
MCQhard

A team uses a single Ansible Tower inventory called 'Production' containing hosts for multiple environments (dev, stage, prod). They want to apply different variables to hosts based on environment. Which inventory structure meets this requirement with minimal administrative overhead?

A.Create groups within the inventory for each environment (e.g., 'dev', 'stage', 'prod') and assign variables at the group level.
B.Assign variables directly to each host using the 'Host Variables' field in the inventory.
C.Add tags to each host and use the tags to filter variables in the job template.
D.Create separate inventories for each environment and link them to the same project.
AnswerA

Grouping hosts by environment inside the single Production inventory and assigning variables at group level applies environment-specific values automatically, satisfying the minimal administrative overhead constraint. No duplicate inventories or per-host variable files are needed, and group variables inherit cleanly.

Why this answer

Ansible Tower (now Red Hat Ansible Automation Platform) supports group-based variable inheritance within a single inventory. By creating groups for each environment (dev, stage, prod) and assigning variables at the group level, you can apply environment-specific variables to all hosts in that group with minimal administrative overhead. This leverages Tower's built-in group variable mechanism without requiring per-host edits or multiple inventory objects.

Exam trap

The trap here is that candidates often confuse tags (which are for job template filtering and RBAC) with group variables (which are for host-level data), leading them to select option C despite tags having no role in variable assignment.

How to eliminate wrong answers

Option B is wrong because assigning variables directly to each host via the 'Host Variables' field creates significant administrative overhead when managing many hosts, as each host must be individually configured, and it does not scale well for environment-wide changes. Option C is wrong because tags in Ansible Tower are used for job template filtering and access control, not for variable assignment; variables cannot be conditionally applied based on tags within an inventory. Option D is wrong because creating separate inventories for each environment increases administrative overhead by requiring multiple inventory objects to be maintained and linked to the same project, and it does not leverage the single-inventory structure specified in the question.

116
MCQeasy

A playbook registers the output of a shell command that returns a JSON string. You need to parse this JSON string into a usable dictionary within the same play. Which filter should you apply to the registered variable?

A.json_query
B.from_yaml
C.to_json
D.from_json
AnswerD

The `from_json` filter parses a JSON-formatted string and returns the corresponding Python data structure, such as a dictionary or list. This is exactly what is needed to convert the registered stdout string into an accessible dictionary for subsequent tasks.

Why this answer

When a command returns JSON as a string, the registered variable stores that string, not a parsed object. The `from_json` filter is specifically designed to deserialize JSON strings into Ansible data structures, enabling direct access to nested keys. Using the wrong direction or a query filter would not achieve the required parsing.

Exam trap

The trap here is confusing `from_json` with `to_json`; the former parses a string into data, while the latter serializes data into a string.

117
MCQmedium

You are reviewing an Ansible playbook that uses the `ansible.builtin.shell` module to run a command that includes a sensitive API key as an argument. You want to prevent the API key from being displayed in the job output. Which task-level directive should you add?

A.changed_when: false
B.no_log: true
C.ignore_errors: true
D.become: true
AnswerB

The `no_log` directive, when set to true on a task, prevents Ansible from logging the task's output, including the command and its arguments. This ensures that the sensitive API key passed to the shell module is not displayed in job output. It is the correct task-level control to suppress logging of sensitive data. It works regardless of the module used, as long as it is applied to the task.

Why this answer

The `no_log: true` directive on a task suppresses all logging for that task, including the command line and its output. This prevents the sensitive API key from appearing in job output. The other directives control privilege escalation, error handling, or change reporting, none of which affect logging of task details.

Therefore, `no_log` is the correct choice.

Exam trap

The trap here is assuming that other task directives like `become` or `ignore_errors` might hide output, when only `no_log` controls logging.

118
MCQmedium

A playbook must write a sensitive token to a remote managed node's /etc/app/token.conf file. The security team requires that the token never appear in plaintext in the playbook or in the controller's job output. The token is stored in an Ansible Vault-encrypted variable file. Which task implementation best meets these requirements?

A.Use the shell module with a command that echoes the token into the file and redirect the output to /dev/null.
B.Use the copy module with content: "{{ vault_token }}" and set no_log: true on the task.
C.Use the lineinfile module with line: "token={{ vault_token }}" and rely on Vault encryption alone.
D.Use the template module with a Jinja2 template that contains the token literal and add no_log: true.
AnswerB

The copy module writes the decrypted token to the managed node without exposing it in logs when no_log is true. The variable is sourced from the vault-encrypted file, so the playbook itself contains no plaintext. This satisfies both the no-plaintext-in-playbook and no-leak-in-output requirements.

Why this answer

The copy module with content and no_log: true ensures the decrypted vault variable is written to the remote file while suppressing sensitive task output. Storing the token only in the vault-encrypted file keeps the playbook free of plaintext. The other approaches either embed the secret in a template or allow the expanded token to be logged, violating the security requirements.

Exam trap

The trap here is assuming that Vault encryption alone prevents secrets from appearing in job output; it protects the variable file at rest but does not suppress task logging.

119
MCQhard

A playbook that manages user accounts must run a task that passes a decrypted service account password to a command. Job output currently shows the password in the task result. Which change ensures the password is not displayed while keeping the task functional?

A.Run the playbook with --diff to show only changes and hide unchanged task output.
B.Add the password variable to a vault-encrypted file and reference it with vars_files.
C.Set display_skipped_hosts and display_ok_hosts to false in ansible.cfg.
D.Set no_log: true on the task so its output is suppressed in the job log.
AnswerD

no_log: true suppresses the task's return data, including any values that would otherwise be printed in the job output. The task still executes and returns success or failure, but the sensitive argument such as the password is masked. This is the supported Ansible mechanism for hiding task output that would otherwise expose decrypted secrets.

Why this answer

Ansible renders task return data in the job output, so any secret passed as an argument or registered value can leak. Applying no_log: true to the specific task suppresses that output while leaving the task's execution intact. This is the targeted control for hiding sensitive values at runtime, complementing vault encryption that only protects data at rest.

Exam trap

The trap here is believing that encrypting a variable with Ansible Vault also hides it at runtime, when vault only protects the file on disk and no_log is required to mask the decrypted value in job output.

120
MCQhard

A build of an execution environment fails with an error that ansible-builder cannot find the collection acme.internal.utils in any configured Galaxy server. The collection exists on the private Automation Hub, and the build host can reach it. The execution-environment.yml lists the collection under dependencies.galaxy pointing to requirements.yml. What is the most likely cause?

A.The collection name in requirements.yml must be prefixed with the Galaxy server name, such as hub_internal.acme.internal.utils.
B.The ansible.cfg used by ansible-builder does not define the private Automation Hub as a Galaxy server with valid credentials.
C.The execution environment base image does not include ansible-galaxy, so collection installation is skipped.
D.The collection version in requirements.yml is pinned to a version that does not exist on the private Automation Hub.
AnswerB

If ansible-builder's ansible.cfg lacks the private Automation Hub entry or its token, the build will not authenticate to that server and will report the collection as unfindable. Even though the host can reach the Hub, the builder must be told the server URL and token to resolve the collection during the build.

Why this answer

The error indicates the collection cannot be found in any configured Galaxy server. Since the collection exists on the private Automation Hub and the host can reach it, the most likely cause is that the ansible.cfg used by ansible-builder does not define that Hub with valid credentials. Without the server URL and token, the builder cannot authenticate and will not see the collection.

Exam trap

The trap here is assuming network reachability is sufficient, when ansible-builder also needs the Galaxy server and token declared in its ansible.cfg.

121
Multi-Selecthard

Which THREE considerations are important when designing a credential strategy in Ansible Automation Platform? (Choose exactly three.)

Select 3 answers
A.All credentials must be stored within the AAP database for security
B.Playbooks should contain hardcoded credentials for simplicity
C.Credentials should be assigned to job templates rather than embedded in playbooks
D.Custom credential types allow integration with external secrets management systems
E.Credential access can be restricted using RBAC on organizations, teams, and users
AnswersC, D, E

Best practice is to manage credentials via AAP and assign them to templates.

Why this answer

Ansible Automation Platform (AAP) best practices dictate that credentials should be assigned to job templates, not embedded in playbooks. This decouples sensitive authentication data from automation logic, allowing credentials to be managed, rotated, and audited centrally through the AAP controller without exposing them in version-controlled playbook files.

Exam trap

The trap here is that candidates often assume all credentials must be stored inside the AAP database for security, but the platform is designed to delegate secret storage to external vaults, and the question tests awareness of that flexibility.

122
MCQhard

An administrator wants to define role dependencies. In which file should they place the dependencies declaration?

A.vars/main.yml
B.defaults/main.yml
C.tasks/main.yml
D.meta/main.yml
AnswerD

Role dependencies are declared under the dependencies key inside meta/main.yml within the role directory. Ansible reads this file during role loading and runs each listed dependency before the role's own tasks, satisfying the declaration requirement.

Why this answer

Role dependencies in Ansible are declared in the `meta/main.yml` file using the `dependencies` key. This allows you to specify other roles that must be executed before the current role, ensuring prerequisite tasks are run automatically.

Exam trap

The trap here is that candidates often confuse `meta/main.yml` with `tasks/main.yml` or variable files, assuming dependencies are defined in the task list or variable defaults, but Ansible specifically reserves `meta/main.yml` for role metadata including dependencies, author info, and supported platforms.

How to eliminate wrong answers

Option A is wrong because `vars/main.yml` is used to define variables for the role, not dependencies. Option B is wrong because `defaults/main.yml` is used to set default variable values, which have the lowest precedence and are not for dependencies. Option C is wrong because `tasks/main.yml` contains the main list of tasks to execute in the role, not dependency declarations.

123
Multi-Selectmedium

Which three of the following are valid methods to pass variables to an Ansible playbook at runtime? (Choose three.)

Select 3 answers
A.Using '--extra-vars' command line option.
B.Using '--ask-vault-pass' and storing variables in encrypted files.
C.Using 'environment' directive in the playbook.
D.Using 'vars_prompt' in the playbook.
E.Using '-e @file' to load variables from a JSON file.
AnswersA, D, E

Correct: This directly passes variables or file paths.

Why this answer

The `--extra-vars` (or `-e`) command-line option allows you to pass variables directly to an Ansible playbook at runtime. This overrides any previously defined variables and can accept key=value pairs or load from JSON/YAML files, making it the primary method for runtime variable injection.

Exam trap

The trap here is confusing variable injection methods with authentication or environment configuration; candidates often mistake `--ask-vault-pass` or `environment` for runtime variable passing, when they serve entirely different purposes in Ansible's architecture.

124
Multi-Selectmedium

An automation team must ensure that sensitive variables used in playbooks are protected both at rest and during job execution in Ansible Automation Platform. Which TWO actions should be taken? (Choose two.)

Select 2 answers
A.Store the vault password in the project repository as a plaintext file for easy access.
B.Mark tasks that use sensitive variables with no_log: true to prevent values from appearing in job output.
C.Define sensitive variables in group_vars/all in plaintext so they are available to all hosts.
D.Enable verbose logging with -vvv to capture all variable values for auditing.
E.Store sensitive variables in an Ansible Vault-encrypted file and provide the vault password through a controller credential.
AnswersB, E

The no_log: true directive suppresses task output, preventing expanded sensitive variables from being displayed in job logs. While it does not protect data at rest, it addresses runtime exposure in job output, complementing vault encryption for a complete protection strategy.

Why this answer

Encrypting sensitive variables with Ansible Vault and supplying the vault password via a controller credential protects data at rest, while no_log: true prevents runtime exposure in job output. Plaintext group_vars, verbose logging, and repository-stored vault passwords all undermine security and fail to meet the dual protection requirement.

Exam trap

The trap here is focusing only on encryption at rest and forgetting that job output can leak decrypted secrets unless no_log: true is applied to tasks handling sensitive data.

125
MCQeasy

A junior admin wants to remove a credential from Ansible Tower. Which role-based access control permission is required to delete a credential?

A.Read
B.Use
C.Execute
D.Admin
AnswerD

Deleting a credential is an administrative operation, so the Admin role is required; lesser roles such as Auditor or Execute only grant read or job-run rights. This satisfies the stem's requirement for the permission that authorises credential deletion.

Why this answer

In Ansible Tower, the Admin role is the only role that grants full management permissions, including the ability to delete credentials. Lower-level roles like Read, Use, and Execute only allow viewing or using credentials, not modifying or deleting them. This aligns with Tower's RBAC hierarchy where Admin is required for destructive actions on any resource.

Exam trap

The trap here is that candidates often confuse the 'Use' role with full management permissions, but 'Use' only allows credential consumption in job templates, not deletion or modification.

How to eliminate wrong answers

Option A is wrong because the Read role only allows viewing credentials, not deleting them. Option B is wrong because the Use role permits using a credential in a job template but does not grant deletion rights. Option C is wrong because the Execute role applies to job templates and projects, not to credential management, and does not include delete permissions.

126
MCQeasy

An organization has a set of common tasks used in many playbooks. The tasks are updated frequently. What is the most maintainable way to share them?

A.Create a role and store it in a local directory referenced by ansible.cfg.
B.Copy the task files into each project repository.
C.Package the tasks into a collection and install it via ansible-galaxy.
D.Use include_tasks with a relative path from each playbook.
AnswerC

Collections bundle roles, modules and plugins with versioning, so frequently updated shared tasks can be distributed and pinned via ansible-galaxy. This satisfies the maintainability constraint by centralising updates rather than duplicating task files across playbooks.

Why this answer

Ansible Collections provide a centralized, versioned, and distributable way to package and share tasks, roles, modules, and plugins. Using `ansible-galaxy collection install` allows teams to manage updates from a single source (e.g., Automation Hub or a private Galaxy server), ensuring all playbooks use the latest version without manual file copying or path dependencies.

Exam trap

Red Hat often tests the misconception that local file paths or roles are sufficient for sharing tasks, but the EX294 exam emphasizes centralized, version-controlled distribution via Collections as the most maintainable approach for frequently updated shared content.

How to eliminate wrong answers

Option A is wrong because storing a role in a local directory referenced by `ansible.cfg` (via `roles_path`) ties the tasks to a specific filesystem location, making it difficult to version, distribute, or update across multiple control nodes or CI/CD pipelines. Option B is wrong because copying task files into each project repository leads to duplication, version drift, and increased maintenance overhead when tasks are updated frequently. Option D is wrong because using `include_tasks` with a relative path creates tight coupling to the playbook's directory structure, breaking if the playbook is moved or executed from a different working directory, and offers no versioning or distribution mechanism.

127
MCQhard

After rotating the Ansible Vault password in the automation controller, several job templates that use vault credentials start failing with 'decryption failed'. The vault credential has been updated with the new password. What is the most likely cause of the failure?

A.The automation controller needs a restart to apply the new vault credential.
B.The vault file in the project repository still uses the old vault password and needs to be re-encrypted with the new password.
C.The vault credential is not linked to the job template correctly.
D.The vault credential type requires the old password to be stored separately.
AnswerB

Re-encrypting the vault file with the new password is required because Ansible Vault decrypts file contents using the password embedded at encryption time. Updating the credential in the automation controller only changes the password supplied at runtime; the repository file still carries ciphertext derived from the old password, so decryption fails until re-encrypted.

Why this answer

The vault file itself is encrypted with a specific password. When the vault password is rotated in the automation controller, the vault file stored in the project repository is still encrypted with the old password. The job template uses the vault credential to decrypt the file, but since the credential now holds the new password, decryption fails.

The vault file must be re-encrypted with the new password using `ansible-vault rekey` or by decrypting and re-encrypting it.

Exam trap

The trap here is that candidates assume updating the vault credential in the controller is sufficient, but they overlook that the vault file itself must be re-encrypted with the new password.

How to eliminate wrong answers

Option A is wrong because the automation controller does not require a restart to apply updated vault credentials; credential changes are applied dynamically to subsequent job runs. Option C is wrong because the vault credential is correctly linked to the job template (as stated in the scenario), and the failure is due to a password mismatch, not a linkage issue. Option D is wrong because the vault credential type does not require storing the old password separately; the credential simply stores the current password used for decryption.

128
MCQmedium

An admin attempts to run this playbook as a job template in AAP. The job fails with 'ERROR! 'now' is not a valid attribute for a task'. What is the issue?

A.The template task is missing quotes around the file paths.
B.The playbook has an incorrect indentation in the tasks block.
C.The 'become' directive is placed incorrectly at the play level.
D.The 'now' attribute does not exist; it may be a typo for 'notify' or should be removed.
AnswerD

Ansible rejects unknown task keywords, so 'now' cannot be parsed as a valid task attribute. It is not a real module or directive; the playbook likely intended 'notify' or the line should be deleted entirely.

Why this answer

The error message 'ERROR! 'now' is not a valid attribute for a task' indicates that Ansible does not recognize 'now' as a valid task attribute. The 'now' keyword is not a standard Ansible directive; it is likely a typo for 'notify' (used with handlers) or should be removed entirely. Ansible validates task attributes against a strict schema, and any unknown attribute causes a parsing failure.

Exam trap

The trap here is that candidates may misread 'now' as a valid Jinja2 filter or confuse it with a module parameter, but Ansible strictly validates task attributes at parse time, not runtime.

How to eliminate wrong answers

Option A is wrong because missing quotes around file paths would cause a syntax error or a 'file not found' error, not an 'invalid attribute' error. Option B is wrong because incorrect indentation in the tasks block would produce a YAML parsing error (e.g., 'mapping values are not allowed here'), not an attribute validation error. Option C is wrong because placing 'become' at the play level is valid and would not generate an error about 'now'; it would either work or cause a privilege escalation error, not an attribute error.

129
MCQmedium

An organization uses automation controller and has multiple teams. They want to create an inventory that automatically includes all hosts from a cloud provider that belong to the 'production' tag, and this inventory should be accessible only to the SRE team. What is the correct way to achieve this?

A.Create a smart inventory with a filter for tag 'production' and assign the SRE team the 'read' role on that inventory.
B.Create a static inventory file and restrict access via a custom script.
C.Use groups in the inventory and assign all production hosts to a group, then restrict access to that group.
D.Create a dynamic inventory plugin in each playbook and include a condition to check team membership.
AnswerA

A smart inventory applies a host filter against the existing inventory source, dynamically including only hosts tagged 'production' without manual maintenance. Assigning the SRE team the 'read' role on that inventory object enforces the access constraint, since automation controller RBAC grants visibility per inventory rather than globally.

Why this answer

A smart inventory in automation controller allows you to dynamically filter hosts from an existing source (like a cloud provider) based on criteria such as tags. By creating a smart inventory with a filter for the 'production' tag, you automatically include all matching hosts. Assigning the SRE team the 'read' role on that inventory restricts access to only that team, meeting both requirements without manual updates.

Exam trap

The trap here is that candidates confuse smart inventories with static groups or assume that playbook-level conditions can replace inventory-level RBAC, but automation controller enforces access control strictly at the inventory object level, not within playbook logic or group membership.

How to eliminate wrong answers

Option B is wrong because a static inventory file would require manual updates and cannot automatically include hosts from a cloud provider based on a tag; custom scripts do not integrate with automation controller's role-based access control (RBAC) for inventory-level permissions. Option C is wrong because groups within an inventory do not provide independent access control; RBAC in automation controller is applied at the inventory level, not at the group level, so restricting access to a group would not prevent users from seeing other hosts in the same inventory. Option D is wrong because dynamic inventory plugins are defined at the inventory level, not per playbook, and checking team membership in a playbook condition does not enforce access control at the inventory level; it would only skip tasks, not prevent the inventory from being visible or accessible.

130
Multi-Selectmedium

An administrator is configuring a new Red Hat Ansible Automation Platform 2.5 installation and must connect the automation controller to a private automation hub so that certified and validated collections can be pulled during project syncs. The administrator wants the controller to authenticate to the hub and resolve collections automatically. Which TWO actions should the administrator take to accomplish this? (Choose two.)

Select 2 answers
A.Set the organization's Galaxy credential to the created hub credential and add the hub to the list of enabled Galaxy servers.
B.Edit ansible.cfg on each execution node to add the private hub URL under the [galaxy_server] sections with a plaintext token.
C.Create a credential of type Ansible Galaxy/Automation Hub API Token in the controller and reference the hub URL and token.
D.Configure a webhook on the private automation hub that pushes collection metadata into the controller database on every change.
E.Publish the collections to the controller's local filesystem under /var/lib/awx/projects/collections and reference them with a relative path.
AnswersA, C

The controller resolves collections from the Galaxy servers configured for an organization. Assigning the hub credential to the organization and enabling the private hub as a Galaxy server ensures project syncs pull collections from the private hub using the stored token, completing the authenticated connection the administrator requires.

Why this answer

Connecting the controller to private automation hub requires a Galaxy/Automation Hub API Token credential holding the hub URL and token, plus assigning that credential to the organization and enabling the hub as a Galaxy server. Together these let project syncs authenticate and download certified or validated collections automatically.

Exam trap

The trap here is assuming that editing ansible.cfg on execution nodes or sideloading collections replaces the controller's own Galaxy server and credential configuration.

131
MCQeasy

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

Roles bundle tasks, handlers, defaults and templates into a reusable, structured unit that playbooks can invoke via the roles keyword or include_role. This satisfies the requirement to reuse firewall configuration tasks across multiple playbooks without duplication.

Why this answer

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.

Exam trap

The trap here is confusing roles with other reusable components like variables or handlers, leading candidates to think that storing tasks in a vars file or using handlers can achieve the same cross-playbook reuse.

How to eliminate wrong answers

Option B is wrong because the inventory file defines hosts and groups, not reusable task logic; adding tasks to an inventory file is syntactically invalid and would not execute them. Option C is wrong because vars files store variables, not tasks; including a vars file with `include_vars` cannot run tasks. Option D is wrong because handlers are special tasks triggered by notifiers only when a change occurs, not designed for general-purpose reuse across playbooks.

132
MCQhard

A company wants to implement a rolling update for a stateful application where hosts cannot be updated in parallel due to data consistency. They also need to ensure that if any host fails, the entire update is rolled back. Which strategy meets these requirements?

A.Use serial: 2 and any_errors_fatal: yes
B.Use serial: 1 and ignore_errors: yes
C.Use serial: 0 and max_fail_percentage: 0
D.Use serial: 1 and any_errors_fatal: yes
AnswerD

Serial: 1 forces strictly sequential host updates, preventing parallel changes that would corrupt shared stateful data. Any_errors_fatal: yes aborts the entire play on the first failure, triggering rollback rather than leaving remaining hosts partially updated, meeting both the consistency and rollback constraints.

Why this answer

Setting `serial: 1` ensures hosts are updated one at a time, preventing parallel updates that could break data consistency for a stateful application. Adding `any_errors_fatal: yes` causes the entire playbook run to abort immediately if any host fails, which satisfies the requirement for a full rollback on failure.

Exam trap

The trap here is that candidates often confuse `serial: 1` with `serial: 0` or think `max_fail_percentage: 0` alone triggers a rollback, but `any_errors_fatal` is required to abort the entire playbook immediately on any failure, not just stop the current batch.

How to eliminate wrong answers

Option A is wrong because `serial: 2` allows two hosts to be updated in parallel, violating the requirement that hosts cannot be updated simultaneously due to data consistency. Option B is wrong because `ignore_errors: yes` causes Ansible to continue the update even if a host fails, which prevents the required rollback on failure. Option C is wrong because `serial: 0` is invalid (serial must be a positive integer or a percentage string), and `max_fail_percentage: 0` only stops the batch if 0% of hosts fail, which is effectively the same as `any_errors_fatal` but does not trigger a rollback of the entire update—it only halts further batches without reverting completed changes.

133
MCQeasy

Which file is required to define the content of an Ansible execution environment when using ansible-builder?

A.Dockerfile
B.requirements.yml
C.ansible.cfg
D.execution-environment.yml
AnswerD

The execution-environment.yml file defines an execution environment's content, specifying the base image, Galaxy dependencies, Python requirements and additional build files that ansible-builder consumes. Without it, ansible-builder has no definition to construct the container image from.

Why this answer

The `execution-environment.yml` file is the required definition file for `ansible-builder` because it specifies the base image, custom dependencies (Python, system, or collections), and additional build instructions needed to construct a containerized Ansible execution environment. Without this file, `ansible-builder` has no manifest to process, as it is the sole input that defines the environment's content.

Exam trap

The trap here is that candidates confuse the generated `Dockerfile` (an output artifact) with the required input file, or they assume `requirements.yml` is the main definition because it is commonly used for collection installation in playbooks, but `ansible-builder` specifically requires `execution-environment.yml` as the blueprint.

How to eliminate wrong answers

Option A is wrong because a `Dockerfile` is not required; `ansible-builder` generates a `Dockerfile` automatically from the `execution-environment.yml` definition, so providing one manually would override the builder's logic and is not the required input. Option B is wrong because `requirements.yml` is an optional file used to list Ansible collections for installation, but it is not the primary definition file; it can be referenced within `execution-environment.yml` under the `dependencies` section. Option C is wrong because `ansible.cfg` is a configuration file for Ansible's runtime behavior (e.g., inventory, roles path, forks) and has no role in defining the content of an execution environment for `ansible-builder`.

134
MCQmedium

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
AnswerD

Listing Python packages in requirements.txt lets ansible-builder install them into the execution environment image during the build, resolving the missing-dependency failure. The bindep.txt file handles system-level packages instead, so requirements.txt is the correct file for the Python dependencies the stem requires.

Why this answer

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.

Exam trap

The trap here is that candidates confuse `bindep.txt` (for system packages) with `requirements.txt` (for Python packages), as both are used in execution environment builds but serve different dependency types.

How to eliminate wrong answers

Option A is wrong because `meta/runtime.yml` is used to define runtime dependencies and compatibility for Ansible collections, not for specifying Python packages for an execution environment. Option B is wrong because `galaxy.yml` is a metadata file for Ansible collections, used to define collection name, version, and dependencies, not for listing Python packages. Option C is wrong because `bindep.txt` is used to specify system-level package dependencies (e.g., for apt or yum), not Python packages.

135
Multi-Selectmedium

Which TWO filters are commonly used to manipulate JSON data in Ansible? (Select exactly two.)

Select 2 answers
A.flatten
B.from_json
C.json_query
D.regex_replace
E.to_json
AnswersB, C

Parses a JSON string into a data structure.

Why this answer

(from_json) is correct because it converts a JSON string into an Ansible data structure (dict or list), enabling further manipulation with filters like json_query. This is essential when parsing API responses or configuration files that return JSON-formatted strings.

Exam trap

The trap here is that candidates often confuse to_json and from_json, thinking both are used for manipulation, but to_json is for serialization (output) while from_json is for deserialization (input), and json_query is the actual manipulation filter for querying JSON data.

136
MCQmedium

A playbook reads a JSON inventory file with `lookup('file', 'hosts.json') | from_json` and registers it as `hostdata`. The structure is a top-level dictionary where each key is a hostname and each value is a dictionary of attributes, for example `{"web1": {"env": "prod", "cpu": 4}, "db1": {"env": "dev", "cpu": 8}}`. You must build a list containing only the hostnames whose `env` attribute equals `prod`. Which task correctly produces that list?

A.- set_fact: prod_hosts: "{{ hostdata | dict2items | selectattr('value.env', 'equalto', 'prod') | map(attribute='value') | list }}"
B.- set_fact: prod_hosts: "{{ hostdata | dict2items | selectattr('env', 'equalto', 'prod') | map(attribute='key') | list }}"
C.- set_fact: prod_hosts: "{{ hostdata | dict2items | selectattr('value.env', 'equalto', 'prod') | map(attribute='key') | list }}"
D.- set_fact: prod_hosts: "{{ hostdata | selectattr('env', 'equalto', 'prod') | map(attribute='name') | list }}"
AnswerC

`dict2items` converts the mapping into a list of `{key, value}` pairs, so each item exposes the hostname under `key` and its attributes under `value`. `selectattr('value.env', 'equalto', 'prod')` keeps only prod entries, and `map(attribute='key')` extracts the hostnames into a list. This chain matches the nested data shape exactly.

Why this answer

Because the source is a dictionary keyed by hostname, it must first be turned into an iterable list of pairs with `dict2items`. Each pair then exposes the hostname as `key` and the attribute dictionary as `value`, so the environment test must reference `value.env`. Extracting `key` afterwards yields exactly the list of prod hostnames the task requires.

Exam trap

The trap here is assuming `selectattr` can filter a plain dictionary directly and that nested attributes are reachable without first converting the mapping with `dict2items`.

137
MCQeasy

Refer to the exhibit. What is the purpose of the 'failed_when' condition?

A.It fails the task only if the return code is non-zero and the error does not indicate 'not installed'.
B.It ensures the task never fails regardless of return code.
C.It fails the task only if the package is installed.
D.It fails the task if the package is not installed.
AnswerA

The failed_when condition overrides Ansible's default failure detection, so the task fails only when the return code is non-zero and the error output does not contain 'not installed'. This prevents a benign absence from being treated as a genuine failure.

Why this answer

The 'failed_when' condition in Ansible allows you to define custom failure criteria for a task. In the exhibit, the condition 'failed_when: result.rc != 0 and "not installed" not in result.stderr' means the task will only be marked as failed if the return code is non-zero AND the error message does not contain the string 'not installed'. This is useful when a command returns a non-zero exit code for expected reasons (e.g., package not found), and you want to treat that as a non-failure.

Exam trap

The trap here is that candidates assume 'failed_when' always causes failure when the condition is true, but they overlook that the condition is a logical AND of two parts, and the second part ('not installed' not in stderr) is a negative check that prevents failure when the expected error message appears.

How to eliminate wrong answers

Option B is wrong because 'failed_when' does not ensure the task never fails; it only defines custom failure conditions, and if the condition evaluates to false, the task may still fail based on the default behavior (non-zero return code). Option C is wrong because the condition does not check whether the package is installed; it checks the return code and the presence of 'not installed' in stderr, not the package installation status itself. Option D is wrong because the condition does not fail the task if the package is not installed; it actually prevents failure when the error indicates 'not installed', so it would not fail in that case.

138
MCQeasy

Refer to the exhibit. A playbook includes this vars file and runs `systemctl restart httpd`. The playbook fails because it cannot decrypt the vault. Which of the following is the most likely cause?

A.The vault ID is missing.
B.The variable db_password is not used in the playbook.
C.The vault password is not provided.
D.The vault file is corrupted.
AnswerC

Ansible Vault decrypts encrypted variables only when the vault password is supplied via --ask-vault-pass, a vault password file, or vault_password_file in ansible.cfg. Without it, decryption fails and the playbook aborts before systemctl restart httpd executes.

Why this answer

The error 'cannot decrypt the vault' indicates that Ansible is unable to decrypt the vault-encrypted variable file. This occurs when the vault password is not provided via `--ask-vault-pass`, `--vault-password-file`, or the `ANSIBLE_VAULT_PASSWORD_FILE` environment variable. Without the correct password, Ansible cannot decrypt the vault, causing the playbook to fail.

Exam trap

Red Hat often tests the distinction between vault ID (which is optional) and vault password (which is mandatory), leading candidates to incorrectly select 'vault ID is missing' when the actual issue is the missing password.

How to eliminate wrong answers

Option A is wrong because a vault ID is optional; Ansible can decrypt vaults without an ID if the password matches, and the error message does not indicate a missing ID. Option B is wrong because whether `db_password` is used in the playbook is irrelevant to the decryption failure; the vault file is loaded regardless of variable usage. Option D is wrong because a corrupted vault file would typically produce a different error (e.g., 'Vault format error' or 'HMAC mismatch'), not a generic 'cannot decrypt' message.

139
MCQhard

An administrator is using a role that includes a task file conditionally with 'include_tasks' inside a loop. The task file contains a handler notification. The administrator notices that the handler is not being triggered for each iteration. What is the most likely reason?

A.The handler is notified only once per host, regardless of how many times it is notified.
B.The handler must be defined inside the included task file, not in the main role.
C.Handlers cannot be notified from tasks included with 'include_tasks'.
D.The 'include_tasks' module does not support loops; 'import_tasks' must be used instead.
AnswerA

Handlers in Ansible are designed to run only once per host, even if notified multiple times. This is intentional to avoid redundant service restarts. In a loop with 'include_tasks', each iteration may notify the handler, but it will only be triggered once at the end of the play. This explains why the handler is not triggered for each iteration, as the administrator might expect.

Why this answer

Handlers run only once per host per play, even if notified multiple times. In a loop with 'include_tasks', each iteration may notify the handler, but it will execute only once at the end of the play. This is by design to prevent multiple restarts.

The other options misstate limitations or requirements that do not exist.

Exam trap

The trap here is assuming handlers run once per notification, when they actually run once per host per play.

140
MCQmedium

Refer to the exhibit. The administrator wants to run a playbook that installs a package on all webservers. Which command will use the existing configuration and inventory correctly?

A.ansible-playbook -e 'ansible_python_interpreter=/usr/bin/python3' site.yml
B.ansible-playbook site.yml
C.ansible webservers -m package -a 'name=httpd state=present'
D.ansible-playbook -i inventory site.yml
AnswerB

ansible-playbook site.yml runs the playbook using the default ansible.cfg and inventory already present in the working directory, so existing host groupings such as webservers are honoured without extra flags. This matches the requirement to use the existing configuration and inventory correctly.

Why this answer

The command 'ansible-playbook site.yml' uses the default Ansible configuration file (ansible.cfg) and the default inventory location defined there. If the administrator has already configured the inventory and other settings in ansible.cfg, this command will correctly target the webservers group as defined in the playbook. No extra flags are needed because the existing configuration is assumed to be in place.

Exam trap

The trap is that candidates may think they need to specify the inventory explicitly with '-i' or provide interpreter variables, but the question states 'existing configuration and inventory correctly,' implying the default configuration already handles it.

How to eliminate wrong answers

Option A is wrong because it passes an extra variable for the Python interpreter, which is unnecessary if the inventory or ansible.cfg already specifies it, and it does not address inventory selection. Option C is wrong because it uses an ad-hoc ansible command rather than running the playbook, and it does not execute the playbook's tasks or use the playbook's logic. Option D is wrong because it explicitly specifies '-i inventory', which may override the configured inventory path and cause the playbook to use a different inventory than intended, potentially missing the webservers group.

141
MCQhard

An administrator must parse an inventory file where hostnames are stored in YAML format under a list 'nodes'. The task needs to extract only hostnames that contain 'prod' in the name, then sort them in reverse order. Which combination of filters in a single Ansible expression achieves this?

A.nodes | select('match', '.*prod.*') | sort(reverse=True)
B.nodes | regex_search('prod') | sort(True)
C.nodes | map('regex_search', 'prod') | sort(reverse=True)
D.nodes | reject('match', '.*prod.*') | sort(reverse=True)
AnswerA

The select filter with match applies the regex '.*prod.*' to each node, keeping only hostnames containing prod, and sort(reverse=True) orders the survivors descending. This single chained expression satisfies both the filtering and reverse-sorting constraints in one evaluation.

Why this answer

The `select` filter with the `match` test returns only list items that match the regex `'.*prod.*'`, i.e., hostnames containing 'prod'. The `sort(reverse=True)` then sorts the resulting list in descending alphabetical order, fulfilling both requirements in a single Ansible expression.

Exam trap

The trap here is that candidates often confuse `select` (which keeps matching items) with `reject` (which removes matching items), or mistakenly use `regex_search` or `map` thinking they will filter the list, when in fact those filters return substrings or transformed values, not the original list elements.

How to eliminate wrong answers

Option B is wrong because `regex_search` returns matched substrings, not the original hostnames, and `sort(True)` is invalid syntax (must be `sort(reverse=True)`). Option C is wrong because `map('regex_search', 'prod')` returns a list of matched substrings (or empty strings for non-matches), not the original hostnames, and would fail to filter properly. Option D is wrong because `reject('match', '.*prod.*')` excludes hostnames containing 'prod', which is the opposite of the required selection.

142
MCQhard

You are performing a rolling update of a 15-node RHEL cluster with an Ansible playbook that uses `serial: 5`. During the second batch, a host fails to restart its application service, and the task fails. You want the playbook to stop the entire rollout immediately so that no further batches are updated, allowing you to investigate the failure. Which play keyword should you set to achieve this behavior?

A.`max_fail_percentage: 0`
B.`ignore_errors: false` on the service restart task.
C.`serial: 1`
D.`any_errors_fatal: true`
AnswerD

Setting any_errors_fatal to true causes the play to abort immediately when any task fails on any host, stopping the entire rollout across all batches. This matches the requirement to halt further updates as soon as the service restart failure occurs, allowing investigation before continuing.

Why this answer

To stop the entire play immediately when any task fails on any host, the play must set any_errors_fatal to true. This keyword overrides the default behavior where a failed host is removed and other hosts continue, causing the whole run to abort as soon as the failure occurs. It is the correct mechanism for halting a rolling update on the first error.

Exam trap

The trap here is assuming that max_fail_percentage or serial adjustments will stop the rollout immediately, when any_errors_fatal is the keyword that aborts the play on the first task failure across all hosts.

143
MCQeasy

An automation team wants to build an execution environment that includes a specific collection from a private Automation Hub. Which file must be present in the build context to specify the collection and its source?

A.execution-environment.yml
B.galaxy.yml
C.bindep.txt
D.requirements.yml
AnswerD

`requirements.yml` is used by `ansible-builder` to list Ansible collections and roles that should be installed into the execution environment. It can specify collections from Automation Hub, including private sources, by using the `source` key or by configuring the server in `ansible.cfg`. This file is essential for including the collection.

Why this answer

To include a collection in an execution environment, `ansible-builder` reads `requirements.yml` from the build context. This file lists collections (and roles) to install, and can specify the source server, making it the correct place to declare a collection from a private Automation Hub.

Exam trap

The trap here is confusing the execution environment definition file (`execution-environment.yml`) with the requirements file that actually lists collections.

144
MCQhard

Refer to the exhibit. After the playbook run fails on the 'Verify config' task, what happens to the 'restart service' handler?

A.The handler runs immediately after the failed task.
B.The handler is not executed because the playbook failed before the end of the play.
C.The handler runs on the next playbook run.
D.The handler is executed because it was notified before the failure.
AnswerB

Handlers are deferred until the end of the play, so a failed task aborts the play before that point and the notify never triggers execution. The restart service handler therefore does not run, satisfying the stem's failure-before-end-of-play condition.

Why this answer

Handlers are notified but only run at the end of the play if notified. However, if a subsequent task fails, the playbook stops, and handlers are not executed unless the 'force_handlers' option is set.

145
MCQmedium

Based on the exhibit, what is the purpose of the `galaxy` dependency entry?

A.Set the base container image.
B.Define which Ansible collections to install in the execution environment.
C.Specify Python packages to install via pip.
D.Configure environment variables for the container.
AnswerB

The `galaxy` entry specifies Ansible collections and roles that the execution environment must include, satisfying the requirement to declare dependencies for the automation content. During image build, ansible-builder reads this key and installs the listed collections into the container, ensuring the playbook's modules are available at runtime.

Why this answer

In the context of Ansible execution environments (EEs), the `galaxy` key within the `dependencies` section of the `execution-environment.yml` file specifies a list of Ansible collections to be installed from Ansible Galaxy or an Automation Hub. This allows the EE to include the necessary content collections required for playbook execution, ensuring all roles and modules are available inside the container.

Exam trap

Red Hat often tests the distinction between `galaxy` (for Ansible collections) and `python` (for pip packages) in the `dependencies` section, leading candidates to confuse the two or assume `galaxy` installs Python packages.

How to eliminate wrong answers

Option A is wrong because the base container image is defined by the `base_image` key in the `execution-environment.yml` file, not by the `galaxy` dependency entry. Option C is wrong because Python packages to install via pip are specified under the `python` key within `dependencies`, not under `galaxy`. Option D is wrong because environment variables for the container are configured using the `environment` key in the `execution-environment.yml` file, not through the `galaxy` dependency entry.

146
MCQmedium

An administrator maintains a role named 'webserver' that is used by several teams. The role must run a handler named 'restart httpd' after a configuration file is changed, but only when the role is included with a variable 'notify_handler' set to true. The role's tasks/main.yml currently has a task that copies httpd.conf with 'notify: restart httpd'. Which change should the administrator make in the role to ensure the handler is notified only when 'notify_handler' is true?

A.Add 'run_once: true' to the handler and set 'notify_handler' in the role's defaults/main.yml.
B.Add 'listen: "{{ notify_handler }}"' to the handler and notify the handler with 'notify: "{{ notify_handler }}"'.
C.Add 'when: notify_handler | bool' to the handler definition in handlers/main.yml.
D.Add 'when: notify_handler | bool' to the task that copies httpd.conf in tasks/main.yml.
AnswerD

Placing the conditional on the task that copies the configuration file ensures the task only runs when 'notify_handler' is true. Because notification occurs only when a task reports 'changed', the handler will be notified only if the copy task actually executes and changes the file. This directly meets the requirement and is the standard Ansible pattern for conditionally notifying handlers from within a role.

Why this answer

The handler is notified only when a task reports a change. To make notification conditional, the condition must be applied to the task that performs the change and notifies the handler. Adding a 'when' clause to the copy task ensures the task runs only when 'notify_handler' is true, so the handler is queued only in that case.

Conditions on handlers themselves do not prevent notification from being queued.

Exam trap

The trap here is assuming that a 'when' condition on a handler prevents the handler from being notified, when in fact it only controls whether the handler runs after being queued.

147
MCQeasy

An administrator needs to encrypt a sensitive variable file 'secrets.yml' using Ansible Vault so that it can be safely stored in a Git repository. The file should remain encrypted at rest but be automatically decrypted during playbook runs when the vault password is supplied. Which command correctly creates the encrypted file?

A.ansible-vault rekey secrets.yml --new-vault-password-file newpass.txt
B.ansible-vault create secrets.yml --encrypt-vault-id default
C.ansible-vault encrypt_string secrets.yml --name secrets
D.ansible-vault encrypt secrets.yml --vault-password-file vault_pass.txt
AnswerD

The ansible-vault encrypt command encrypts an existing file in place, and --vault-password-file specifies the file containing the vault password. This produces an encrypted secrets.yml that Ansible can decrypt at runtime when the same password file is provided, meeting the requirement for secure storage and automatic decryption.

Why this answer

The ansible-vault encrypt command is the correct tool to encrypt an existing plaintext file. Using --vault-password-file provides the password non-interactively, enabling automation. The resulting file remains encrypted at rest and is decrypted automatically during playbook runs when the same vault password is supplied.

Exam trap

The trap here is confusing ansible-vault encrypt with create or encrypt_string, which serve different purposes, or using rekey on a plaintext file.

148
Multi-Selectmedium

Which TWO statements about Ansible Execution Environments (EE) are true?

Select 2 answers
A.Execution environments are primarily used for developing new Ansible modules.
B.Execution environments use ansible-navigator as the default entrypoint.
C.Execution environments are container images built with ansible-builder.
D.Execution environments package Ansible Core, collections, and Python dependencies.
E.Execution environments can only be used with the ansible-navigator command-line tool.
AnswersC, D

Ansible-builder is the supported tool that assembles execution environments, producing a container image from an execution-environment definition file. The resulting image is what ansible-navigator or AWX runs, satisfying the requirement that EEs are container images.

Why this answer

Option C is correct because Ansible Execution Environments are defined in an execution-environment.yml file and built into container images using the ansible-builder tool, producing OCI-compliant images that bundle everything needed to run automation. Option D is correct because an EE image packages ansible-core, the required Ansible collections, and their Python dependencies (plus system packages) into a single portable container, ensuring consistent runtime environments. Option A is incorrect because EEs are runtime artifacts for executing playbooks and roles, not a development framework for authoring new modules.

Option B is incorrect because ansible-navigator is a CLI tool that consumes EEs, not the default entrypoint inside the image (the entrypoint is typically the ansible-runner based execution). Option E is incorrect because EEs are standard container images and can be run with podman, docker, ansible-runner, AWX/Controller, and other tools, not exclusively ansible-navigator.

Exam trap

The trap here is that candidates may confuse the purpose of execution environments (packaging and running automation) with module development, or assume that `ansible-navigator` is the only way to use them, when in fact they are container images that can be used with multiple Ansible tools.

149
MCQmedium

A playbook uses the `ansible.builtin.uri` module to interact with a REST API. The API requires a Bearer token that is stored in an encrypted variable file. The playbook must ensure the token is not exposed in logs. Which approach best meets the requirement?

A.Set `ANSIBLE_DEBUG` to false in the environment.
B.Set `no_log: true` on the task that uses the `uri` module.
C.Encrypt the variable file with `ansible-vault` and reference it in the playbook.
D.Use `vars_prompt` to ask for the token at runtime.
AnswerB

The no_log directive prevents the task's output, including any sensitive data like tokens, from being logged or displayed. When set to true on the uri task, Ansible will not show the module arguments or results, which could contain the Bearer token. This is the standard way to protect secrets from being exposed in logs or console output during playbook execution.

Why this answer

To prevent a sensitive token from appearing in logs, the task that uses the token must have no_log set to true. This suppresses all output from that task, including module arguments and results. While vault encrypts the token at rest, it does not prevent logging during execution.

Therefore, no_log is the necessary control in this scenario.

Exam trap

The trap here is assuming that encrypting the variable file with ansible-vault automatically prevents the token from being logged.

150
MCQeasy

Which directive in an Ansible playbook ensures that a task runs only on the first host in a batch, and results are applied to all hosts?

A.run_once
B.any_errors_fatal
C.throttle
D.delegate_to: localhost
AnswerA

`run_once` executes the task on a single host — the first in the batch — while its results are applied to every host in the play. This satisfies the stem's constraint of limiting execution to one host yet propagating outcomes to all, avoiding redundant operations across the batch.

Why this answer

The run_once directive ensures that a task is executed only on the first host in the current batch of hosts. The results of that task are then applied to all hosts in the play. This is useful for tasks that should only be performed once, such as database migrations or generating a shared token, while still making the outcome available to all hosts.

Exam trap

EX294 often tests the distinction between run_once and other execution control directives like throttle and any_errors_fatal, and candidates may confuse run_once with delegate_to when both are used together.

How to eliminate wrong answers

Option B is wrong because any_errors_fatal causes the entire play to abort if any host fails a task, which is unrelated to running a task on a single host. Option C is wrong because throttle limits the number of hosts that execute a task concurrently, but it does not restrict execution to only the first host. Option D is wrong because delegate_to: localhost runs the task on the control node instead of the target hosts, but it does not ensure that the task runs only once; it would run for each host unless combined with other directives like run_once.

Page 1

Page 2 of 6

Page 3

All pages