TTechclick ⚡ XP 0% All lessons
Ansible · Automation · Interview PrepInteractive · L1 / L2 / L3

Ansible Interview Questions — Playbooks, Roles, Vault & Cheat-Sheet

The complete Ansible interview guide — for DevOps, DevSecOps and automation roles, freshers and experienced. Real questions with answers across the agentless push model and idempotency, inventory, playbooks (tasks, handlers, facts, variable precedence, Jinja2), roles and reuse, Ansible Galaxy and collections, Ansible Vault for secrets, and scale/ops with AAP/AWX, check mode, serial and become. Scenario-led, interactive, with a printable cheat-sheet.

📅 2026-06-11 · ⏱ 18 min · 1 live demo · 5 infographics · real console form · 🏷 10-Q assessment + AI Tutor inline

⚡ Quick Answer

Ansible interview questions and answers (2026) for DevOps and DevSecOps roles — the agentless push model, idempotency, inventory, playbooks (tasks, handlers, facts, variable precedence, Jinja2), roles and reuse, Ansible Galaxy and collections (FQCN), Ansible Vault for secrets, and scale/ops with AAP/AWX, check mode, serial and become — scenario-led with a printable cheat-sheet.

🎯 By the end you will be able to

Read as:

Pick where you want to start

1

Core concepts

Agentless, push, declarative, idempotent — inventory & modules.

2

Playbooks

YAML, tasks, handlers, facts, variables, Jinja2.

3

Roles & secrets

Roles, Galaxy, collections (FQCN), Ansible Vault.

4

Scale & ops

AAP/AWX, --check, serial, become, troubleshooting.

🧠 Warm-up — 3 questions, no score

Just notice which ones make you pause. We answer all three inside the lesson.

1. Does Ansible need an agent on each target?

Answered in Core concepts.

2. Handlers run…

Answered in Roles & secrets.

3. A safe way to store a secret in a Git playbook repo is…

Answered in Playbooks.

Most engineers think…

Most candidates say "Ansible needs an agent" or "a playbook is basically a shell script" — and the interview quietly ends there.

Both fail you. Ansible is agentless — it pushes Python modules over SSH/WinRM with nothing pre-installed on the target — and a playbook is declarative and idempotent, not imperative: running it twice converges to the same state instead of blindly re-running commands. That idempotency is the whole point and the #1 interview theme. This lesson trains the framing that gets you hired.

① Core concepts — agentless, push, idempotent

Ansible interviews open on the model, and the model is the whole exam. Ansible runs from a single control node and configures many managed nodes over SSH (WinRM for Windows). It is agentless — nothing is pre-installed on the targets — and it uses a push model, not a pull/poll model.

Figure 1 — Ansible architecture — one control node pushes to many
Ansible architecture — one control node pushes to manyAnsible runs from a single control node: it reads the inventory, ships Python modules over SSH (WinRM for Windows) to managed nodes, runs them, then removes them. There is no agent and no central daemon polling — the model is push, not pull.Control node → inventory → modules → managed nodes (over SSH)Playbooks (YAML)Inventory (static/dynamic)Modules & collectionsRoles & GalaxyControl nodeansible-playbook · SSH/WinRMLinux servers (SSH)Windows servers (WinRM)Network & cloud APIsIdempotent end state
Nothing is installed on the targets to run a task — Ansible copies the module, executes it under Python, and cleans up. The green box is the whole point: re-running converges to the same declared state.

The Ansible vocabulary every interview opens with

Know these four cold before anything else. Tap each card.

🖧
Control vs managed node
tap to flip

Control node = where Ansible is installed and runs from. Managed nodes = the targets it configures over SSH/WinRM. Only the control node needs Ansible.

🚫
Agentless
tap to flip

No software is pre-installed on targets. Ansible copies a Python module, runs it over SSH/WinRM, then deletes it. Just need SSH + Python on the target.

🔁
Idempotency
tap to flip

Running the same play twice converges to the same state without redoing work. A task reports changed only when it truly alters the system — the core of Ansible.

📜
Playbook vs ad-hoc
tap to flip

A playbook is a reusable YAML file of plays/tasks. An ad-hoc command (ansible all -m ping) is a one-off — great for quick checks, not for repeatable config.

The single most-tested idea is idempotency: running the same playbook twice converges to the same state without re-doing changes. The inventory (static or dynamic) tells Ansible which hosts; modules do the real work and report ok/changed/failed.

Figure 3 — Ansible vs Puppet / Chef — why agentless + push wins
Ansible vs Puppet / Chef — why agentless + push winsThe classic config-management comparison. Ansible's agentless, push, YAML model is the reason it spread so fast in DevOps shops.Ansible vs Puppet / Chef — why agentless + push winsAnsiblePuppet / ChefAgentless — SSH / WinRM onlyAgent/daemon installed on every nodePush model — control node initiatesPull model — node polls a masterYAML playbooks (declarative data)Ruby DSL (Puppet) / Ruby recipes (Chef)Nothing to bootstrap but Python+SSHMaster server + certs + agent to manageIdempotent via module state checksIdempotent via resource abstraction
The one-liner that wins: Ansible is agentless and push-based — you manage a target the moment SSH works, with no agent to install, certificate to sign, or master server to keep alive.

Interviewers often probe the comparison with Puppet and Chef to test whether you really understand the model — so be ready to contrast agentless/push/YAML against agent/pull/DSL in one breath.

Quick check · Q1 of 10 · Apply

An interviewer asks: "How does Ansible run a task on 50 Linux servers without anything installed on them?" Best answer?

Correct: a. Ansible is agentless and push-based: it opens an SSH connection, copies the relevant Python module to the target, executes it, captures ok/changed/failed, then deletes it. No agent, no daemon, no master to poll.
👉 So far: Ansible = agentless + push + declarative + idempotent. Control node runs it; managed nodes need only SSH/WinRM + Python. Inventory says WHICH hosts; modules do the work; idempotency means re-running converges to the same state.
The 'Ansible needs an agent' trap

Answer firmly: no. Puppet and Chef install an agent and pull from a master; Ansible installs nothing on the target and PUSHES over SSH/WinRM. The only requirements on a Linux target are SSH access and Python; on Windows it is WinRM. Saying 'Ansible needs an agent' is an instant fail.

② Playbooks — YAML, tasks, handlers, variables & facts

A playbook is a YAML file of one or more play; each play maps a host group to an ordered list of task (module calls). Ansible gathers facts via the setup module unless you set gather_facts: false. Changed tasks can notify handlers, which run once at the very end.

▶ Watch a play converge — and why running it twice is safe

How Ansible installs and starts nginx idempotently, then what changes on the second run. Press Play for the healthy path, then Break it to see the failure.

① Gather factsThe setup module collects ansible_facts (OS, IP, packages) so tasks can branch on them.
② Task: install nginxThe dnf/apt module checks if nginx is present. First run: absent → installs it → reports changed.
③ Task: deploy config (template)Jinja2 renders nginx.conf.j2. The file differs from the target → written → changed → notifies a handler.
④ Handler: restart nginxBecause the config changed, the queued handler fires ONCE at the end and restarts nginx. State now matches.
Press Play to step through the healthy path. Then press Break it.
Figure 2 — How a playbook actually runs — recite this order
How a playbook actually runs — recite this orderFrom ansible-playbook on the control node to the PLAY RECAP line: parse, connect, gather facts, run tasks top-to-bottom, fire notified handlers at the end, then print the recap.① Parse playbook + inventoryload YAML, resolve hosts & the host pattern② Connect over SSH / WinRMone connection per host, in parallel (forks)③ Gather facts (setup module)collect ansible_facts unless gather_facts: false④ Run tasks top-to-bottomeach task = a module call, checked for idempotency⑤ Notify handlerschanged tasks queue handlers (run once, at the end)⑥ Run handlersrestart service etc. — only if something changed⑦ PLAY RECAPok / changed / unreachable / failed per host
Two facts interviewers love: handlers run ONCE at the very end (not inline), and a task reports changed=true only when it actually altered state — that distinction is idempotency on screen.
COLOUR KEYunreachable / failedtask running / inspectedchanged — state alteredok — already in desired state

variable precedence decides which value wins when the same variable is set in many places. Jinja2 powers {{ }} templates and when: conditionals; register captures a task's output for later steps.

Quick check · Q2 of 10 · Analyze

A playbook deploys nginx.conf from a Jinja2 template and a separate task does "notify: restart nginx". On the SECOND run nothing changed in the template. Does nginx restart?

Correct: c. Handlers fire only when a notifying task reports changed. On the second run the rendered config matches the target, the template task is 'ok', the handler is not queued, and nginx is left running — that is idempotency protecting you from a needless restart.

Pause & Predict

Where in a role do you put a variable you want users to easily override, versus one that should be hard to override? Type your guess.

Answer: Put easily-overridden values in defaults/main.yml (lowest precedence — almost anything beats it). Put values you want to win in vars/main.yml (much higher precedence). The classic interview point: role defaults are the weakest source, role vars are strong — mixing them up is why 'my override isn't working'.

Sneha at Infosys faces this

A play installs a package and a handler should restart the service, but the service never restarts even though the package was just installed.

Likely cause

The package task reported 'ok' (already installed from a prior run), so it never sent the notify; OR the handler name in notify does not exactly match the handler's name.

Diagnosis

Run with -v and read the recap: is the install task 'changed' or 'ok'? Compare the notify string to the handler's name character-for-character.

ansible-playbook site.yml -v ▸ read changed/ok per task
Fix

Make the notify string match the handler name exactly; if you truly need a restart regardless, use a separate handler triggered by the config task, or force_handlers/meta: flush_handlers.

Verify

Re-run: when the config changes, the task reports changed, the handler is notified, and the service restarts exactly once.

👉 So far: Playbook = YAML plays → tasks (module calls). Facts come from the setup module. Handlers run once at the end, only when notified by a changed task. Variable precedence: -e (extra-vars) wins, role defaults lose. Jinja2 powers templates and when:.

③ Roles, reuse & secrets — Galaxy, collections, Vault

roles are how you stop copy-pasting tasks. A role is a directory with a fixed layout — tasks/, handlers/, templates/, files/, vars/, defaults/, meta/ — that a play includes by name. Share and reuse them via Ansible Galaxy and bundle modules/roles/plugins into collections addressed by FQCN.

🖥️ This is the screen you run automation from in production — Automation Execution ▸ Templates ▸ Create job template in the AAP / AWX controller. Fields ①②③ decide WHAT runs, WHERE, and AS WHOM.

controller.aap.lab · Automation Execution ▸ Templates ▸ Create job template
Name *
Patch-RHEL-Web-Tier
Job Type
Run
Inventory *
Prod-WebServers
Project *
infra-playbooks (Git)
Playbook *
site.yml
1
Credentials *
rhel-ssh-key + vault-pass
2
Limit
webservers:&mumbai
Verbosity
1 (Verbose)
3
Save   Cancel

Playbook must be a file inside the linked Project (Git repo synced into AAP) — usually site.yml. ② Credentials pin BOTH the machine credential (SSH key) and the Vault credential, or encrypted vars fail to decrypt. ③ Limit narrows the run to a host pattern (e.g. one batch) without editing the inventory.

include vs import controls reuse timing. Secrets are handled by Ansible Vault — and you can encrypt a single value inline with encrypt_string.

Pause & Predict

You have a database password that must live in a Git repo with the playbook. How do you store it safely? Type your guess.

Answer: Encrypt it with Ansible Vault — either put it in a vault-encrypted vars file (ansible-vault encrypt group_vars/prod/vault.yml) or encrypt just that value with ansible-vault encrypt_string and paste the ciphertext into a normal vars file. At runtime you supply the password via --ask-vault-pass or a vault credential (in AAP). Plaintext in Git is the instant-fail answer.
Quick check · Q3 of 10 · Analyze

A teammate writes the same 30 lines of "install + configure + restart Apache" tasks in five different playbooks. What is the correct Ansible fix?

Correct: b. Extracting the repeated tasks into a roles/apache/ role makes them reusable, testable and shareable (via Galaxy/collections). Each playbook then references the role in one line — DRY, the entire reason roles exist.

Rahul at TCS faces this

After moving secrets into a Vault-encrypted vars file, the playbook fails on every host with 'Attempting to decrypt but no vault secrets found'.

Likely cause

The run wasn't given the Vault password — no --ask-vault-pass, no --vault-id, or (in AAP) no Vault credential attached to the job template.

Diagnosis

Re-run locally with --ask-vault-pass; if it works there, the gap is the missing Vault credential on the AAP job template.

ansible-playbook site.yml --ask-vault-pass ▸ then check AAP Credentials
Fix

Supply the Vault password: --ask-vault-pass / --vault-id prod@prompt locally, or attach the Vault credential alongside the SSH credential on the AAP job template.

Verify

Re-run: the encrypted vars decrypt, tasks proceed, and the recap shows failed=0.

'Roles are just folders' and 'Vault is optional'

Two killers. Roles aren't cosmetic — defaults/ vs vars/ have very different precedence, and meta/main.yml declares dependencies. And never hand-roll secret hiding: use Vault (or an external secrets manager like HashiCorp Vault) and commit only ciphertext. Plaintext passwords in a repo end interviews.

④ Scale & ops + troubleshooting

At scale you stop running from a laptop and move to AAP (the controller, formerly Tower; AWX is the open-source upstream). You define a job template that pins the playbook, inventory and credentials. dynamic inventory keeps the host list current.

Figure 4 — The play failed — why? Read the recap, then climb
The play failed — why? Read the recap, then climbA ladder to diagnose a failed run from the PLAY RECAP outward — unreachable is connectivity, failed is the task, changed-every-run is non-idempotency, undefined var is templating.The play failed — why? Read the recap, then climbunreachable=1 in recapcan the control node even reach the host?FAILSSH / auth / DNS problemfix key, user, become, host in inventoryPASS ↓failed=1 on a taskmodule error or bad syntax/argsFAILModule/parameter/permission errorread the task error, fix args or add becomePASS ↓changed=1 every single runis the task actually idempotent?FAILUsing command/shell, not a moduleswitch to the proper module or add creates/whenPASS ↓'undefined variable' erroris the var defined for this host?FAILVar missing / wrong precedencedefine it in vars/group_vars or use default()All pass → the layer is healthy; look one level up.
Start at the recap line, not the traceback: unreachable means SSH/auth, failed means the task, changed-every-time means you broke idempotency, and undefined variable means templating/precedence.

Pause & Predict

Before patching 200 production servers, how do you prove the playbook is safe WITHOUT changing anything? Type your guess.

Answer: Run it in check mode with diff: ansible-playbook patch.yml --check --diff. --check is a dry run — modules report what they would change but make no changes; --diff shows the exact file/line differences. Combine with --limit and serial to roll out in batches. This is the answer interviewers want for 'how do you de-risk a big change'.

Arjun at HCL faces this

A patching play over 200 servers hammers them all at once and a few time out, leaving the fleet half-patched.

Likely cause

No batching — Ansible ran across all hosts up to the default forks at once. There is no serial setting to roll out gradually, and no check before the real run.

Diagnosis

Dry-run first with --check --diff on a --limit subset; then set serial to patch in waves so a failure stops the rollout early.

ansible-playbook patch.yml --check --diff --limit canary ▸ then serial: 10
Fix

Add serial: 10 (or a percentage) to the play, raise forks sensibly, and gate prod behind --check; use --limit to canary a small subset of hosts first.

Verify

Re-run: hosts patch in controlled waves, a failing wave halts the play (max_fail_percentage), and the recap shows unreachable=0 failed=0.

Dry-run, then verify connectivity and idempotency
ansible all -i inventory.ini -m ping              # is every host reachable over SSH?
ansible-playbook patch.yml --check --diff --limit 10.20.30.41   # dry run, show diffs
ansible-playbook patch.yml --become --limit webservers          # real run, sudo
ansible-playbook patch.yml --limit webservers                   # run AGAIN — must be all 'ok'
Expected output
PLAY RECAP *********************************************************
10.20.30.41   : ok=5    changed=0    unreachable=0    failed=0
10.20.30.42   : ok=5    changed=0    unreachable=0    failed=0
Quick check · Q4 of 10 · Apply

On the SECOND consecutive run of a working playbook, you still see "changed=4" on every host. What does that tell a senior engineer?

Correct: d. A correct playbook should report changed=0 on the second run because the state already matches. Persistent 'changed' usually means raw command/shell tasks (which always report changed) instead of proper modules, or missing creates:/changed_when: guards. That is a non-idempotency red flag.

Priya at Wipro faces this

A play fails immediately with 'unreachable=1' on a brand-new host that the team swears is online.

Likely cause

It is a connectivity/auth problem, not a task problem: wrong SSH user or key, host not in the inventory group being targeted, host key not accepted, or Python missing on the target.

Diagnosis

Test the layer below Ansible: ssh user@host, then ansible -m ping. The error message (Permission denied / No route / host key) names the cause.

ansible 10.40.50.61 -m ping -vvv ▸ read the SSH error
Fix

Fix the inventory entry (ansible_user, ansible_ssh_private_key_file), accept/known_hosts the key, ensure become for privileged tasks, and confirm Python on the target.

Verify

ansible -m ping returns pong; the play recap shows unreachable=0.

Figure 5 — Ansible interview cheat-sheet
Ansible interview cheat-sheetOne card: the model, the playbook order, roles layout, Vault, escalation and the recap meaning.🖨 Print this before your Ansible interview📡The modelAgentless · push · declarative· idempotent. Control node →SSH/WinRM → managed nodes. Noagent, no master.🔁IdempotencyRun twice = same state.changed=true ONLY when stateactually changed. The #1theme.📜Playbook orderParse → connect → gather_facts→ tasks (top-down) → notify →handlers (once, at end) →RECAP.📦Roles layoutroles/<name>/ → tasks,handlers, templates, files,vars, defaults, meta. Reusevia Galaxy/collections (FQCN).🔐SecretsAnsible Vault encryptsvars/files; ansible-vaultencrypt_string for one value.Never commit plaintext.🧪Safety + recap--check (dry run) + --diffbefore prod. RECAP: ok /changed / unreachable /failed. become for sudo.Train hands-on. Pass with proof. — Techclick
Tap the Preview button at the top to save this one-page card before your interview.
Prove it with --check, ping, and a second run

Don't close an Ansible ticket on 'should be fine'. ansible all -m ping proves connectivity; --check --diff proves what a change WOULD do; and running the same play a second time should report changed=0 — that final check proves idempotency. These three answer the vast majority of Ansible problems.

👉 So far: Scale with AAP/AWX job templates + dynamic inventory; de-risk with --check --diff, --limit and serial; escalate with become. Read the RECAP first: unreachable=SSH/auth, failed=the task, changed-every-run=broken idempotency, undefined var=precedence.

🤖 Ask the AI Tutor

Tap any question — instant, scoped to this lesson. No login, no waiting.

Pre-curated from Ansible docs + community Q&A, scoped to this lesson. For a live prod issue, paste your export into chat.techclick.in.

📝 Wrap-up assessment — six more

You've answered 4 inline. Six left. 70% (7 of 10) marks the lesson complete on your profile. Tap Submit all answers at the end.

Q5 · Remember

What does it mean that Ansible is 'idempotent'?

Correct: b. Idempotency means a task changes the system only if it is not already in the desired state, so re-running a playbook is safe and predictable — the defining property of Ansible and the most-tested interview concept.
Q6 · Apply

An Indian IT-services team must patch 200 servers but cannot risk an outage. What is the right pre-flight?

Correct: a. --check is a dry run (no changes), --diff shows exactly what would change, --limit canaries one batch, and serial rolls the real run out in controlled waves so a failure stops early — the textbook way to de-risk a large change.
Q7 · Evaluate

You need a DB password inside a Git-tracked playbook repo. Which is correct?

Correct: c. Ansible Vault encrypts secrets at rest (AES256); you commit only ciphertext and decrypt at runtime via --ask-vault-pass / a vault-id / an AAP Vault credential. Plaintext or base64 in Git is an instant fail.
Q8 · Analyze

On the second run a playbook still reports changed=4 on every host. The most likely root cause is…

Correct: d. A truly idempotent play reports changed=0 on the second run. Persistent changes almost always come from command/shell tasks (which can't detect prior state) or missing creates:/changed_when: — switch to a real module or add the guards.
Q9 · Analyze

A play fails with 'unreachable=1' on one host while others succeed. Where do you look FIRST?

Correct: b. 'unreachable' is a transport problem, not a task problem — Ansible couldn't establish the SSH/WinRM session. Check ansible_user, the private key, the inventory entry, host-key trust and Python on the target. 'failed' (not 'unreachable') would point at the task.
Q10 · Evaluate

An interviewer says 'a playbook is basically just a shell script.' The best correction is…

Correct: a. A shell script runs the same imperative commands on every execution; an Ansible playbook declares the desired end state and its modules check current state, changing only what's needed (idempotency). That declarative + idempotent distinction — not the YAML syntax — is the real answer.
Lesson complete — saved to your profile.
Almost! You need 70% (7 of 10) — re-read the path that tripped you up and tap "Try again".

🧠 In your own words

Type one line: why is Ansible idempotency such a big deal? Then compare to the expert version.

Expert version: Because idempotency makes automation safe to run repeatedly. A task checks current state and changes the system only if it is not already in the desired state, so re-running a playbook never re-does work or causes drift — you get the same end state every time, whether it is the first run or the hundredth. That predictability is what lets teams run the same play across hundreds of production servers, schedule it, and trust it. The proof in an interview: a correct play reports changed=0 on its second consecutive run.

🗣 Teach a friend

Best way to lock it in — explain it in one line to a teammate. Tap to generate a paste-ready summary.

📖 Glossary

Control node
The machine where Ansible is installed and run from; reads inventory and pushes modules. The only node needing Ansible.
Managed node
A target host Ansible configures over SSH (Linux) or WinRM (Windows); needs no agent — just SSH + Python or WinRM.
Agentless
No persistent agent on targets — Ansible copies a module, runs it, then removes it each run.
Idempotency
Re-running a playbook converges to the same state; a task reports changed only when it truly alters the system.
Inventory
The host list — static (INI/YAML) or dynamic (cloud plugin) — grouped, with host_vars/group_vars.
Playbook vs role
Playbook = a YAML file of plays/tasks; role = a reusable standard directory (tasks/handlers/templates/defaults/…).
Handlers
Tasks that run once at the end of a play, only if a changed task notified them — usually a service restart.
Variable precedence
-e extra-vars wins; role defaults lose; the merge order decides which value applies per host.
Ansible Vault
Encrypts secrets at rest (AES256); encrypt whole files or single values (encrypt_string) — commit only ciphertext.
AAP / AWX
Enterprise (AAP, ex-Tower) / open-source (AWX) controller: job templates, RBAC, scheduling, logging, dynamic inventory.

📚 Sources

  1. Ansible Documentation — How Ansible works & the agentless architecture. docs.ansible.com
  2. Ansible Documentation — Intro to playbooks, handlers and variable precedence. docs.ansible.com
  3. Ansible Documentation — Roles, collections (FQCN) and Ansible Galaxy. docs.ansible.com / galaxy.ansible.com
  4. Ansible Documentation — Protecting sensitive data with Ansible Vault (encrypt_string). docs.ansible.com
  5. Red Hat — Ansible Automation Platform 2.5: Using automation execution — Job templates. docs.redhat.com
  6. Spacelift / igmGuru — Ansible interview questions & answers (2026). spacelift.io, igmguru.com

What's next?

Cleared the Ansible round? Keep going — the interview-prep library covers Docker, Kubernetes, Terraform, Jenkins, Linux and more, all in the same hands-on style.