Courseiva

Red Hat Certified Engineer EX294 (EX294) — Questions 301–375

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

Page 4

Page 5 of 6

Page 6
301
MCQmedium

An automation architect is deploying Red Hat Ansible Automation Platform 2.4 on a RHEL 9 control node. The setup bundle has been extracted, and the admin runs `./setup.sh` from the installer directory. During the pre-flight checks, the installer reports that the PostgreSQL database is not reachable and aborts. The admin confirms that the database server is running and that the inventory file contains the correct hostname. Which action should the admin take to resolve the installation failure?

A.Edit the inventory file to set `pg_port=5432` and `pg_ssl=false` to force a plain-text connection to the database.
B.Disable the firewall on the automation controller node using `systemctl stop firewalld` and rerun `./setup.sh`.
C.Re-run the installer with the `--skip-preflight` flag to bypass the database check and complete the installation.
D.Verify that the `pg_hba.conf` file on the database server allows connections from the automation controller node and that the `postgresql` service is listening on the correct network interface.
AnswerD

The installer's pre-flight check validates database connectivity using the credentials and hostname in the inventory. If the database is running but not accepting remote connections, it is typically due to `pg_hba.conf` restrictions or the service binding only to localhost. Ensuring the database allows connections from the controller node and listens on the correct interface resolves the failure.

Why this answer

The installer's pre-flight check verifies that the automation controller can reach the PostgreSQL database using the inventory-defined host and credentials. When the database service is running but unreachable, the most common causes are restrictive `pg_hba.conf` entries or the service binding only to the loopback interface. Verifying these settings ensures the controller can establish the required connection.

Exam trap

The trap here is assuming that a running database service automatically accepts remote connections, when host-based authentication or interface binding may still block the controller.

302
MCQhard

Refer to the exhibit. The administrator runs the playbook with the 'deploy' tag, but all tasks are skipped. What is the most likely reason?

A.The --tags option filters tasks; only tasks with the 'deploy' tag run, but none of the role tasks have that tag.
B.The role 'database' is not found in the roles_path.
C.The inventory host db1.example.com is not in the dbservers group.
D.The tags in the role tasks conflict with the play tags, causing a syntax error.
AnswerA

The `--tags deploy` filter runs only tasks carrying that tag, so untagged role tasks are skipped entirely. Since Ansible applies tag filtering at task level and roles do not inherit tags from the play, every task lacking an explicit `deploy` tag is excluded, producing the all-skipped output described in the stem.

Why this answer

Ansible's --tags option filters task execution so that only tasks tagged with the specified tag(s) run. If the playbook is executed with '--tags deploy' but none of the tasks inside the 'database' role have the 'deploy' tag applied, all tasks are skipped. This is the most likely reason given the symptom that all tasks are skipped rather than an error being raised.

Exam trap

EX294 often tests the misconception that tags applied at the play or role-inclusion level automatically propagate to all tasks inside a role — they do not unless 'apply' or explicit task tags are used, leading to silent skips.

How to eliminate wrong answers

Option B is wrong because if the role 'database' were not found in roles_path, Ansible would raise a fatal error ('role not found') rather than silently skipping all tasks. Option C is wrong because if the host were not in the 'dbservers' group, the play would simply have no hosts to run against (or skip the host), but the symptom described is that tasks are skipped, which points to tag filtering. Option D is wrong because tag conflicts do not cause syntax errors — tags are additive and non-conflicting; Ansible would not fail with a syntax error due to tag mismatches.

303
MCQhard

Your inventory directory `inventory/prod` contains a static hosts file plus a group_vars subdirectory with webservers.yml. A dynamic inventory plugin in the same directory returns the group `webservers` with a host-level variable `http_port` set to 8080. The static group_vars/webservers.yml sets `http_port: 80`. When a play runs against the webservers group, which value does the managed host receive for http_port?

A.80, because the static inventory directory is processed after the dynamic plugin.
B.80, because group_vars files always override variables supplied by inventory plugins.
C.8080, because a host-level variable from the plugin outranks a group-level variable from group_vars.
D.The play fails with a conflicting variable definition error.
AnswerC

Ansible's variable precedence places host variables above group variables, regardless of whether the host value comes from a dynamic plugin or a static file. Because http_port is returned as a host variable by the plugin, it takes priority over the group-level definition in group_vars/webservers.yml, so the host receives 8080 when the play runs.

Why this answer

Variable precedence in Ansible is hierarchical rather than source-based: host variables outrank group variables, and more specific group levels outrank broader ones. Because the dynamic plugin attaches http_port to the individual host, that value sits above the group-level definition in group_vars. The managed host therefore receives 8080 even though the static group file specifies 80.

Exam trap

The trap here is assuming static group_vars always beats dynamic plugin data, when precedence depends on whether the value is host-level or group-level.

304
MCQmedium

An automation engineer manages two data centers with Ansible Automation Platform 2.4. The production inventory file is located at /etc/ansible/prod_inventory.ini and the staging inventory at /etc/ansible/stage_inventory.ini. The engineer wants to run a playbook against both inventories in a single ansible-playbook command, but the host groups must remain separate so that group_vars/prod and group_vars/stage apply correctly. Which command should the engineer use?

A.ansible-playbook --inventory=/etc/ansible/prod_inventory.ini --inventory=/etc/ansible/stage_inventory.ini site.yml
B.ansible-playbook -i /etc/ansible/prod_inventory.ini,/etc/ansible/stage_inventory.ini site.yml
C.ansible-playbook -i /etc/ansible/prod_inventory.ini /etc/ansible/stage_inventory.ini site.yml
D.ansible-playbook -i /etc/ansible/prod_inventory.ini -i /etc/ansible/stage_inventory.ini site.yml
AnswerD

Multiple -i flags are supported by ansible-playbook; each inventory source is parsed independently and merged into a single inventory. Groups with the same name are combined, but distinct groups like prod and stage remain separate, so group_vars directories are applied correctly. This command meets the requirement without altering the inventory files.

Why this answer

Ansible supports multiple inventory sources by repeating the -i option. Each source is parsed separately and merged, preserving distinct group names so that group_vars directories are applied based on group membership. Using a single -i with a comma-separated list or additional positional arguments does not achieve the same result and will cause errors.

Exam trap

The trap here is assuming that a comma-separated list of files can be passed to a single -i option, when in fact -i must be repeated for each inventory source.

305
MCQhard

Given `{{ ['1', '2', '3'] | map('int') | list }}`, what is the result?

A.An error because 'int' is not a valid filter name.
B.`[1, 2, 3]`
C.`['1', '2', '3']` as integers, but stored as strings.
D.`['1', '2', '3']`
AnswerB

The map filter applies the int filter to each element of the list, converting the strings '1', '2' and '3' into integers. The subsequent list filter materialises the generator into an actual list, yielding [1, 2, 3].

Why this answer

The `map('int')` filter in Ansible/Jinja2 converts each string element in the list to an integer. The `list` filter then materializes the generator into a list, resulting in `[1, 2, 3]`. Option B is correct because this is the standard behavior of the `map` filter with the `int` function.

Exam trap

The trap here is that candidates may think 'int' is a filter name rather than a Python function passed to `map`, or they may forget that `map` returns a generator that must be converted to a list with the `list` filter to see the result.

How to eliminate wrong answers

Option A is wrong because 'int' is a valid built-in function name for the `map` filter in Jinja2/Ansible, not a filter name itself, and it does not cause an error. Option C is wrong because the `map('int')` filter explicitly converts strings to actual integers, not 'integers stored as strings' — that would be a contradiction. Option D is wrong because it shows the original string list unchanged, ignoring the conversion performed by `map('int')`.

306
MCQhard

Your team maintains a collection that depends on a module requiring the Python library netaddr. You are building an execution environment with ansible-builder and need that library available inside the image at run time. The collection itself is installed from a private Automation Hub. Which approach ensures the Python dependency is present in the execution environment?

A.Add netaddr to the requirements.txt referenced by the dependencies.python section of execution-environment.yml.
B.List netaddr under dependencies.galaxy in execution-environment.yml so ansible-galaxy installs it with the collection.
C.Install netaddr on the control node and rely on the module using the control node's Python environment.
D.Add netaddr to the collection's runtime.yml under the requires_ansible key.
AnswerA

The dependencies.python section of execution-environment.yml points to a requirements.txt that ansible-builder installs into the image. Listing netaddr there ensures the Python library is present for the module at run time. This is the supported way to add Python packages to an execution environment and works regardless of where the collection itself is hosted.

Why this answer

Python libraries needed by modules must be installed into the execution environment image during the build. The dependencies.python section of execution-environment.yml references a pip requirements file, and listing netaddr there causes ansible-builder to install it into the image. Collection metadata and Galaxy dependency lists do not install Python packages, and installing on the control node has no effect inside the container.

Exam trap

The trap here is confusing collection dependencies with Python dependencies, leading to placing a pip package in the Galaxy requirements list.

307
MCQeasy

A developer wants to create a new Ansible collection from a skeleton template. Which command should be used?

A.`ansible-galaxy collection generate my_namespace.my_collection`
B.`ansible-galaxy collection create my_namespace.my_collection`
C.`ansible-galaxy collection start my_namespace.my_collection`
D.`ansible-galaxy collection init my_namespace.my_collection`
AnswerD

`ansible-galaxy collection init` scaffolds the namespace.collection skeleton, generating galaxy.yml, plugins, roles and docs directories. The stem requires creating a new collection from a template, and this subcommand is the only one that produces that structure rather than installing or building an existing collection.

Why this answer

The correct command is `ansible-galaxy collection init my_namespace.my_collection`, which creates a new collection skeleton with the required directory structure and metadata files. This is the official Ansible command for bootstrapping a collection from a template.

Exam trap

The trap here is that candidates often confuse the `ansible-galaxy` subcommands for roles (`init` for roles) with those for collections, or they misremember the verb as `create` or `generate`, which are not valid for collection initialization.

How to eliminate wrong answers

Option A is wrong because `ansible-galaxy collection generate` is not a valid subcommand; the correct verb is `init`. Option B is wrong because `ansible-galaxy collection create` does not exist; `create` is used for roles, not collections. Option C is wrong because `ansible-galaxy collection start` is not a valid Ansible command; `start` is not a recognized subcommand for collections.

308
MCQmedium

An administrator maintains a role named 'webserver' whose tasks reference the variable 'http_port'. The playbook calls the role twice within the same play, first with http_port set to 8080 and then with http_port set to 8443, expecting two differently configured deployments. After the run, both deployments use port 8443. Which change to the role invocation should the administrator make so each invocation uses its own value?

A.Define http_port in group_vars for every managed host in the inventory.
B.Pass the variable with the 'vars' keyword on the 'roles' entry for each invocation.
C.Declare http_port in the role's defaults/main.yml and override it with set_fact before each role entry.
D.Add 'allow_duplicates: true' to the role's meta/main.yml file and pass the variable on the command line with -e.
AnswerB

Variables supplied through the 'vars' keyword on a role entry are scoped to that individual role invocation, so the first call receives 8080 and the second receives 8443 independently. This is the documented way to parameterize the same role multiple times inside one play without the values bleeding between invocations.

Why this answer

Each entry in the 'roles' list is a separate role invocation, and the 'vars' keyword attached to that entry scopes the supplied variables to that invocation only. This lets one role run twice in the same play with different parameter values. Inventory variables, defaults, extra variables, or persistent facts all resolve at host or play scope, so they cannot differentiate the two calls.

Exam trap

The trap here is believing that adding allow_duplicates alone gives each role call its own variables, when it only permits the duplicate role to run.

309
MCQmedium

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

A.Use 'serial: 1' and delegate load balancer disable/enable tasks to localhost, ensuring each node is taken out of rotation before updating.
B.Run the update playbook with 'serial: 10' to update all nodes at once, then run a separate playbook to update the load balancer.
C.Run the update on each node manually using 'ansible-playbook --limit' and skip load balancer management to save time.
D.Use 'strategy: free' to allow nodes to update independently without controlling the load balancer.
AnswerA

Using `serial: 1` updates one node at a time, so the remaining nine keep serving traffic. Delegating the load balancer disable and enable tasks to localhost runs them once from the controller rather than on each managed node, satisfying the rolling-update constraint of removing a node from rotation before patching and restoring it afterwards.

Why this answer

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

Exam trap

The trap here is that candidates may think 'serial: 10' is efficient because it updates all nodes quickly, but they overlook that it causes a full outage, whereas the correct approach prioritizes availability over speed.

How to eliminate wrong answers

Option B is wrong because 'serial: 10' updates all nodes simultaneously, which would cause a complete outage during the update window, defeating the purpose of a rolling update. Option C is wrong because manually running with '--limit' and skipping load balancer management does not automate the process and leaves nodes in the load balancer pool while they are being updated, causing traffic to be sent to an unavailable node and increasing downtime. Option D is wrong because 'strategy: free' allows nodes to run tasks independently without any serialization or load balancer coordination, leading to potential race conditions and no guarantee of minimizing downtime.

310
MCQeasy

An Ansible administrator wants to use an encrypted vault file to store sensitive variables. Which command creates a new vault file and prompts for a password?

A.ansible-vault edit secrets.yml
B.ansible-vault create secrets.yml
C.ansible-vault view secrets.yml
D.ansible-vault encrypt secrets.yml
AnswerB

ansible-vault create secrets.yml generates a new encrypted file and prompts for the vault password, then opens the editor for content entry. The create subcommand is specifically designed for new vault files, unlike encrypt, which converts an existing plaintext file.

Why this answer

`ansible-vault create secrets.yml` creates a new encrypted vault file and immediately prompts the user to set a password, which is then used to encrypt the file. This command is specifically designed for initial creation of vault files, unlike `edit` which requires an existing file, `view` which only displays content, or `encrypt` which encrypts an existing plaintext file.

Exam trap

The trap here is that candidates confuse `ansible-vault create` with `ansible-vault encrypt`, mistakenly thinking both create new files, but `encrypt` requires an existing plaintext file while `create` generates a new encrypted file from scratch.

How to eliminate wrong answers

Option A is wrong because `ansible-vault edit` opens an existing vault file for editing, not creating a new one; it requires the file to already exist and be encrypted. Option C is wrong because `ansible-vault view` displays the decrypted content of an existing vault file without prompting for a new password or creating a file. Option D is wrong because `ansible-vault encrypt` encrypts an existing plaintext file into a vault file, but does not create a new file from scratch; it expects the file to already exist in plaintext.

311
MCQeasy

Refer to the exhibit. An Ansible playbook task fails with 'Missing sudo password'. The playbook runs against a server where the remote user 'admin' has sudo privileges but requires a password. Which configuration change would resolve this issue?

A.Set ansible_become_password or use the -K flag when running the playbook.
B.Change become_method to su to avoid password prompts.
C.Remove the become_user line and rely on default root.
D.Change become_user to root.
AnswerA

Supplying the sudo password via `ansible_become_password` or the `-K` prompt lets Ansible satisfy the privilege-escalation credential the remote user requires. The stem's constraint is that `admin` holds sudo rights but sudo demands a password; without that secret, become fails with 'Missing sudo password'. This directly resolves it.

Why this answer

The error 'Missing sudo password' occurs because Ansible needs the sudo password for the remote user. Option A provides the password either by setting ansible_become_password in inventory or using the -K flag to prompt for it. Option B is incorrect because switching to su does not solve the password issue and is unnecessary.

Option C is incorrect because removing become_user doesn't address the password requirement. Option D is incorrect because changing become_user to root doesn't provide the needed password.

312
MCQhard

A playbook must run only against hosts that belong to both the `webservers` group and the `production` group. Your inventory defines these as separate groups, and a host named web3 is a member of both. Which inventory pattern restricts the play's hosts to exactly that intersection?

A.hosts: webservers:production
B.hosts: webservers[production]
C.hosts: webservers:&production
D.hosts: webservers:!production
AnswerC

The ampersand prefix introduces an intersection constraint, so the pattern selects only hosts that are members of webservers and also members of production. Because web3 belongs to both groups, it is included, while hosts in just one group are excluded. This is the documented syntax for intersecting group membership in a play's hosts line.

Why this answer

Ansible group patterns use colon-prefixed operators: a leading ampersand means intersection, a leading exclamation mark means exclusion, and a bare colon means union. Placing an ampersand before the second group limits the selection to hosts that are members of both groups, which matches the requirement that only hosts in webservers and production be targeted by the play.

Exam trap

The trap here is reading the colon as an intersection when it actually forms a union, and confusing the ampersand intersection operator with exclusion.

313
MCQmedium

The playbook uses the community.general.parse_csv filter. Assuming the collection is installed, what is the type and structure of the 'parsed' variable?

A.A list of dictionaries: [{'name': 'Alice', 'age': '30'}, {'name': 'Bob', 'age': '25'}]
B.A single string: 'Alice,30\nBob,25'
C.A list of strings: ['name,age', 'Alice,30', 'Bob,25']
D.A dictionary: {'Alice': '30', 'Bob': '25'}
AnswerA

The community.general.parse_csv filter converts CSV text into a list of dictionaries, using the header row as keys and each subsequent row as values. Fields remain strings, so age appears as '30' rather than an integer, matching the structure shown.

Why this answer

The `community.general.parse_csv` filter in Ansible parses CSV content into a list of dictionaries, where the first row is treated as headers and subsequent rows become dictionaries with those headers as keys. Option A correctly describes this output: a list of dictionaries with keys 'name' and 'age' and corresponding string values.

Exam trap

The trap here is that candidates confuse `parse_csv` with `split` or `regex_replace` filters, assuming it returns raw strings or a single dictionary, rather than understanding it returns a list of dictionaries with header-based keys.

How to eliminate wrong answers

Option B is wrong because `parse_csv` does not return a single string; it returns structured data, not raw CSV text. Option C is wrong because it describes a list of strings (each row as a string), but `parse_csv` parses the CSV into dictionaries, not raw strings. Option D is wrong because it suggests a single dictionary mapping names to ages, but `parse_csv` returns a list of dictionaries, one per data row, not a flat mapping.

314
MCQmedium

Refer to the exhibit. A user runs ansible-runner with --container-image localhost/ee-30:latest and receives the error shown. What is the most likely cause?

A.The container image tag is incorrect.
B.The ansible-runner process does not have network access.
C.The execution environment is not listed in the project's execution-environment.yml.
D.The container image has not been pulled or built locally.
AnswerD

ansible-runner does not pull images automatically. With --container-image localhost/ee-30:latest, the image must already exist in the local container storage; if it was never pulled or built, the runtime cannot resolve the reference and fails immediately.

Why this answer

The error indicates that the container image `localhost/ee-30:latest` is not available locally. The `--container-image` flag tells ansible-runner to use a specific execution environment image, but if that image has not been pulled from a registry or built locally, the container runtime (e.g., Podman or Docker) cannot find it. Option D is correct because the image must exist in the local container storage before ansible-runner can launch it.

Exam trap

Red Hat often tests the distinction between local image availability and network access, leading candidates to incorrectly assume that ansible-runner automatically pulls missing images when it does not by default.

How to eliminate wrong answers

Option A is wrong because the tag `latest` is valid and the error does not mention an invalid tag format; a missing image error would occur regardless of tag correctness if the image is not present. Option B is wrong because the error message indicates the image is not found locally, not that network access is blocked; ansible-runner does not attempt to pull the image when `--container-image` is used unless `--container-option` or `--container-pull` is explicitly set. Option C is wrong because the execution-environment.yml file is used by Automation Controller (formerly Ansible Tower) to define execution environments for job templates, not by the `ansible-runner` command-line tool; ansible-runner directly uses the image specified via `--container-image`.

315
MCQhard

A company has a large infrastructure with over 1000 servers. They run a playbook that configures NTP on all servers. The playbook takes over 30 minutes due to sequential execution. The team wants to reduce execution time. Which approach should they take?

A.Use serial: 10 to batch hosts.
B.Set forks: 50 and strategy: free.
C.Use include_tasks to parallelize tasks.
D.Use ansible-pull on each server.
AnswerB

Raising forks lets Ansible run the play across 50 hosts concurrently instead of sequentially, and the free strategy lets each host proceed independently rather than waiting at task barriers. Together these cut wall-clock time across the 1000-server fleet.

Why this answer

Ansible's default forks value is 5, meaning only five hosts are configured concurrently, which explains the 30-minute runtime across 1000 servers. Raising forks to 50 increases parallelism, and the free strategy lets each host proceed through tasks independently without waiting for all hosts to finish each task, further reducing wall-clock time.

Exam trap

The trap is choosing serial thinking it means 'more parallel'; serial actually throttles batch size, and the exam expects you to know forks and strategy are the real parallelism levers.

How to eliminate wrong answers

Option A is wrong because serial: 10 limits execution to batches of 10 hosts, which reduces parallelism and would make the playbook slower, not faster. Option C is wrong because include_tasks is a static/dynamic task inclusion mechanism; it does not parallelize execution across hosts. Option D is wrong because ansible-pull inverts the model to have each host pull its own configuration, which changes the architecture but does not directly address the sequential execution bottleneck in the existing push-based playbook.

316
Multi-Selectmedium

Which TWO statements about inventory groups in Ansible Automation Platform are correct? (Choose exactly two.)

Select 2 answers
A.A host can belong to multiple groups
B.Inventory groups can be used in smart inventories as filter criteria
C.Host variables are the only way to define variables for a host
D.Groups cannot be members of other groups
E.Dynamic inventory sources cannot produce groups
AnswersA, B

A host can be a member of multiple groups, e.g., 'webservers' and 'production'.

Why this answer

Ansible's inventory system allows a host to belong to multiple groups simultaneously. This is a fundamental feature of Ansible's inventory model, enabling flexible host organization and variable inheritance from all parent groups.

Exam trap

The trap here is that candidates often assume groups cannot be nested or that dynamic inventories cannot produce groups, but Ansible explicitly supports both features, and the exam tests understanding of these flexible inventory capabilities.

317
MCQhard

An admin imports this inventory into AAP and assigns a machine credential that uses SSH key authentication. The job fails with 'Authentication failed'. What is the most likely cause?

A.The private key file path in the inventory does not exist on the controller.
B.The credential's SSH key is not being used because the inventory variable ansible_ssh_private_key_file conflicts.
C.The machine credential does not contain an SSH private key.
D.The 'ansible_become' variable is missing from the inventory.
AnswerC

SSH key authentication requires the machine credential to hold the private key matching the public key on the managed host. Without that private key stored in the credential, Ansible cannot authenticate, producing the 'Authentication failed' error.

Why this answer

In Red Hat Ansible Automation Platform (AAP), when a machine credential is assigned to a host, that credential's SSH key is used for authentication. If the credential does not contain an SSH private key, authentication will fail. Credentials take precedence over inventory variables such as ansible_ssh_private_key_file, so a conflict is not the likely cause.

Therefore, the most likely cause is that the machine credential is missing its SSH private key.

318
Multi-Selecteasy

A managed node is configured with an Ansible vault-encrypted variable file. When running a playbook that uses these variables, the user receives a 'decryption failed' error. Which two steps should the user take to resolve the issue?

Select 2 answers
A.Verify the file permissions are set to 600.
B.Check that the SSH private key has access to the managed node.
C.Make sure the vault password file contains the path to the vault file.
D.Ensure the vault ID matches the one used when encrypting the file.
E.Verify the correct vault password is being provided.
AnswersD, E

Vault matches decryption to the vault ID recorded in the file's header. If the playbook supplies a different ID, or none, decryption fails even with the right password, so aligning the vault ID used at encryption with the one supplied at runtime resolves it.

Why this answer

Option D is correct because Ansible vault supports multiple vault IDs, and if the playbook or ansible-vault command specifies a vault ID that differs from the one used at encryption time, decryption will fail with a 'decryption failed' error; the vault ID must match exactly. Option E is correct because the most common cause of a vault decryption failure is supplying the wrong vault password, whether via --ask-vault-pass, --vault-password-file, or the ANSIBLE_VAULT_PASSWORD_FILE environment variable, so verifying the correct password resolves the error. Option A is not correct because file permissions of 600 affect access control, not the cryptographic decryption of vault contents.

Option B is not correct because SSH private key access to the managed node is unrelated to decrypting a local vault-encrypted variable file. Option C is not correct because a vault password file should contain the password itself, not the path to the vault file, so that step is technically inaccurate.

Exam trap

The trap here is that candidates often assume 'decryption failed' always means a wrong password, overlooking that Ansible vault IDs must match exactly when multiple vault passwords are in use.

319
MCQeasy

A team wants to ensure that a sensitive variable, such as a database password, is not printed when ansible-playbook runs with -v (verbose). What is the best method to achieve this?

A.Set the password as an environment variable on the control node.
B.Store the password in a file with 0600 permissions and use lookup('file', ...).
C.Use the 'no_log: true' directive on the task.
D.Use the 'ansible-vault encrypt_string' command and reference the variable from a vault file.
AnswerC

The no_log: true directive suppresses a task's output, including variable values, from verbose ansible-playbook runs. Applying it to the task handling the database password prevents that sensitive value being printed at -v, directly meeting the stem's requirement.

Why this answer

The `no_log: true` directive explicitly prevents Ansible from printing the value of any variable used in that task to the console, even when verbosity is increased with `-v`. This is the most direct and secure method to ensure sensitive data like passwords are not exposed in output logs, as it overrides the default logging behavior at the task level.

Exam trap

Red Hat often tests the misconception that encrypting data at rest (e.g., with vault or file permissions) is sufficient to prevent exposure during execution, but the real risk is runtime output in verbose logs, which only `no_log: true` addresses.

How to eliminate wrong answers

Option A is wrong because setting the password as an environment variable on the control node does not prevent Ansible from printing its value when the task uses it; the variable's content will still be displayed in verbose output unless explicitly suppressed. Option B is wrong because using `lookup('file', ...)` to read a password from a file with 0600 permissions only protects the file at rest, but the variable's value will still be printed in verbose output when the task runs. Option D is wrong because `ansible-vault encrypt_string` encrypts the variable at rest, but when the variable is decrypted and used in a task, its value will still be printed in verbose output unless `no_log: true` is also applied.

320
MCQeasy

A developer wants to encrypt a string in a playbook variable file. Which command should they use?

A.ansible-vault rekey
B.ansible-vault create
C.ansible-vault edit
D.ansible-vault encrypt_string
AnswerD

The ansible-vault encrypt_string subcommand encrypts a single string value inline, producing ciphertext suitable for embedding directly in a variable file. This satisfies the requirement to encrypt one string rather than an entire file, which encrypt would handle.

Why this answer

`ansible-vault encrypt_string` is specifically designed to encrypt a single string value for use in a playbook variable file, without encrypting the entire file. This command outputs the encrypted string in a format that can be directly pasted into a YAML variable definition, preserving the rest of the file as plaintext.

Exam trap

The trap here is that candidates confuse encrypting a single string with encrypting an entire file, leading them to choose `ansible-vault create` or `ansible-vault edit` instead of the specific `encrypt_string` subcommand.

How to eliminate wrong answers

Option A is wrong because `ansible-vault rekey` is used to change the password of an already encrypted file, not to encrypt a string. Option B is wrong because `ansible-vault create` creates a new encrypted file from scratch, not a single string for a variable file. Option C is wrong because `ansible-vault edit` opens an existing encrypted file for modification, not to encrypt a new string.

321
MCQeasy

Which ansible.cfg setting controls the number of parallel forks for task execution?

A.parallel
B.max_parallel
C.forks
D.threads
AnswerC

The forks directive in the [defaults] section sets how many hosts Ansible configures concurrently, each fork being a separate worker process. Raising it increases parallelism across the inventory; leaving it at the default of five limits throughput on large host counts.

Why this answer

The `forks` setting in `ansible.cfg` (or the `ANSIBLE_FORKS` environment variable) controls the maximum number of parallel processes Ansible uses when executing tasks on remote hosts. By default, this value is 5, meaning Ansible will manage up to 5 hosts concurrently per playbook run. Increasing this value allows Ansible to operate on more hosts simultaneously, improving throughput in larger environments.

Exam trap

The trap here is that candidates may confuse Ansible's `forks` with generic terms like `parallel` or `threads`, or with similar settings from other configuration management tools, leading them to select a plausible-sounding but incorrect option.

How to eliminate wrong answers

Option A is wrong because `parallel` is not a valid Ansible configuration setting; Ansible uses the `forks` parameter to control parallelism. Option B is wrong because `max_parallel` does not exist in Ansible's configuration; it may be confused with a similar concept in other tools like Puppet or SaltStack. Option D is wrong because `threads` is not an Ansible configuration key; Ansible uses multiprocessing (fork-based) rather than threading for parallel execution, and `threads` is unrelated to the number of concurrent hosts.

322
MCQeasy

Which best practice should be followed when using Ansible to manage task execution across multiple hosts?

A.Use 'ignore_errors: yes' on all tasks to prevent playbook failures.
B.Ensure tasks are idempotent so they can be run multiple times without changing the system state beyond the desired state.
C.Always use serial execution to avoid race conditions.
D.Write tasks that rely on the previous task's output to ensure correct order.
AnswerB

Idempotence means repeated runs converge on the same desired state without side effects, which is essential when a play targets many hosts and some tasks may be retried or partially applied. It keeps multi-host execution predictable and safe.

Why this answer

Idempotency is a core principle of Ansible: running the same playbook multiple times should produce the same desired state without unintended side effects. This ensures predictable, safe task execution across multiple hosts, as Ansible modules are designed to check the current state before making changes.

Exam trap

The trap here is that candidates confuse 'ignore_errors' with a valid error-handling strategy, or assume serial execution is always safer, when in fact idempotency is the fundamental best practice that Ansible's design revolves around.

How to eliminate wrong answers

Option A is wrong because 'ignore_errors: yes' on all tasks would suppress legitimate failures, making debugging impossible and potentially leaving systems in an inconsistent or broken state. Option C is wrong because serial execution is not always necessary; Ansible's default parallel execution (via forks) is efficient and safe for idempotent tasks, and serial is only used for specific rolling-update scenarios. Option D is wrong because relying on previous task output creates tight coupling and non-idempotent workflows; Ansible encourages using facts, registered variables, and idempotent modules to maintain order without hard dependencies.

323
MCQhard

An administrator maintains a dynamic inventory script that outputs JSON. The script is placed at `/etc/ansible/inventory/aws_inventory.py` and is executable. The administrator runs `ansible-playbook -i /etc/ansible/inventory/aws_inventory.py site.yml` but receives an error: "Unable to parse /etc/ansible/inventory/aws_inventory.py as an inventory source". Which action is most likely to resolve the issue?

A.Ensure the script outputs a JSON object with a top-level key `_meta` containing `hostvars`, and that the script supports the `--list` argument.
B.Change the script's file extension to .json so Ansible recognizes it as a JSON inventory.
C.Make the script non-executable and pass it as a static inventory file.
D.Add the script path to the `inventory` setting in ansible.cfg and remove the -i option from the command.
AnswerA

Ansible dynamic inventory scripts must accept the --list argument and output JSON with groups and hosts. The _meta key is optional but recommended to provide hostvars efficiently. If the script does not support --list or outputs invalid JSON, Ansible cannot parse it. This is the most common cause of the parse error. Ensuring the script meets these requirements resolves the issue.

Why this answer

Dynamic inventory scripts must be executable and support the --list argument, returning valid JSON with groups and hosts. The _meta key with hostvars is recommended to avoid separate --host calls. The parse error typically occurs when the script fails to output valid JSON or does not handle --list.

The other options either misrepresent how Ansible detects dynamic inventories or take actions that would not fix the script's output.

Exam trap

The trap here is assuming that file extension or configuration location determines dynamic inventory parsing, when the critical factor is the script's executable behavior and JSON output for --list.

324
MCQeasy

A systems administrator is preparing to install Red Hat Ansible Automation Platform 2.4 on a RHEL 9 server. They have downloaded the installer tarball and extracted it. Which file must they edit to specify the target hosts and authentication credentials for the installation?

A.`group_vars/all.yml`
B.`ansible.cfg`
C.`inventory`
D.`setup.sh`
AnswerC

The AAP installer uses an inventory file, typically named `inventory`, located in the installer directory. This file defines the groups such as `[automationcontroller]`, `[automationhub]`, and `[database]`, and includes variables like `ansible_user`, `ansible_password`, and `ansible_become_password` for authentication. Editing this file is a required step before running `setup.sh`.

Why this answer

The AAP installer requires an inventory file where you list the target hosts under specific groups and provide authentication variables such as `ansible_user` and `ansible_password`. This file is typically named `inventory` and is located in the installer directory. Editing it is mandatory before running `setup.sh` to ensure the installer can connect to and configure the hosts.

Exam trap

The trap here is confusing the AAP installer inventory file with general Ansible configuration files like `ansible.cfg` or `group_vars`.

325
Multi-Selecthard

An administrator is using Ansible Vault to protect sensitive variables in an inventory project. The project has a vault-encrypted file 'secrets.yml' that contains the variable 'db_password'. The playbook needs to use this variable. Which TWO statements are correct about using vault-encrypted variables in this scenario? (Choose two.)

Select 2 answers
A.The variable db_password must be defined in a separate unencrypted file that references the encrypted one.
B.The vault password can be provided at runtime using the --ask-vault-pass option when running ansible-playbook.
C.The vault-encrypted file must be listed in the ansible.cfg file under the [defaults] section as vault_identity_list.
D.Vault-encrypted variables can only be used in playbooks, not in inventory variables.
E.A vault password file can be specified using the --vault-password-file option, and it can be a script that outputs the password.
AnswersB, E

The --ask-vault-pass option prompts for the vault password interactively when running ansible-playbook. This allows decryption of vault-encrypted files without storing the password in plain text. It is a secure and common method for providing the vault password during playbook execution, especially in interactive or ad-hoc runs.

Why this answer

Providing the vault password interactively with --ask-vault-pass or via a vault password file with --vault-password-file are both valid methods to decrypt vault-encrypted files. The password file can be a script that outputs the password, which is useful for automation. Vault-encrypted files can be used for any variables, including inventory variables, and do not require an unencrypted reference file.

Exam trap

The trap here is believing that vault-encrypted variables require special configuration like vault_identity_list or an unencrypted reference file, when they can be decrypted directly with a password provided at runtime.

326
MCQmedium

Refer to the exhibit. An Ansible playbook contains the following block structure. If the task inside the block fails, which of the following describes the execution order of the rescue and always sections?

A.Only always runs.
B.Only rescue runs.
C.Rescue runs, then always.
D.Always runs, then rescue.
AnswerC

When a task inside a block fails, Ansible transfers control to the rescue section, executing its tasks to handle the error. After rescue completes, the always section runs regardless of success or failure, ensuring cleanup tasks execute. This matches Ansible's documented block error-handling flow, satisfying the stem's requirement to describe execution order.

Why this answer

In Ansible, when a task inside a block fails, the rescue section executes to handle the failure, and then the always section runs unconditionally. This ensures that cleanup or finalization tasks are performed regardless of success or failure. Therefore, the correct execution order is rescue first, then always.

Exam trap

The trap here is that candidates often confuse the order of rescue and always, mistakenly thinking always runs first or that only one of them executes, when in fact rescue runs before always on failure.

How to eliminate wrong answers

Option A is wrong because the always section runs unconditionally, but the rescue section also runs when a task fails, so it is not the only section executed. Option B is wrong because the always section always runs after rescue, so rescue does not run alone. Option D is wrong because the always section runs after rescue, not before; the order is rescue then always, not always then rescue.

327
Multi-Selecteasy

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

Select 2 answers
A.Set ignore_errors: yes to ensure the playbook continues even if some hosts fail.
B.Use the serial keyword to update hosts in batches.
C.Use the default serial setting (all hosts) for simplicity.
D.Set max_fail_percentage to limit the number of failed hosts before aborting.
E.Run all hosts in parallel to minimize total update time.
AnswersB, D

The serial keyword partitions the play's host list into batches, so each batch completes before the next begins. This limits blast radius during rolling updates, satisfying the requirement to update hosts incrementally rather than all at once.

Why this answer

Option B is correct because the serial keyword in Ansible controls how many hosts are targeted per play iteration, allowing rolling updates in controlled batches (e.g., serial: 2 or serial: 25%) so that only a subset of hosts is updated at a time while the rest continue serving traffic. Option D is correct because max_fail_percentage defines a failure threshold within a serial batch; if the percentage of failed hosts exceeds that value, Ansible aborts the play, preventing a bad update from cascading across the entire fleet. Option A is not a best practice for rolling updates because ignore_errors: yes masks failures and lets the playbook proceed even when hosts are broken, defeating the safety purpose of batching.

Option C is wrong because the default serial value is effectively all hosts in the play, which performs a simultaneous update rather than a rolling one. Option E is also wrong because running all hosts in parallel maximizes blast radius and downtime risk, the opposite of a rolling-update strategy.

Exam trap

The trap here is that candidates often confuse `ignore_errors` with error handling for rolling updates, not realizing that it bypasses failure detection, whereas `max_fail_percentage` is the correct way to control abort behavior during batch updates.

328
MCQeasy

A playbook uses the `copy` module to distribute a configuration file to managed nodes. The file contains a sensitive API key. You want to ensure the API key is not visible in the playbook source or in Ansible logs. Which approach should you use?

A.Store the API key in an environment variable on the control node and use the `lookup` plugin `env` to inject it into the copy module.
B.Use the `copy` module with the API key hardcoded in the content parameter and rely on Ansible's automatic log redaction.
C.Use the `template` module with a Jinja2 template that includes the API key as a plaintext variable defined in the playbook.
D.Store the API key in a vault-encrypted variable file, reference it in the copy module's content parameter, and set no_log: true on the task.
AnswerD

Using a vault-encrypted variable file keeps the API key encrypted at rest and out of the playbook source. Referencing it in the content parameter allows the file to be generated with the secret. Setting no_log: true prevents the task output from displaying the secret in logs or console. Together, these measures protect the key in both storage and execution, meeting the requirement.

Why this answer

To protect a sensitive API key, it should be stored encrypted using Ansible Vault and referenced in the playbook without exposing plaintext. Marking the task with no_log: true prevents the secret from appearing in output or logs. Using plaintext variables, hardcoded values, or environment variables without no_log leaves the secret exposed in the playbook source or execution logs, failing the security requirement.

Exam trap

The trap here is assuming Ansible automatically hides sensitive data in module parameters, when only explicit no_log: true suppresses task output.

329
MCQhard

An Ansible playbook that deploys a web application includes a task that uses the `uri` module to call an external API. The task occasionally fails due to API rate limiting. Which combination of keywords should be added to the task to automatically retry up to 5 times with a 30-second delay between attempts, and only fail if all retries are exhausted?

A.`register: result`, `until: status == 200`, `retries: 5`, `delay: 30`
B.`register: result`, `until: result.status == 200`, `retries: 5`, `delay: 30`
C.`until: result.status == 200`, `retries: 5`, `delay: 30`
D.`register: result`, `retries: 5`, `delay: 30`
AnswerB

The `until` keyword loops the task until `result.status == 200`, satisfying the rate-limit constraint by re-polling the API. `retries: 5` caps attempts, while `delay: 30` inserts the required 30-second pause between them. `register` captures each response so the condition can be evaluated, and the task fails only once retries are exhausted.

Why this answer

It combines `register` to capture the API response, `until` to check that `result.status` equals 200 (the HTTP success code), `retries: 5` to attempt the task up to five times, and `delay: 30` to wait 30 seconds between retries. This ensures the task only fails after all five retries are exhausted, which is the exact behavior needed to handle transient API rate limiting.

Exam trap

Red Hat often tests the requirement that `register` must be used with `until` to reference the captured result, and that `retries`/`delay` are meaningless without `until` — candidates frequently omit `register` or forget to prefix the variable with `result.` in the condition.

How to eliminate wrong answers

Option A is wrong because it uses `status == 200` instead of `result.status == 200`; without referencing the registered variable, Ansible would look for a nonexistent `status` fact, causing a syntax or logic error. Option C is wrong because it omits `register: result`, so the `until` condition has no captured variable to check, leading to an undefined variable error. Option D is wrong because it lacks the `until` keyword entirely, meaning the task will not retry based on a condition; `retries` and `delay` alone only apply when `until` is present, so the task would run once and fail immediately.

330
MCQmedium

An administrator needs to run a playbook in check mode to preview changes on managed hosts, but a critical task using the `command` module must always execute regardless of check mode. Which task directive should be applied to that specific task?

A.`always_run: yes`
B.`ignore_errors: yes`
C.`run_once: true`
D.`check_mode: no`
AnswerD

Setting `check_mode: no` forces the task to run normally even when the playbook is executed with `--check`, overriding the global check mode for that task. This is the correct directive to ensure the command executes regardless of the playbook's check mode setting, allowing critical operations to proceed while other tasks are only simulated.

Why this answer

The `check_mode: no` task directive overrides the playbook-level check mode for that specific task, forcing it to execute normally even when `--check` is used. This is essential for tasks that must always run, such as those that gather facts or perform critical operations that should not be simulated.

Exam trap

The trap here is assuming that `always_run` still works in modern Ansible; it was deprecated and removed, so the correct directive is `check_mode: no`.

331
MCQeasy

A developer is creating a new content collection named acme.tools to distribute internal modules and roles. Which command initializes the collection with the standard directory skeleton, including the galaxy.yml metadata file?

A.ansible-galaxy collection init acme.tools
B.ansible-galaxy collection create acme.tools
C.ansible-builder create acme.tools
D.ansible-galaxy init acme.tools --type collection
AnswerA

The ansible-galaxy collection init command creates the collection directory structure and a galaxy.yml metadata file, which is the starting point for a new collection. It scaffolds the standard layout with roles, plugins, and other directories so the developer can begin adding content and later build and publish the collection.

Why this answer

To scaffold a new collection, use ansible-galaxy collection init followed by the namespace and collection name. This generates the standard directory layout and the galaxy.yml metadata file that describes the collection. Other ansible-galaxy subcommands such as build and publish operate on an existing collection, and ansible-builder is unrelated to collection initialization.

Exam trap

The trap here is using the role-oriented ansible-galaxy init form instead of the collection-specific subcommand.

332
MCQmedium

An administrator maintains a static inventory file at /home/student/inventory that defines a group 'webservers' and a group 'dbservers'. A host named 'web1.example.com' must belong to both groups. Which INI snippet correctly assigns web1.example.com to both groups without creating duplicate host entries?

A.[webservers] web1.example.com [dbservers] web1.example.com ansible_group=webservers
B.[webservers] web1.example.com [dbservers] web1.example.com
C.[webservers] web1.example.com [dbservers] web1.example.com:children
D.[webservers] web1.example.com [dbservers:children] webservers
AnswerB

This INI structure places web1.example.com under two distinct group headers. Ansible merges the host into both groups while maintaining a single host record, so group_vars for webservers and dbservers both apply. This is the standard, supported way to express overlapping group membership in a static inventory.

Why this answer

Placing the same hostname under two separate group headers is the correct way to give a host membership in multiple groups in an INI inventory. Ansible then treats the host as a single managed node that inherits variables from both groups, with group variable precedence rules resolving conflicts.

Exam trap

The trap here is assuming a host can belong to only one group or that a special variable is needed to add it to another group, when simply listing it under a second group header is sufficient.

333
MCQeasy

An automation team wants to grant a group of operators the ability to launch job templates in automation controller but prevent them from modifying the job template configuration. They also need to troubleshoot failed jobs by viewing job output. Which predefined role should be assigned to the team for a specific job template?

A.Execute role
B.Read role
C.Admin role
D.Update role
AnswerA

The Execute role grants permission to launch a job template and view its job output, without allowing edits to the template configuration. Assigning it on the specific job template satisfies both the launch and troubleshooting requirements.

Why this answer

The Execute role is the correct predefined role because it grants permission to launch a job template and view job output (including standard out and error logs) without allowing any modifications to the job template's configuration. This aligns exactly with the requirement: operators can execute and troubleshoot failed jobs but cannot edit the template.

Exam trap

The trap here is that candidates often confuse the Execute role with the Read role, assuming that Read allows launching jobs, when in fact Read only permits viewing the template and its output, not executing it.

How to eliminate wrong answers

Option B (Read role) is wrong because it only allows viewing the job template definition and job output, but does not include the permission to launch the job template. Option C (Admin role) is wrong because it grants full administrative privileges, including the ability to modify the job template configuration, which violates the requirement to prevent modifications. Option D (Update role) is wrong because it allows updating the job template's configuration, which is explicitly prohibited by the requirement.

334
MCQmedium

A playbook uses the 'debug' module to print a variable 'my_var' but the output is 'VARIABLE IS UNDEFINED'. The variable is defined in group_vars/all.yml. Which filter could be used to provide a default value and avoid this error?

A.{{ my_var | mandatory }}
B.{{ my_var | default('fallback') }}
C.{{ my_var | ternary('yes', 'no') }}
D.{{ my_var | dflt('fallback') }}
AnswerB

The default filter substitutes 'fallback' when my_var is undefined, preventing the undefined-variable error. It resolves the stem's problem because group_vars/all.yml evidently is not being loaded for this host, so the variable never reaches the template.

Why this answer

The `default` filter in Ansible provides a fallback value when a variable is undefined, preventing the 'VARIABLE IS UNDEFINED' error. Using `{{ my_var | default('fallback') }}` ensures that if `my_var` is not defined in group_vars/all.yml or any other precedence level, the string 'fallback' is used instead of causing a failure.

Exam trap

The trap here is that candidates may confuse the `default` filter with the `mandatory` filter, thinking that 'mandatory' provides a fallback, when in fact it enforces definition and causes an error if the variable is missing.

How to eliminate wrong answers

Option A is wrong because the `mandatory` filter forces the variable to be defined; if it is undefined, it raises an error, which is the opposite of providing a default value. Option C is wrong because the `ternary` filter evaluates a condition and returns one of two values based on truthiness, not a default for undefined variables. Option D is wrong because `dflt` is not a valid Ansible filter; the correct filter name is `default`.

335
MCQmedium

A playbook defines the variable `packages` as a list of dictionaries, each containing `name` and `version` keys. You need to build a new list of strings in the form `name-version` for use in a log message. Which filter combination produces this result?

A.{{ packages | map(attribute='name') | zip(packages | map(attribute='version')) | map('join', '-') | list }}
B.{{ packages | selectattr('name') | map('join', '-') | list }}
C.{{ packages | map('combine') | list }}
D.{{ packages | map('dict2items') | map('join', '-') | list }}
AnswerA

This expression extracts the `name` and `version` attributes from each dictionary, pairs them positionally with `zip`, then joins each pair with a hyphen using `map('join', '-')`. The final `list` materializes the result. It produces exactly the `name-version` strings required in the correct order.

Why this answer

Building `name-version` strings from a list of dictionaries requires extracting both attributes separately and then pairing them. The `zip` filter aligns the two extracted lists element-wise, and `map('join', '-')` converts each pair into a hyphenated string. Filters like `combine`, `dict2items`, and `selectattr` operate on different data shapes and do not produce the desired formatted strings.

Exam trap

The trap here is assuming `map('join', '-')` alone can combine two fields from the same dictionary, when it only joins elements within one list.

336
Multi-Selectmedium

You are writing a playbook that needs to transform a list of strings representing file paths. You want to extract only the base filenames (without directory paths) and ensure they are all lowercase. Which TWO filters should you use in your Jinja2 expression? (Choose two.)

Select 2 answers
A.lower
B.dirname
C.splitext
D.upper
E.basename
AnswersA, E

The `lower` filter converts a string to all lowercase characters. After extracting the base filename, applying `lower` ensures the result is consistently lowercase, which is useful for case-insensitive comparisons or standardizing output. It operates on strings and returns a new string.

Why this answer

To extract base filenames from full paths, the `basename` filter is the correct tool. To ensure the result is lowercase, the `lower` filter is applied afterward. Together they transform a list of paths into a list of lowercase filenames.

Other filters like `dirname`, `upper`, or `splitext` serve different purposes and do not meet the requirements.

Exam trap

The trap here is confusing `basename` with `dirname` or assuming that `splitext` can extract the filename from a path.

337
MCQeasy

A playbook targets a group of database servers and must run a backup task only on one host at a time, waiting for each host to finish before starting the next, so that a shared storage array is not saturated. Which play keyword should the administrator set to achieve this serialized behavior?

A.serial: 1
B.throttle: 1
C.order: sequential
D.strategy: host_pinned
AnswerA

The serial keyword controls how many hosts are taken from the play's host list and processed as a batch. Setting it to 1 makes Ansible complete the entire play on one host before moving to the next, which serializes execution and prevents simultaneous load on the shared storage array.

Why this answer

The serial keyword defines the batch size for a play, and a value of 1 forces Ansible to finish all tasks on one host before selecting the next host from the group. This produces strictly sequential execution across the targeted database servers, which is the desired protection for shared storage.

Exam trap

The trap here is confusing task-level concurrency controls such as throttle with play-level batching controlled by serial.

338
MCQmedium

A new technician runs a playbook that uses the yum module to install packages. The playbook fails with 'No package matching' for a custom package. The package is available on a third-party repository. Which step should the technician take?

A.Use the rpm_key module to import the GPG key.
B.Add the repository using the yum_repository module.
C.Use command: yum install directly.
D.Update the package cache using yum update.
AnswerB

The yum module resolves packages only from repositories already configured on the managed host. A third-party repository must first be defined, so the yum_repository module adds the repo definition before the install task runs, allowing the custom package to be found.

Why this answer

The yum module requires that the repository providing the package is already configured on the target system. Since the custom package is on a third-party repository, the technician must first add that repository using the yum_repository module. This module creates the necessary .repo file in /etc/yum.repos.d/, making the package available for installation via the yum module.

Exam trap

The trap here is that candidates may confuse the need to add a repository with other common tasks like importing GPG keys or updating the cache, assuming the package is simply not found due to stale metadata rather than a missing repository source.

How to eliminate wrong answers

Option A is wrong because importing a GPG key (rpm_key) is used to verify package signatures, not to add a repository or make packages available; the package is not found because the repository is missing, not because of a key issue. Option C is wrong because using command: yum install bypasses Ansible's idempotency and module benefits, and is not a best practice for package management in Ansible playbooks. Option D is wrong because updating the package cache (yum update) only refreshes metadata for already-configured repositories; it does not add a new third-party repository.

339
MCQmedium

An organization is deploying Automation Platform for the first time. The security team requires that all SSH private keys used for automation be stored securely with access controls. Which AAP feature should be used to meet this requirement?

A.Store the private key in plain text within the inventory file.
B.Use Ansible Vault to encrypt the private key file.
C.Set the SSH key as an environment variable on the controller.
D.Create a Machine credential type and upload the SSH private key.
AnswerD

A Machine credential stores the SSH private key encrypted within Automation Platform and enforces role-based access controls, so only authorised users and job templates can retrieve it. This satisfies the requirement that keys never sit in plain text on disk.

Why this answer

The Machine credential type in Ansible Automation Platform (AAP) is specifically designed to securely store SSH private keys. When you upload the private key via the AAP web UI or API, it is encrypted at rest in the AAP database and access is controlled through role-based access control (RBAC). This meets the security team's requirement for secure storage and access controls without exposing the key in plain text.

Exam trap

The trap here is that candidates may confuse Ansible Vault (a file-level encryption tool) with AAP's credential management system, not realizing that Vault does not provide the centralized access control and audit trail required for enterprise security compliance.

How to eliminate wrong answers

Option A is wrong because storing a private key in plain text within an inventory file violates basic security principles and exposes the key to anyone with file system access, which is not secure storage with access controls. Option B is wrong because Ansible Vault encrypts files at rest but does not integrate with AAP's native credential system; the key would still need to be decrypted at runtime and managed outside of AAP's RBAC, failing the access control requirement. Option C is wrong because setting the SSH key as an environment variable on the controller exposes it to any process or user that can read environment variables, and it lacks the granular access controls and audit logging that AAP credentials provide.

340
MCQmedium

You are preparing an Ansible playbook that will run on a managed node. The playbook includes a task that uses the `ansible.builtin.user` module to create a user. The playbook is stored in a Git repository that multiple engineers can access. You need to ensure that the password for the new user is not stored in plain text in the repository. Which Ansible feature should you use to protect the password?

A.ansible-vault create
B.ansible-vault encrypt_string
C.ansible-vault encrypt
D.ansible-vault rekey
AnswerB

`ansible-vault encrypt_string` encrypts a single string value, such as a password, which can then be embedded directly in a playbook or variable file. This keeps the secret out of plain text while allowing the playbook to decrypt it at runtime with the vault password. It is ideal for inline secrets that are not part of a larger file, and it integrates seamlessly with Ansible's vault mechanism.

Why this answer

The password must not be stored in plain text in the Git repository. Using `ansible-vault encrypt_string` allows you to encrypt just the password value and include it inline in the playbook or variables file. At runtime, Ansible decrypts the string using the vault password, so the secret remains protected in version control.

The other commands either encrypt entire files or manage vault keys, which do not address an inline secret.

Exam trap

The trap here is confusing file-level encryption with string-level encryption, assuming any ansible-vault command can protect an inline secret.

341
Matchingmedium

Match each Ansible inventory parameter to its meaning.

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

Concepts
Matches

Hostname or IP to connect to

SSH user for connection

SSH port number

Private key file path

Python interpreter path

Why these pairings

Common Ansible inventory parameters: ansible_host defines target host, ansible_port defines SSH port, ansible_user defines remote user, ansible_ssh_private_key_file defines SSH key. Be careful not to confuse them with ansible_connection or ansible_become.

342
Multi-Selectmedium

Which TWO statements about execution environments are true?

Select 2 answers
A.Execution environments can include both Ansible and system dependencies.
B.Execution environments cannot be used with ansible-playbook directly.
C.Execution environments must be built using ansible-builder.
D.Ansible Navigator is required to use execution environments.
E.Execution environments are OCI containers.
AnswersA, E

Execution environments are container images bundling both the Ansible runtime (ansible-core, collections) and the system-level dependencies those modules require, such as Python libraries, RPMs and binaries. This dual inclusion is what makes them portable and reproducible across control nodes.

Why this answer

Option A is correct because an execution environment is an OCI container image that bundles the Ansible Core/ansible-runner runtime together with collections, Python libraries, and system-level dependencies (RPMs, etc.), so it can carry both Ansible and system dependencies. Option E is correct because execution environments are distributed and consumed as OCI container images (e.g., via podman or docker registries), which is the packaging format that makes them portable and reproducible. Option B is wrong because ansible-playbook can be run inside an execution environment (for example, via ansible-navigator or by invoking the container directly), so they are not incompatible.

Option C is wrong because ansible-builder is only one tool for creating execution environments; they can also be built with a Containerfile/Dockerfile or other tooling. Option D is wrong because Ansible Navigator is a convenience CLI for running and inspecting execution environments, but it is not required — podman/docker or ansible-runner can use them directly.

Exam trap

Red Hat often tests the misconception that `ansible-builder` is the only way to build execution environments, but candidates must remember that any OCI-compliant container build tool (e.g., Dockerfile) can be used, and pre-built images can be pulled from a registry.

343
MCQmedium

An automation engineer is deploying Red Hat Ansible Automation Platform 2.4 using the bundled installer on a RHEL 9 control node. The inventory file is configured with `[automationcontroller]` and `[automationhub]` groups. After running `./setup.sh`, the installation fails with the message 'Unable to resolve the DNS name for the automation hub host'. The engineer verifies that the hostname is correct and resolvable from the control node. What is the most likely cause of this failure?

A.The control node's firewall is blocking outbound DNS queries to the automation hub host.
B.The automation hub host is not listed in the `[automationhub]` group of the installer inventory.
C.The `[automationhub]` group is missing the `automationhub_admin_password` variable, causing the installer to fail before DNS resolution.
D.The target host's `/etc/hosts` file does not contain an entry mapping its own hostname to its IP address, and the installer uses the host's own hostname for internal service communication.
AnswerD

The AAP installer relies on the target host being able to resolve its own hostname, often via `/etc/hosts`. Even if the control node can resolve the target's DNS name, the target itself may fail to resolve its own hostname during service configuration. This causes the installer to report a DNS resolution error. Adding the hostname to `/etc/hosts` on the target resolves the issue.

Why this answer

The AAP installer requires that each target host can resolve its own hostname, typically via an entry in `/etc/hosts`. Even when the control node resolves the target's DNS name, the target itself may fail to resolve its own hostname during internal service configuration, producing a DNS resolution error. Adding the hostname to `/etc/hosts` on the target resolves the issue.

Exam trap

The trap here is assuming that DNS resolution from the control node is sufficient, while overlooking the target host's need to resolve its own hostname.

344
MCQeasy

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

A.Set 'hosts: web_servers' in the play.
B.Set 'hosts: all' and use '--limit web_servers' when running ansible-playbook.
C.Set 'hosts: localhost' and delegate tasks to web_servers.
D.Set 'hosts: all' and use a 'when' condition to check if the node is in the web_servers group.
AnswerA

Setting `hosts: web_servers` scopes the play directly to the inventory group, so Ansible targets only those managed nodes and skips all others. This satisfies the constraint that execution must be limited to the 'web_servers' group, using Ansible's native group pattern matching rather than conditional logic or delegation.

Why this answer

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

Exam trap

The trap here is that candidates may overcomplicate the solution by choosing runtime flags or conditional logic, forgetting that Ansible's simplest and most explicit targeting method—setting 'hosts' to the group name—is both best practice and the most reliable for clarity and execution.

How to eliminate wrong answers

Option B is wrong because using '--limit web_servers' with 'hosts: all' is a runtime override that can be forgotten or misapplied, making the playbook less self-documenting and error-prone; it also requires the operator to remember the flag each time. Option C is wrong because setting 'hosts: localhost' and delegating tasks to web_servers is unnecessary complexity—delegation is meant for tasks that must run on the control node (e.g., fetching files), not for targeting a group of managed nodes. Option D is wrong because using a 'when' condition to check group membership (e.g., 'when: "web_servers" in group_names') still runs the play on all nodes, wasting resources and potentially causing failures on non-target nodes if tasks are not idempotent.

345
MCQmedium

An administrator is writing a role that must execute a handler only if a configuration file changes. The handler is defined in handlers/main.yml. The task that modifies the configuration file uses the copy module. Which keyword must be used on the task to trigger the handler?

A.changed_when
B.when
C.notify
D.listen
AnswerC

The notify keyword on a task specifies one or more handlers to run when the task reports a changed state. When the copy module writes a new configuration file, it returns changed: true, which triggers the handler. Handlers run once at the end of the play, or when flushed. This is the standard way to restart services after configuration updates.

Why this answer

Handlers are triggered by the notify keyword on a task. When the task's state is changed, Ansible adds the handler to a list of handlers to run at the end of the play. The copy module will report changed when it updates the file, thus notifying the handler to restart the service.

Without notify, the handler never runs.

Exam trap

The trap here is thinking that a handler runs automatically when its associated file changes, but Ansible requires an explicit notify declaration on the task that makes the change.

346
MCQhard

A company uses dynamic inventory from a cloud provider. The playbook needs to run tasks only on instances with a specific tag. The ansible_ec2_tags variable is not available. What is the most efficient method to filter hosts?

A.Use the hostvars lookup to check tags.
B.Use the ec2_instance_facts module inside the playbook to gather facts and filter.
C.Use a static inventory file with hosts pre-filtered.
D.Use the amazon.aws.aws_ec2 inventory plugin with compose and keyed_groups.
AnswerD

Pre-filters hosts at inventory time, most efficient.

Why this answer

The `amazon.aws.aws_ec2` inventory plugin can dynamically filter EC2 instances by tag using `keyed_groups` and `compose` at inventory build time, avoiding runtime overhead. This is the most efficient method as it pre-filters hosts before the playbook runs, unlike runtime fact gathering or lookups.

Exam trap

The trap here is that candidates often confuse runtime fact gathering (like `ec2_instance_info`) with inventory plugin filtering, not realizing that pre-filtering at inventory build time is far more efficient and aligns with Ansible's dynamic inventory best practices.

How to eliminate wrong answers

Option A is wrong because `hostvars` is a runtime lookup that requires the host to already be in the inventory, and it does not filter hosts; it only retrieves variables for hosts that are already present. Option B is wrong because `ec2_instance_facts` (now `amazon.aws.ec2_instance_info`) gathers facts at runtime on all hosts, which is inefficient and contradicts the goal of filtering hosts before task execution. Option C is wrong because a static inventory file defeats the purpose of dynamic inventory from a cloud provider, requiring manual updates and not scaling with dynamic environments.

347
MCQeasy

Which key in the galaxy.yml file defines the collection's namespace?

A.collection
B.authors
C.name
D.namespace
AnswerD

The namespace key in galaxy.yml declares the collection's namespace, which forms the first part of the fully qualified collection name used for installation and referencing. It must match the Automation Hub namespace the collection is published under.

Why this answer

The `namespace` key in the `galaxy.yml` file explicitly defines the collection's namespace, which is the first part of the fully qualified collection name (FQCN) and is used to organize collections under a specific publisher or organization on Ansible Galaxy. This is a required field in the `galaxy.yml` metadata file, as per the Ansible Collection structure.

Exam trap

Red Hat often tests the distinction between `namespace` and `name` in `galaxy.yml`, knowing candidates may confuse the two or think `namespace` is implied by the directory structure rather than explicitly defined in the file.

How to eliminate wrong answers

Option A is wrong because `collection` is not a valid key in `galaxy.yml`; the file itself describes a collection, but no such key exists. Option B is wrong because `authors` is a metadata field listing the collection's authors, not the namespace. Option C is wrong because `name` defines the collection's short name (the second part of the FQCN), not the namespace.

348
MCQhard

Refer to the exhibit. The playbook uses the 'yum' module to install 'httpd' on a RHEL 8 system. Which of the following is the most likely cause of the failure?

A.The 'yum' module is deprecated for RHEL 8; must use 'dnf'.
B.The AppStream repository is not enabled on the target host.
C.The remote host does not have subscription-manager access.
D.The package name is misspelled; it should be 'apache2'.
AnswerB

On RHEL 8, httpd ships in the AppStream repository rather than BaseOS. If AppStream is disabled, the yum module cannot resolve the package and the task fails, so enabling that repository is the required fix.

Why this answer

On RHEL 8, the `yum` command is a symbolic link to `dnf`, and the `yum` Ansible module internally uses `dnf` as the backend. The most common cause of failure when installing a package like `httpd` on RHEL 8 is that the AppStream repository (which contains `httpd`) is not enabled or available on the target host. Without an enabled repository containing the package, the module cannot resolve and install it, leading to a failure.

Exam trap

The trap here is that candidates assume the `yum` module is deprecated or incompatible with RHEL 8, but the actual failure is almost always a repository availability issue, not the module itself.

How to eliminate wrong answers

Option A is wrong because the `yum` module is not deprecated for RHEL 8; it is fully functional and internally delegates to `dnf` on RHEL 8 systems, so using the `yum` module is valid. Option C is wrong because subscription-manager access is not required for installing `httpd`; the package is available from standard repositories (e.g., AppStream) and does not require a Red Hat subscription to be accessed. Option D is wrong because the package name `httpd` is correct for RHEL 8; `apache2` is the package name used on Debian-based systems, not on RHEL.

349
MCQeasy

A Red Hat Certified Engineer is configuring Ansible to run playbooks against managed nodes. The security policy requires that all communication between the control node and managed nodes is encrypted and authenticated. The engineer decides to use SSH keys for authentication. Which Ansible configuration parameter should be set to specify the private key file to use for SSH connections?

A.`ansible_ssh_common_args`
B.`ansible_ssh_pass`
C.`ansible_ssh_private_key_file`
D.`ansible_user`
AnswerC

`ansible_ssh_private_key_file` is an Ansible connection variable that specifies the path to the private key file used for SSH authentication. Setting this variable in the inventory or as a host variable ensures that Ansible uses the correct key when connecting to managed nodes. This directly satisfies the requirement to use SSH keys for encrypted and authenticated communication.

Why this answer

To specify a private key file for SSH connections in Ansible, the connection variable `ansible_ssh_private_key_file` is used. It can be set in the inventory, in group_vars, host_vars, or as an extra variable. This ensures that Ansible uses the designated key for authentication, meeting the security policy.

The other options either specify a password, username, or additional SSH arguments, none of which directly designate the private key file.

Exam trap

The trap here is confusing `ansible_ssh_common_args` with the dedicated private key variable; while you can pass `-i` via common args, the correct parameter is `ansible_ssh_private_key_file`.

350
MCQeasy

An admin wants to build an execution environment using ansible-builder. Which file is required to define the base image and additional Python dependencies?

A.execution-environment.yml
B.requirements.yml
C.galaxy.yml
D.Dockerfile
AnswerA

The execution-environment.yml file is the definition file ansible-builder consumes, specifying the base image and Python dependencies under its build and dependencies keys. Without it, ansible-builder has no blueprint to construct the execution environment, so it satisfies the requirement to declare both the base image and additional Python packages.

Why this answer

`execution-environment.yml` is the required file for `ansible-builder` to define the base image (via the `base_image` field) and additional Python dependencies (via the `python` section under `dependencies`). This YAML file serves as the build definition that `ansible-builder` reads to construct the container image, making it essential for creating custom execution environments.

Exam trap

Red Hat often tests the distinction between files used by different Ansible tools—candidates confuse `requirements.yml` (for collections/roles) or `galaxy.yml` (for collection metadata) with the `execution-environment.yml` file that is specifically required by `ansible-builder`.

How to eliminate wrong answers

Option B is wrong because `requirements.yml` is used by `ansible-galaxy` to install Ansible collections or roles, not by `ansible-builder` to define the base image or Python dependencies. Option C is wrong because `galaxy.yml` is a metadata file for Ansible collections (e.g., defining namespace, version, and dependencies), not for building execution environments. Option D is wrong because while `ansible-builder` internally generates a Dockerfile, the user does not provide it directly; the required input file is `execution-environment.yml`, which `ansible-builder` processes to produce the Dockerfile and build context.

351
MCQmedium

A team wants to use a certified collection from Red Hat Automation Hub but cannot access it directly due to firewall restrictions. What is the best practice?

A.Download the collection manually and install from a tarball.
B.Set up a private Automation Hub and sync the collection.
C.Copy the collection from another team's workspace.
D.Use ansible-galaxy collection install with --offline flag.
AnswerB

A private Automation Hub mirrors certified collections internally, so the firewall-restricted team syncs content from an on-premises repository rather than reaching Red Hat Automation Hub directly. This preserves certified content while satisfying network isolation requirements.

Why this answer

Setting up a private Automation Hub and syncing the certified collection is the best practice for environments with firewall restrictions. This approach ensures that the collection remains in a trusted, curated state, is automatically updated, and can be consumed by all team members via `ansible-galaxy` without manual intervention, maintaining compliance with Red Hat's support policies.

Exam trap

The trap here is that candidates often assume manual download (Option A) is acceptable for firewall restrictions, but Red Hat's best practice emphasizes using a private Automation Hub to maintain supportability and consistency across the enterprise.

How to eliminate wrong answers

Option A is wrong because manually downloading and installing from a tarball bypasses the dependency resolution and version tracking provided by Automation Hub, leading to potential inconsistencies and unsupported configurations. Option C is wrong because copying a collection from another team's workspace introduces risks of untracked modifications, missing dependencies, and violates Red Hat's best practices for centralized, version-controlled content management. Option D is wrong because the `--offline` flag does not exist in `ansible-galaxy collection install`; the correct flag is `--no-deps` for offline scenarios, but this still requires the collection to be available locally and does not address the firewall restriction for initial access.

352
MCQeasy

A task sets a variable `raw_size` to the string `'2048'`. You need to pass this value to a module parameter that expects an integer. Which filter should be applied to `raw_size` to achieve the correct type?

A.{{ raw_size | float }}
B.{{ raw_size | bool }}
C.{{ raw_size | int }}
D.{{ raw_size | string }}
AnswerC

`int` converts the string `'2048'` into the integer 2048, satisfying the module parameter's numeric type requirement. It correctly handles numeric strings and produces a value usable in arithmetic or size comparisons. This is the appropriate filter for the stated scenario.

Why this answer

When a variable holds a numeric string and a module parameter requires an integer, the `int` filter performs the necessary conversion. Filters like `bool` and `string` do not change the value into an integer, and `float` produces a floating-point number that may not satisfy an integer parameter. Using `int` ensures the value is the correct type for the module.

Exam trap

The trap here is reaching for `float` because it is numeric, when the parameter specifically requires an integer type.

353
MCQhard

A team has developed several roles that share common variables. They want to organize these variables in a central file. Where should they place this file so it is automatically loaded by all roles?

A.In the inventory directory as host_vars/localhost.yml
B.In a common role's vars/main.yml
C.In a common role's defaults/main.yml
D.In the playbook directory as group_vars/all.yml
AnswerD

Variables in group_vars/all.yml, relative to the playbook directory, are automatically loaded for every host in every play, giving all roles centralised access without explicit includes. This satisfies the requirement that the file load automatically for all roles.

Why this answer

Placing a file in the playbook directory as group_vars/all.yml makes it automatically loaded by all roles. Ansible automatically includes any YAML files in the group_vars directory that match group names, and the special group 'all' applies to every host. This centralizes shared variables without requiring explicit imports in each role.

Exam trap

Red Hat often tests the distinction between role-level variable files (vars/main.yml and defaults/main.yml) and global variable files (group_vars/all.yml), trapping candidates who think a common role's vars/main.yml is automatically loaded by all roles when in fact it requires explicit role dependencies or includes.

How to eliminate wrong answers

Option A is wrong because host_vars/localhost.yml applies only to the localhost host, not to all hosts targeted by roles. Option B is wrong because vars/main.yml in a common role would require every other role to explicitly depend on or include that role, which is not automatic. Option C is wrong because defaults/main.yml in a common role defines default variables with the lowest precedence, which can be overridden by any higher-precedence variable source, making it unsuitable for central shared variables that should be consistently applied.

354
MCQhard

A developer wrote a custom filter plugin in a Python file `my_filters.py` and placed it in the directory `./filter_plugins/`. The playbook fails with 'ERROR! no filter named 'my_custom_filter''. The playbook is located in `/home/user/project/playbook.yml`. The `ansible.cfg` file in the same directory does not set `filter_plugins`. Which is the most likely cause?

A.The filter file must be named `__init__.py`
B.The plugin file must be a Python module with a class named `FilterModule` and the filter function must be listed in the `filters` method
C.The filter function must be imported in the playbook via `filter_plugins: my_filters`
D.The filter function name does not match the class name in the plugin
AnswerB

Ansible loads filter plugins only from Python modules exposing a FilterModule class whose filters method returns a dict mapping filter names to callables. Without that structure, the plugin is ignored, so no filter named my_custom_filter is registered, producing the error.

Why this answer

Ansible requires custom filter plugins to be Python modules that define a class named `FilterModule` with a `filters()` method returning a dictionary mapping filter names to their implementing functions. Without this structure, Ansible cannot discover or register the filter, causing the 'no filter named' error.

Exam trap

Red Hat often tests the misconception that the filter function name must match the class name or that the file must be named `__init__.py`, when in fact the critical requirement is the `FilterModule` class with a `filters()` method.

How to eliminate wrong answers

Option A is wrong because the filter file does not need to be named `__init__.py`; that naming is for Python packages, not individual plugin files. Option C is wrong because filters are not imported in the playbook via a `filter_plugins` directive; Ansible automatically loads plugins from the `filter_plugins` directory based on configuration. Option D is wrong because the filter function name does not need to match the class name; the mapping is defined in the `filters()` method's dictionary.

355
MCQeasy

A system administrator wants to build an Ansible execution environment using ansible-builder. Which file format is required to define the base image, dependencies, and additional Python packages for the build?

A.execution-environment.yml
B.ansible-navigator.yml
C.Containerfile
D.requirements.yml
AnswerA

The `execution-environment.yml` file is the definition file ansible-builder consumes, with its `dependencies` section specifying the base image, Galaxy collections, and Python packages. This directly satisfies the stem's requirement to define all three build inputs in one file, unlike an inventory or playbook.

Why this answer

`ansible-builder` requires an `execution-environment.yml` file to define the build context, including the base image (under `version: 1`), system-level dependencies (under `dependencies: system:`), and additional Python packages (under `dependencies: python:`). This file is the mandatory definition file for building an Ansible Execution Environment (EE) using `ansible-builder build`.

Exam trap

The trap here is that candidates confuse the build input file (`execution-environment.yml`) with the runtime configuration file (`ansible-navigator.yml`) or with the generated output (`Containerfile`), leading them to pick the wrong option.

How to eliminate wrong answers

Option B is wrong because `ansible-navigator.yml` is the configuration file for `ansible-navigator`, a tool used to run and inspect execution environments, not for building them with `ansible-builder`. Option C is wrong because a `Containerfile` (or `Dockerfile`) is a lower-level container build file that `ansible-builder` generates from `execution-environment.yml`; it is not the input file the administrator writes. Option D is wrong because `requirements.yml` is used by `ansible-galaxy` to install collections and roles, not by `ansible-builder` to define the base image or Python packages for an execution environment build.

356
Multi-Selectmedium

An Ansible playbook uses the 'block' and 'rescue' directives. Which two statements are true about this construct? (Choose two.)

Select 2 answers
A.Rescue tasks are executed on all hosts in the play.
B.A rescue section executes only if the block tasks fail.
C.Blocks cannot be nested.
D.The 'always' section runs regardless of success or failure.
E.A block can have multiple rescue sections.
AnswersB, D

The rescue section is bound to its enclosing block: it runs only when a task inside that block returns a failure, allowing recovery or rollback. Successful block execution skips rescue entirely, so it never triggers on unrelated task failures elsewhere in the play.

Why this answer

Option B is correct because the 'rescue' section of a block is executed only when a task inside the corresponding 'block' fails, allowing error handling and recovery logic to run conditionally. Option D is correct because the 'always' section is guaranteed to run whether the block tasks succeed, fail, or are rescued, making it suitable for cleanup or finalization steps. Option A is incorrect because rescue tasks run only on hosts where the block failed, not on all hosts in the play.

Option C is incorrect because blocks can be nested inside other blocks. Option E is incorrect because a block can contain only one 'rescue' section.

Exam trap

The trap here is that candidates often think 'rescue' runs on all hosts or that multiple rescue sections are allowed, confusing Ansible's block/rescue/always pattern with exception handling in programming languages like try-catch-finally.

357
MCQmedium

A playbook uses 'vars_prompt' to ask for a confirmation before proceeding with destructive changes. However, when the playbook is run from a CI/CD pipeline, it hangs indefinitely. What is the best way to handle this?

A.Remove the prompt and always proceed.
B.Set ANSIBLE_STDOUT_CALLBACK=unixy to avoid interactive prompts.
C.Encrypt the confirmation in vault and include it.
D.Use --check mode to simulate.
E.Pass the variable via --extra-vars and modify the prompt to be conditional with 'when: variable is not defined'.
AnswerE

Correct: This allows non-interactive input from CI/CD and only prompts when variable is missing.

Why this answer

Passing the variable via --extra-vars and making the prompt conditional with 'when: variable is not defined' allows the pipeline to provide the variable non-interactively. Option A is unsafe. Option B's --check mode does not solve prompts.

Option C is unrelated. Option D encrypts data but does not handle prompts. Therefore, E is best.

358
Multi-Selectmedium

Which THREE are valid user roles within an Automation Controller organization? (Choose three.)

Select 3 answers
A.Organization auditor
B.Organization admin
C.Organization team_member
D.Superuser
E.Organization member
AnswersA, B, E

Organization auditor is a built-in Automation Controller role granting read-only visibility across all objects within a single organization, including inventories, credentials, job templates and projects. It satisfies the stem's requirement for a valid organization-scoped user role, distinct from system auditor, which spans the entire controller instance rather than one organization.

Why this answer

In Automation Controller (Ansible Tower), an organization defines a set of users, teams, and resources, and it grants three built-in user roles: Organization admin, Organization member, and Organization auditor. Option B (Organization admin) is correct because this role has full administrative rights over the organization, including managing users, teams, projects, inventories, and credentials within it. Option E (Organization member) is correct because this role grants standard access to use the organization's resources, such as running job templates, without administrative privileges.

Option A (Organization auditor) is correct because this role provides read-only visibility into the organization's objects and activity for auditing purposes. Option C (Organization team_member) is not a valid organization-level role; team membership is a separate association, and roles like member/admin are assigned to teams rather than being an organization role itself. Option D (Superuser) is a system-wide role that sits above organizations and is not one of the organization-scoped user roles.

Exam trap

The trap here is that candidates may confuse 'Organization team_member' with a valid role, not realizing that team membership is distinct from organization-level roles, or they may incorrectly select 'Superuser' thinking it is an organization role when it is actually a global system role.

359
MCQhard

A playbook contains a task that uses the 'until' keyword with a retry count of 5 and a delay of 10. The task fails on all 5 attempts. What is the default behavior of Ansible regarding this task and subsequent tasks?

A.The task is skipped, and the playbook continues with subsequent tasks.
B.The task failure is ignored, and the playbook continues.
C.The task fails, and the playbook stops executing on that host by default.
D.The task is retried indefinitely until it succeeds.
AnswerC

When a task with 'until' exhausts all retries, it is marked as failed. By default, Ansible stops executing further tasks on that host, unless ignore_errors or failed_when is used. This prevents subsequent tasks from running on a host where a critical operation did not succeed. The play continues on other hosts unless any_errors_fatal is set.

Why this answer

When a task with 'until' exhausts its retries, it fails. Ansible's default behavior is to stop executing further tasks on that host, preventing subsequent actions that might depend on the failed task's success. The play continues on other hosts unless any_errors_fatal is set.

Exam trap

The trap here is assuming that retries imply eventual success or that a failed retry loop is automatically ignored, but Ansible treats exhausted retries as a standard task failure.

360
MCQmedium

A playbook uses the 'block' and 'rescue' keywords. If a task in the block fails, but the rescue tasks also fail, what happens?

A.The play fails.
B.The play continues to the next task.
C.The block is re-executed.
D.The rescue tasks are retried.
AnswerA

When a block task fails, rescue tasks run; if those rescue tasks also fail, the error remains unhandled, so the play aborts with a failed status for the host rather than continuing to subsequent tasks.

Why this answer

When a task in a block fails, the rescue tasks execute. If the rescue tasks also fail, the entire play fails (the failure propagates). Option B is incorrect because the play does not continue; it fails.

Option C is incorrect because the block is not re-executed; rescue only runs once. Option D is incorrect because rescue tasks are not retried after failure.

361
Drag & Dropmedium

Drag and drop the steps to set up a cron job that runs a script every day at 2 AM in the correct order.

Drag or tap steps into the slots.

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

Why this order

Cron setup: prepare script, test, edit crontab, add entry with correct syntax, verify.

362
MCQeasy

An admin is configuring a project in Automation Platform to pull playbooks from a Git repository. Which source control type should be selected?

A.Local
B.Manual
C.SCM
D.Red Hat Insights
AnswerC

Selecting SCM as the source control type lets Automation Platform authenticate to the Git repository and retrieve playbooks directly, satisfying the requirement to pull playbooks from Git. Other source control types, such as manual or archive-based imports, do not establish the live repository connection the scenario demands.

Why this answer

(SCM) is correct because Ansible Automation Platform uses Source Control Management (SCM) to integrate with Git repositories. When configuring a project, selecting 'SCM' allows the platform to pull playbooks, roles, and inventories directly from a remote Git repository, enabling version control and automated sync.

Exam trap

The trap here is that candidates may confuse 'SCM' with a generic term and think 'Manual' or 'Local' are valid options, but only SCM enables Git integration for project synchronization.

How to eliminate wrong answers

Option A is wrong because 'Local' refers to a project that uses playbooks stored directly on the Automation Controller file system, not from a remote Git repository. Option B is wrong because 'Manual' is not a valid source control type in Automation Platform; projects require either Local or SCM. Option D is wrong because 'Red Hat Insights' is a separate analytics and remediation service, not a source control mechanism for pulling playbooks.

363
MCQmedium

A playbook reads a YAML configuration file with the `include_vars` module and registers the result. The variable `app_config` now holds a dictionary with keys `database`, `cache`, and `logging`. You need to produce a list containing only the top-level key names for a later loop. Which Jinja2 filter expression should you use in the task that builds this list?

A.{{ app_config | items2dict | map(attribute='key') | list }}
B.{{ app_config | dict2items | map(attribute='key') | list }}
C.{{ app_config | flatten | map(attribute='key') | list }}
D.{{ app_config | subelements('key') | map(attribute='key') | list }}
AnswerB

The `dict2items` filter converts a dictionary into a list of dictionaries, each with a `key` and `value` field. Applying `map(attribute='key')` extracts the original top-level dictionary keys, and `list` materializes the result. This produces exactly the list of top-level names required for the loop, without touching nested values.

Why this answer

To turn dictionary keys into a list, the canonical approach is to convert the dictionary to a list of `{key, value}` dictionaries with `dict2items`, then extract the `key` attribute using `map`. The resulting list can be looped over directly. Filters like `items2dict`, `flatten`, and `subelements` operate on different data shapes and do not produce top-level key names from a plain dictionary.

Exam trap

The trap here is confusing `dict2items` with `items2dict` and assuming either one works in both directions on a dictionary.

364
MCQmedium

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

A.Deploy an additional automation mesh node in the branch office and make the branch office execution nodes children of that node.
B.Configure the controller to use the AWS execution nodes for all branch office jobs via a proxy.
C.Increase the `ansible_timeout` setting in the controller configuration to 120 seconds.
D.Reduce the forks value for branch office execution nodes to 1.
AnswerA

Introducing an intermediate hop node in the branch office lets execution nodes connect over the low-latency LAN rather than the high-latency VPN, satisfying the requirement to minimise latency and prevent timeouts. Direct children of the controller force every job hop across the constrained VPN link.

Why this answer

Deploying an additional automation mesh node in the branch office creates a local parent for the branch office execution nodes, reducing the number of high-latency, low-bandwidth VPN hops between the controller and those nodes. In the automation mesh, parent-child relationships allow execution nodes to connect through a closer intermediary, minimizing timeouts and improving reliability by keeping control-plane traffic local.

Exam trap

The trap here is that candidates may confuse tuning parameters (timeout, forks) with architectural fixes, failing to recognize that the mesh topology itself must be adapted to overcome network constraints.

How to eliminate wrong answers

Option B is wrong because using AWS execution nodes as a proxy for branch office jobs would still route traffic over the VPN, adding unnecessary latency and complexity without addressing the root cause. Option C is wrong because increasing `ansible_timeout` only masks the symptom of network delays; it does not reduce the underlying latency or packet loss causing the timeouts. Option D is wrong because reducing forks to 1 limits parallelism but does not solve connectivity issues; it may even increase execution time without preventing hangs from network instability.

365
MCQmedium

Your team stores two inventories: a static file at inventories/prod and a dynamic inventory plugin configuration at inventories/aws_ec2.yml. The static file defines the group `db` with `db1 ansible_host=172.16.5.10`, while the plugin also returns a host named db1 with the address 172.16.5.99. You run `ansible-inventory -i inventories/prod -i inventories/aws_ec2.yml --host db1`. Which host variable value does Ansible report for ansible_host?

A.172.16.5.99, because the last inventory source processed takes precedence for the same host.
B.Both values are retained, and Ansible fails with a duplicate host variable error.
C.Neither value; Ansible reports the host as undefined because duplicate host names are skipped.
D.172.16.5.10, because the first inventory source listed on the command line takes precedence.
AnswerA

When inventories are merged, Ansible combines hosts and groups, and for a host defined in more than one source the variable values from the later source override earlier ones. Here the dynamic plugin is processed after the static file, so its ansible_host value of 172.16.5.99 prevails. You can verify this with ansible-inventory before running production playbooks.

Why this answer

Merging multiple inventories unifies hosts and groups rather than rejecting duplicates. For a host present in several sources, variables from the source processed later override those from earlier sources. Since the dynamic plugin is processed after the static file, its ansible_host value is the one that survives, so the host resolves to the plugin-provided address.

Exam trap

The trap here is assuming command-line order of -i flags decides precedence, when merging actually favors the last-processed source.

366
MCQmedium

An admin configures an automation mesh environment. What is the primary purpose of mesh nodes in AAP?

A.To enable high availability for the web UI.
B.To act as a backup for the automation controller.
C.To provide a redundant database server.
D.To scale automation execution capacity.
AnswerD

Mesh nodes extend execution capacity by running jobs alongside control-plane hybrid nodes, distributing playbook workloads across additional compute. This directly satisfies the stem's scaling requirement: adding mesh nodes increases parallel job execution without altering the control plane, unlike hop nodes, which only relay traffic between isolated network segments.

Why this answer

Mesh nodes in Ansible Automation Platform (AAP) are designed to distribute automation execution workloads across multiple nodes, enabling horizontal scaling. They do not handle the web UI, controller logic, or database functions; instead, they execute playbooks and jobs, offloading work from the automation controller to increase overall capacity and performance.

Exam trap

The trap here is that candidates confuse mesh nodes with general high-availability or redundancy components, assuming they serve as backups for the controller or database, when in fact they are strictly for scaling execution capacity.

How to eliminate wrong answers

Option A is wrong because high availability for the web UI is provided by the automation controller nodes themselves, often through a load balancer, not by mesh nodes. Option B is wrong because mesh nodes are not backups for the automation controller; controller redundancy is achieved through a separate controller cluster with active/passive or active/active setups. Option C is wrong because database redundancy is handled by a separate database cluster (e.g., PostgreSQL streaming replication), not by mesh nodes, which have no database role.

367
MCQeasy

An administrator is writing a playbook to manage multiple web servers. The playbook uses a variable "server_facts" which is a list of dictionaries with keys "hostname", "ip", and "status". The administrator needs to extract a list of all hostnames where status is "online". The administrator writes: - name: Get online hosts set_fact: online_hosts: "{{ server_facts | selectattr('status', '==', 'online') | map(attribute='hostname') | list }}" However, when running the playbook, the "selectattr" filter fails with an error: "Invalid data passed to filter". The administrator checks the structure of "server_facts" and confirms it is a list of dicts with the expected keys. What is the most likely cause of the error?

A.The "status" key exists but its value is not consistently a string; some entries have integer 0/1 instead of "online"/"offline".
B.The "map" filter cannot be chained with "selectattr" directly.
C.The "list" filter is unnecessary and causes the error.
D.The "selectattr" filter requires Python 3.8 or later.
AnswerA

Mismatched types cause the comparison to fail.

Why this answer

The `selectattr` filter in Ansible uses Jinja2's `selectattr` which relies on Python's `attrgetter` and comparison operators. If the `status` key exists but its value is not consistently a string (e.g., some entries have integer 0/1 instead of 'online'/'offline'), the equality comparison `'==', 'online'` will fail because an integer cannot be compared to a string in this context, causing an 'Invalid data passed to filter' error. The administrator confirmed the structure is correct, so the issue is likely a type mismatch in the values.

Exam trap

The trap here is that candidates assume the error is about filter chaining or syntax, but the real issue is data type inconsistency—specifically that `selectattr` performs strict equality checks and fails when comparing mismatched types like integers and strings.

How to eliminate wrong answers

Option B is wrong because `map` can be chained directly with `selectattr` in Jinja2 filters; this is a standard and supported pattern in Ansible. Option C is wrong because the `list` filter is necessary to convert the generator returned by `map` into a list; omitting it would not cause an 'Invalid data passed to filter' error. Option D is wrong because `selectattr` does not require Python 3.8; it works with Jinja2's built-in filters and is available in Python 2.7+ and all versions of Python 3 supported by Ansible.

368
MCQhard

An Ansible playbook uses a custom filter plugin located in the `filter_plugins/` directory next to the playbook. The filter is not being applied, and the playbook fails with an error that the filter is undefined. What is the most likely reason?

A.The filter plugin must be written in Python and have a `.py` extension.
B.The `filter_plugins` directory must be specified in `ansible.cfg` using `filter_plugins = ./filter_plugins`.
C.The filter plugin file must define a `FilterModule` class with a `filters` method.
D.The filter plugin must be placed in a `library` directory instead of `filter_plugins`.
AnswerC

Ansible filter plugins must define a class named `FilterModule` that contains a `filters` method returning a dictionary of filter names to callables. If this structure is missing, the filter will not be registered and will appear undefined. This is the most common reason for such errors.

Why this answer

Filter plugins require a specific structure: a `FilterModule` class with a `filters` method that returns a dictionary mapping filter names to functions. Without this, Ansible cannot register the filter, leading to an undefined filter error. The directory location and file extension are correct, so the structure is the likely culprit.

Exam trap

The trap here is assuming that placing the plugin in the correct directory is enough, when the internal class and method structure is critical for registration.

369
MCQhard

An execution environment fails to build because `pip install` fails when installing a Python package from a private repository that requires authentication. The build works when run locally by the developer. Which approach should be taken to securely provide credentials during the `ansible-builder build` process?

A.Store the credentials in the Automation Hub token and reference it.
B.Add the credentials directly to the `Containerfile` that `ansible-builder` generates.
C.Include the credentials in the `execution-environment.yml` under `dependencies: python:`.
D.Create a `pip.conf` file that uses environment variables or BuildKit secrets to inject credentials.
AnswerD

A pip.conf referencing environment variables or BuildKit secrets keeps credentials out of image layers and build context, satisfying the requirement to authenticate to the private repository securely during ansible-builder build without exposing secrets in the resulting image.

Why this answer

`ansible-builder` supports BuildKit secrets and environment variable injection via a `pip.conf` file, allowing credentials to be passed securely at build time without hardcoding them into the execution environment definition. This approach ensures that sensitive authentication tokens are not exposed in the `execution-environment.yml` or the generated `Containerfile`, and it mirrors the local developer workflow where environment variables or secret mounts are used.

Exam trap

The trap here is that candidates often assume credentials must be placed directly in the execution environment definition file or the generated Containerfile, overlooking the secure, build-time injection mechanisms provided by BuildKit secrets and environment variables.

How to eliminate wrong answers

Option A is wrong because Automation Hub tokens are used for authenticating to Automation Hub itself, not for private Python package repositories; they cannot be referenced in a `pip.conf` or passed to `pip install` for external registries. Option B is wrong because adding credentials directly to the `Containerfile` would hardcode secrets into the image layers, violating security best practices and making the credentials visible to anyone with access to the image. Option C is wrong because the `dependencies: python:` section in `execution-environment.yml` only lists package names and versions, not authentication credentials; it does not support inline credentials or secret injection.

370
MCQmedium

A playbook uses import_playbook to include other playbooks. The main playbook is run with --check mode. Which statement is true?

A.Only the main playbook runs in check mode; imported ones run normally.
B.All imported playbooks are skipped because import happens at parse time.
C.import_playbook does not support check mode.
D.Imported playbooks are also run in check mode.
AnswerD

Import_playbook merges tasks at parse time, so check mode affects all tasks.

Why this answer

When a playbook uses `import_playbook`, the imported playbooks are statically included at parse time, meaning they become part of the main playbook's play structure. The `--check` mode flag applies to the entire playbook execution, so all imported playbooks also run in check mode. Option D is correct because Ansible propagates the check mode flag to all imported plays.

Exam trap

The trap here is that candidates confuse `import_playbook` (static inclusion) with dynamic includes like `include_tasks`, which do not inherit check mode in the same way, leading them to think imported playbooks are skipped or run normally.

How to eliminate wrong answers

Option A is wrong because `--check` mode is not limited to the main playbook; it applies globally to all plays, including those imported via `import_playbook`. Option B is wrong because `import_playbook` does not cause imported playbooks to be skipped in check mode; they are included at parse time and run with the same check mode flag. Option C is wrong because `import_playbook` fully supports check mode; there is no restriction that prevents imported playbooks from running in check mode.

371
MCQmedium

A platform team maintains an execution environment definition where `requirements.yml` lists several collections. They need to pin `community.general` to a specific version range so that only releases from 7.0.0 up to but not including 8.0.0 are installed during the build. Which syntax inside `requirements.yml` accomplishes this?

A.- name: community.general version: "^7.0.0"
B.- name: community.general version_range: ">=7.0.0 <8.0.0"
C.- name: community.general version: ">=7.0.0,<8.0.0"
D.- name: community.general version: "7.x"
AnswerC

Collection requirements in `requirements.yml` accept a `version` field using standard version specifiers. The comma-separated range `>=7.0.0,<8.0.0` tells the resolver to install any 7.x release but nothing from 8.0.0 onward. This is the documented way to constrain a collection to a major version line when building an execution environment.

Why this answer

Ansible collection requirements use the `version` key with Python-style comparison operators. Combining a lower bound and an exclusive upper bound in a single quoted string yields the desired 7.x-only range, which is the only syntax among the choices that the resolver actually understands when building the execution environment.

Exam trap

The trap here is assuming npm or wildcard version syntax works in Ansible requirements files; only Python-style specifier strings are honored by the collection resolver.

372
Multi-Selectmedium

Which TWO statements about Ansible roles are correct?

Select 2 answers
A.Roles must follow a specific directory structure.
B.Roles can be shared via Ansible Galaxy.
C.Ansible Galaxy is a continuous integration tool for testing roles.
D.Role dependencies must be defined in a file named dependencies.yml.
E.Role names must have a .role extension.
AnswersA, B

Ansible roles enforce a defined directory hierarchy — tasks, handlers, defaults, vars, files, templates and meta — so the role loader can locate content automatically. This structure satisfies the stem's requirement that roles follow a specific layout, since deviating from these conventional paths prevents Ansible from resolving tasks and variables correctly.

Why this answer

Option A is correct because Ansible roles rely on a defined directory layout (e.g., tasks/, handlers/, defaults/, vars/, files/, templates/, meta/, and the main.yml entry files) so that Ansible can automatically load each component without explicit includes. Option B is correct because Ansible Galaxy is the public repository and CLI for packaging, downloading, and sharing roles, so roles can indeed be distributed and installed via Galaxy (e.g., ansible-galaxy install). Option C is wrong because Ansible Galaxy is a role/content distribution hub, not a CI tool; CI for roles would be handled by tools like Jenkins, GitLab CI, or Molecule.

Option D is wrong because role dependencies are declared in meta/main.yml under the dependencies key, not in a file named dependencies.yml. Option E is wrong because role names are plain directory names and do not use a .role extension.

Exam trap

The trap here is that candidates confuse Ansible Galaxy as a CI tool because it has 'Galaxy' in its name, or assume role dependencies require a separate file like dependencies.yml, when in fact they must be placed in meta/main.yml.

373
MCQeasy

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

A.ansible-galaxy collection init mycollection
B.ansible-galaxy collection publish ./mycollection-1.0.0.tar.gz
C.ansible-galaxy collection install .
D.ansible-galaxy collection build
AnswerD

The ansible-galaxy collection build command packages the collection directory into a tarball artefact containing the galaxy.yml manifest, roles, plugins and modules. This tarball is the required input for ansible-galaxy collection publish, so building must precede uploading to the private Automation Hub.

Why this answer

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

Exam trap

The trap here is that candidates confuse the `publish` command (which uploads an existing tarball) with the `build` command (which creates the tarball), leading them to select option B instead of D.

How to eliminate wrong answers

Option A is wrong because `ansible-galaxy collection init` creates the skeleton directory structure for a new collection, not the build artifact needed for publishing. Option B is wrong because `ansible-galaxy collection publish` uploads an already-built tarball to Automation Hub, but the question asks for the command to build the collection before publishing. Option C is wrong because `ansible-galaxy collection install` downloads and installs a collection from a source (like a galaxy server or a tarball), not builds one for distribution.

374
MCQeasy

An Ansible playbook contains many tasks. An administrator wants to run only a subset of tasks by passing '--tags ' at the command line. Which of the following must be added to the tasks?

A.a 'name' with specific naming convention
B.a 'block' statement
C.a 'tags' directive on each task
D.a 'when' condition
AnswerC

The --tags flag matches tasks carrying a tags directive, so each task to be selectively run must declare one. Without tags on the tasks, ansible-playbook cannot identify which subset to execute and runs none of the tagged selection.

Why this answer

The 'tags' directive is the only mechanism in Ansible that allows tasks to be selectively included or excluded when running a playbook with the '--tags' command-line option. By adding a 'tags' attribute to a task (e.g., 'tags: install'), the administrator can target that task specifically, and Ansible's task execution engine filters tasks based on the provided tags at runtime.

Exam trap

The trap here is that candidates often confuse the 'name' field with a functional identifier, assuming it can be used for filtering, when in reality only the 'tags' directive controls task selection with '--tags'.

How to eliminate wrong answers

Option A is wrong because the 'name' field in a task is purely for documentation and display purposes; it does not influence task selection via '--tags'. Option B is wrong because a 'block' statement groups tasks for error handling or conditional execution but does not provide tag-based filtering; blocks themselves can have tags, but the question asks what must be added to each task, and a block is not required. Option D is wrong because a 'when' condition controls whether a task runs based on variables or facts, not on command-line tag selection, and cannot be used with '--tags'.

375
MCQmedium

An Ansible rolling update playbook includes 'max_fail_percentage: 20'. If more than 20% of hosts fail during any batch, what happens?

A.The play pauses and waits for user input
B.The failed hosts are removed from inventory
C.The play retries failed hosts
D.The play aborts immediately
E.The play continues with remaining hosts
AnswerD

max_fail_percentage sets a tolerance threshold; once failed hosts in a batch exceed 20%, Ansible halts the play for all remaining hosts rather than continuing. This aborts the rolling update immediately, preventing further hosts from being updated.

Why this answer

The `max_fail_percentage` parameter in Ansible's rolling update strategy defines the maximum percentage of hosts that can fail in a single batch before the playbook aborts entirely. When the failure rate exceeds this threshold, Ansible stops execution immediately to prevent cascading failures or inconsistent state across the remaining hosts.

Exam trap

The trap here is that candidates often confuse `max_fail_percentage` with `any_errors_fatal` or assume the play will simply skip failed hosts and continue, but Ansible strictly aborts the entire play when the threshold is exceeded to enforce safety limits.

How to eliminate wrong answers

Option A is wrong because `max_fail_percentage` does not pause the play for user input; that behavior is controlled by `serial` with `pause` or `wait_for` tasks, not by failure thresholds. Option B is wrong because failed hosts are not removed from inventory; Ansible does not modify inventory files dynamically based on playbook failures. Option C is wrong because `max_fail_percentage` does not trigger automatic retries; retry behavior is configured separately via `retries` and `until` on individual tasks or via `any_errors_fatal`.

Option E is wrong because the play does not continue with remaining hosts when the failure percentage is exceeded; instead, it aborts immediately to prevent further execution.

Page 4

Page 5 of 6

Page 6

All pages