Courseiva

CCNA Implement advanced Ansible automation Questions

21 of 96 questions · Page 2/2 · Implement advanced Ansible automation · Answers revealed

76
Multi-Selecthard

Which THREE factors are essential for achieving idempotent behavior in Ansible plays?

Select 3 answers
A.Task execution order should not affect the final state.
B.Modules should be state-based and check current state before action.
C.Variables registered from previous tasks should be avoided.
D.Loops must be avoided because they always cause changes.
E.The 'ignore_errors' directive should be used sparingly and only when appropriate.
AnswersA, B, E

Idempotent plays produce same result regardless of order.

Why this answer

Options A, B, and E are correct for achieving idempotent behavior in Ansible plays. A is correct because idempotent tasks should produce the same final state regardless of the order they are executed; this ensures consistency across multiple runs. B is correct because idempotent modules check the current state before making any changes, only acting when the desired state differs, which is fundamental to idempotency.

E is correct because 'ignore_errors' should be used sparingly; overusing it can mask failures that would otherwise leave the system in a non-idempotent state, as subsequent runs may not correct hidden issues. C is incorrect because registered variables can be used in an idempotent manner; they do not inherently break idempotency. D is incorrect because loops can be idempotent if the module inside the loop is idempotent and the loop is designed to handle conditional changes.

77
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

Correct: 'no_log: true' suppresses logging of task input/output, protecting sensitive data.

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.

78
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

Standard block behavior: rescue on failure, then always.

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.

79
MCQhard

Your team is responsible for managing a fleet of 200 RHEL 8 servers using Ansible Tower. You have been asked to implement a secure automation workflow that meets the following requirements: 1. All playbooks must be stored in a private Git repository hosted on an internal GitLab server. 2. Credentials to access the Git repository must be stored securely in Ansible Tower. 3. The automation must run on a schedule every night at 2:00 AM. 4. If a playbook run fails, the team must be notified via email. 5. The playbooks require SSH private keys to connect to the managed hosts; these keys must be stored securely. 6. A development team needs to be able to launch the same job template manually, but they must not be able to modify the job template or view the credentials. You have created a Machine Credential for SSH and a Source Control Credential for Git. You have also created a Job Template that references the project, inventory, and credentials. What is the correct sequence of steps to satisfy all requirements?

A.1. Create a Project in Tower, pointing to the Git repository and associate the Source Control Credential. 2. Create a Job Template referencing the Project. 3. Add the Machine Credential to the Job Template. 4. Create a Schedule for the Job Template. 5. Assign the development team execute-only permissions on the Job Template. 6. Configure a Notification Template for email on failure.
B.1. Create a Schedule for 2:00 AM. 2. Create a Project in Tower with Source Control Credential. 3. Create a Job Template with Machine Credential. 4. Assign the development team admin permissions on the Job Template. 5. Configure a Notification Template.
C.1. Create a Project in Tower, pointing to the Git repository without a credential. 2. Create a Job Template referencing the Project. 3. Add the Source Control Credential to the Job Template. 4. Create a Schedule for the Job Template. 5. Assign the development team read-only permissions on the Job Template. 6. Configure a Notification Template for email on failure.
D.1. Create a Project in Tower, pointing to the Git repository and associate the Source Control Credential. 2. Create a Job Template referencing the Project, and add the Machine Credential. 3. Assign the development team read and execute permissions on the Job Template (not admin). 4. Create a Schedule for the Job Template to run at 2:00 AM. 5. Configure a Notification Template for email on failure and associate it with the Job Template.
AnswerD

This sequence correctly associates credentials, sets permissions (read+execute allows launch without edit), schedules, and configures notifications.

Why this answer

It correctly sequences the steps: first creating a Project with the Source Control Credential to securely access the private Git repository, then creating a Job Template that references the Project and includes the Machine Credential for SSH access to managed hosts. Assigning the development team 'read and execute' permissions (not admin) satisfies the requirement that they can launch the job template manually but cannot modify it or view credentials. Creating a Schedule for 2:00 AM and configuring a Notification Template for email on failure completes the automation workflow.

Exam trap

The trap here is that candidates often confuse the permission levels in Ansible Tower, mistakenly thinking 'execute-only' or 'read-only' allows launching a job template, when in fact the correct combination is 'read and execute' to permit manual launch without modification rights.

How to eliminate wrong answers

Option A is wrong because it adds the Machine Credential to the Job Template after creating the Job Template, which is technically acceptable but the sequence is less efficient; more critically, it assigns 'execute-only' permissions, which in Ansible Tower does not exist as a distinct permission level—the correct permission is 'read and execute' to allow launching without modification. Option B is wrong because it creates the Schedule before the Project and Job Template, which is invalid as a Schedule must be associated with an existing Job Template; it also assigns 'admin' permissions to the development team, which violates the requirement that they must not be able to modify the job template or view credentials. Option C is wrong because it creates the Project without a Source Control Credential, which would fail to authenticate to the private Git repository; it then incorrectly adds the Source Control Credential to the Job Template instead of the Project, and assigns 'read-only' permissions, which in Ansible Tower does not allow launching the job template—only 'read and execute' permits manual launch.

80
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

Correctly registers the result, retries until status 200, with 5 retries and 30-second delay.

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.

81
Multi-Selecteasy

A playbook must execute cleanup tasks after a block of tasks, both on success and failure. Which two of the following should be used within the block to achieve this?

Select 2 answers
A.ignore_errors
B.rescue
C.failed_when
D.always
E.block
AnswersD, E

always runs after the block regardless of outcome, ensuring cleanup.

Why this answer

To execute cleanup tasks after a block regardless of success or failure, use the block keyword to group the main tasks and the always keyword to define tasks that run unconditionally. The block + always pattern ensures cleanup runs even if the block fails. The other options do not achieve this: ignore_errors only prevents failures from stopping execution, rescue handles failures but only after a failure, and failed_when customizes failure conditions but does not guarantee cleanup execution.

82
Multi-Selectmedium

Which TWO of the following are valid methods to include external variable files into an Ansible playbook?

Select 2 answers
A.using the 'add_host' module
B.using the 'set_fact' module
C.using the 'include_vars' module
D.using '-e' command line option
E.using the 'vars_files' directive in the play
AnswersC, E

Correct: include_vars loads variables from files at runtime.

Why this answer

The 'include_vars' module dynamically loads variables from external files into a playbook at runtime, allowing for conditional or loop-based variable inclusion. Option E is correct because the 'vars_files' directive statically specifies external variable files to be parsed before task execution, a standard method for separating variable data from play logic.

Exam trap

The trap here is that candidates may confuse the '-e' command line option with a method to include external variable files into the playbook itself, when in fact it passes variables at runtime and does not modify the playbook's variable loading mechanism.

83
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

Properly adds the repository for package installation.

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.

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

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

86
MCQhard

Refer to the exhibit. The playbook fails to install httpd on server1. Which is the most likely cause?

A.The ansible.cfg file has an incorrect module path
B.The target host does not have internet access
C.The yum module should use state: present instead of latest
D.The target host is not registered with Red Hat Subscription Manager
AnswerD

Without subscription, the yum repositories are not available.

Why this answer

The error indicates no package found, likely because the target host is not subscribed to the necessary repositories.

87
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

A failed rescue marks the play as failed.

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.

88
MCQmedium

Refer to the exhibit. The playbook runs successfully, but the service is not restarted. What is the most likely cause?

A.The handler name has a typo: 'restart app' vs 'restart app'
B.The systemd module requires ansible_user to be root
C.The template did not result in a change to the destination file
D.The template source file does not exist
AnswerC

Handlers only run if notified on change.

Why this answer

The handler is not notified because the template task might not have changed the file.

89
MCQhard

Refer to the exhibit. After running the playbook, the admin checks /etc/ssh/sshd_config and finds that the MaxAuthTries line is unchanged. What is the most likely cause?

A.The playbook needs become: yes to modify the file
B.The regexp pattern is incorrect and does not match the current configuration
C.The handler was not notified because the task did not report 'changed'
D.The service name should be 'sshd' not 'sshd'
AnswerB

If no line matches, lineinfile does nothing by default.

Why this answer

The lineinfile regexp does not match any existing line, and the module does not add it if not found.

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

91
MCQhard

A playbook uses 'delegate_to: localhost' for a task that modifies a local file. The playbook runs against multiple servers. The administrator notices that the local file is overwritten by each parallel execution, causing corruption. Which strategy should be used to prevent this?

A.Increase 'forks: 1' to serialize execution.
B.Use 'throttle: 1' on the task.
C.Use 'serial: 1' at the play level.
D.Use 'run_once: true' along with 'delegate_to'.
AnswerD

Correct: run_once ensures the task is executed only once, avoiding parallel overwrites.

Why this answer

`run_once: true` ensures that the task executes only once across the entire batch of hosts, even when `delegate_to: localhost` is used. This prevents the local file from being overwritten by multiple parallel executions, as the task runs on a single host (the first in the inventory) and delegates the file modification to localhost once.

Exam trap

The trap here is that candidates confuse serialization (`serial`, `forks`, `throttle`) with single execution (`run_once`), mistakenly believing that running tasks one at a time prevents the overwrite, when in fact each host still triggers the task.

How to eliminate wrong answers

Option A is wrong because increasing `forks: 1` would serialize execution across all hosts, but the task would still run once per host, each time overwriting the local file — it does not limit the task to a single execution. Option B is wrong because `throttle: 1` limits the number of concurrent task executions to one, but like forks, it still runs the task for each host sequentially, causing the same overwrite issue. Option C is wrong because `serial: 1` at the play level runs the play against one host at a time, but the task still executes for each host, leading to repeated local file modifications.

92
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

Correct. The 'tags' directive is used to label tasks so that they can be selected with the '--tags' option.

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

93
MCQhard

An Ansible playbook uses 'async' and 'poll' to run a long-running task. The task returns a changed status and the playbook continues. However, the remote server reports that the task failed after the playbook finished. What is the most likely reason?

A.The 'async' timeout was set too high.
B.The 'poll' interval was set too low.
C.The task's return code was not checked; 'async_status' module should be used to explicitly check the job result.
D.The playbook used 'ignore_errors: true' on the async task.
AnswerC

Correct: Without explicit status check, Ansible only sees that the job started, not its final outcome.

Why this answer

When a task is launched with `async` and `poll: 0`, Ansible does not wait for the task to complete; it immediately continues the playbook. The task runs in the background on the remote host, and its final result (including failure) is not automatically captured by the playbook. To retrieve the actual exit status and output, you must explicitly use the `async_status` module with the job ID to poll the task until it finishes.

Without this explicit check, the playbook may report success even if the background task ultimately fails.

Exam trap

The trap here is that candidates assume Ansible automatically captures the final result of an async task when `poll: 0` is used, but in reality the playbook only records the initial launch status and requires an explicit `async_status` call to retrieve the actual completion status.

How to eliminate wrong answers

Option A is wrong because setting the `async` timeout too high would only allow the task to run longer before Ansible considers it failed; it does not cause a false success or mask a failure after the playbook finishes. Option B is wrong because the `poll` interval controls how frequently Ansible checks the task status while waiting; a low interval would cause more frequent checks, not a missed failure. Option D is wrong because `ignore_errors: true` would cause the playbook to continue despite a failure, but the question states the playbook already continues and the remote server reports failure after the playbook finished; `ignore_errors` would not cause the task to appear successful when it actually failed—it would still show a failure in the task result, just not halt the playbook.

94
MCQhard

You are managing a large infrastructure of 500 Linux servers. The servers are divided into groups: 'web', 'app', and 'db'. Each group has specific configuration requirements. You have developed a set of Ansible roles to manage these configurations. Recently, you noticed that when you run the playbook against all servers, the 'web' role is applied to 'app' servers due to a variable misconfiguration. The playbook uses include_role with a variable that determines which role to apply. The variable is defined in group_vars/all.yml as 'server_role: web'. However, each group should have its own role: 'web' for web servers, 'app' for app servers, 'db' for db servers. The playbook includes the role based on '{{ server_role }}'. What is the best course of action to fix this issue without modifying the playbook structure?

A.Change the variable in group_vars/all.yml to a list and use 'include_role' with loop.
B.Add a 'when' condition to the include_role task to check the group name.
C.Define the server_role variable in group_vars/web.yml, group_vars/app.yml, and group_vars/db.yml with the appropriate values.
D.Define the server_role in host_vars for each server.
AnswerC

Group vars override all.yml for that group.

Why this answer

Ansible's variable precedence dictates that group_vars/<group_name>.yml files override group_vars/all.yml for hosts in that group. By defining `server_role` per group file (web, app, db), each server gets the correct role without modifying the playbook structure. This leverages Ansible's built-in group variable inheritance to resolve the misconfiguration cleanly.

Exam trap

The trap here is that candidates may think a `when` condition or modifying the playbook is necessary, but the question tests understanding of Ansible's variable precedence and the correct use of group_vars to override all.yml without altering the playbook structure.

How to eliminate wrong answers

Option A is wrong because changing `server_role` to a list and looping `include_role` would apply multiple roles to each server, not fix the single-role misassignment; it also unnecessarily complicates the playbook. Option B is wrong because adding a `when` condition requires modifying the playbook structure, which the question explicitly forbids, and it would not leverage Ansible's variable precedence. Option D is wrong because defining `server_role` in `host_vars` for each of 500 servers is impractical and violates the DRY principle; group_vars is the correct scope for group-specific variables.

95
Multi-Selectmedium

Which TWO conditions are necessary for the 'local_action' directive to work as intended?

Select 2 answers
A.The inventory must contain an entry for the control node.
B.The task must have privilege escalation (become) enabled.
C.The task must be executed on the Ansible control node.
D.The 'local_action' module must be used instead of 'action'.
E.The connection plugin must be set to 'local'.
AnswersC, E

local_action runs locally.

Why this answer

Options C and E are correct. For the 'local_action' directive to work as intended, the task must be executed on the Ansible control node (C) because local_action delegates the task to localhost. Additionally, the connection plugin must be set to 'local' (E) because local_action uses the local connection plugin to run commands on the control node without SSH.

Option A is incorrect because local_action does not require an inventory entry for the control node; it implicitly uses localhost. Option B is incorrect because privilege escalation (become) is not a requirement for local_action; it can be used independently. Option D is incorrect because local_action is a shorthand directive, not a module; it is used instead of the 'action' keyword with delegate_to: localhost, but the key is that it runs locally with the local connection.

96
MCQmedium

An Ansible playbook runs tasks on a group of web servers. During a rolling update, the playbook should ensure that no more than 2 servers are taken out of service at the same time. Which play keyword should be used?

A.forks: 2
B.max_fail_percentage: 2
C.throttle: 2
D.serial: 2
AnswerD

Correct: 'serial: 2' ensures that tasks run on at most 2 hosts at a time, providing controlled rolling updates.

Why this answer

The `serial` keyword controls the batch size of hosts that Ansible executes a play against. Setting `serial: 2` ensures that only 2 web servers are processed at a time, which is exactly what is needed for a rolling update where no more than 2 servers should be taken out of service simultaneously.

Exam trap

The trap here is confusing `serial` (which controls batch size of hosts) with `forks` (which controls parallelism of task execution), leading candidates to pick `forks: 2` thinking it limits concurrency, when in fact it only limits the number of parallel task processes, not the number of hosts taken out of service simultaneously.

How to eliminate wrong answers

Option A is wrong because `forks: 2` sets the number of parallel processes Ansible uses to execute tasks across all hosts, but it does not limit the batch size of hosts that are taken out of service; with forks, all hosts can still be targeted in parallel up to the fork limit, which could take more than 2 servers out of service at once. Option B is wrong because `max_fail_percentage: 2` defines the maximum percentage of hosts that can fail before the playbook aborts, not the number of hosts processed concurrently. Option C is wrong because `throttle: 2` limits the number of concurrent task executions across a play or role, but it applies to individual tasks rather than controlling the batch size of hosts in a rolling update scenario.

← PreviousPage 2 of 2 · 96 questions total

Ready to test yourself?

Try a timed practice session using only Implement advanced Ansible automation questions.