Agentless: Nothing to Install on the Servers
Scenario: A competing tool needs a daemon installed and kept upgraded on all 400 machines, plus a certificate for each one. The security team asks who is going to patch 400 extra long-running processes.
New words, in plain English
- Agent - a program permanently installed and running on a managed machine so a central system can control it.
- Agentless - the opposite: the control machine connects on demand and leaves nothing running behind.
- Control node - the machine you run Ansible from - your laptop, or a CI runner.
- Managed host / managed node - any machine Ansible configures. It needs no Ansible installed.
- SSH - Secure Shell: the standard, already-installed way to run commands on a remote Linux machine over an encrypted connection.
- Python interpreter - the program that runs Python code. Ansible ships small Python programs to the target and runs them there.
Ansible runs entirely from the control node. For each task it: opens an SSH connection to the managed host, copies a small self-contained Python program (a module) into a temporary directory there, executes it, reads back a JSON result, and deletes the temporary files. Nothing is left running.
That means the only prerequisites on a managed Linux host are an SSH daemon and a Python interpreter - both of which a normal server already has. There is no agent to install, no agent to upgrade, no agent port to firewall, and no agent to be a fresh attack surface.
The trade-offs are real and worth knowing. Because there is no resident agent, Ansible is push-based: change happens when someone runs it, not continuously. And because every task is a fresh connection round-trip, very large fleets need tuning (persistent connections, pipelining, more parallel workers) that an agent-based tool gets for free.
Analogy: An agent-based tool posts a permanent employee to every building and pays their salary forever. Ansible is a contractor with a key: they let themselves in, do the work, clean up, and leave. Nobody is on site between visits - which is cheaper and safer, but also means nothing happens unless you send them.
A worked example
# What actually crosses the wire for ONE task:
#
# control node managed host
# ------------ ------------
# ssh connect ...................> sshd accepts
# copy module .py ...............> /home/you/.ansible/tmp/xxx/
# run: python3 xxx/AnsiballZ_file.py
# <.......... {"changed": true, "path": "..."}
# rm -rf tmp dir ................>
# close connection
#
# You never see any of this. You just see:
# changed: [web01]
Two consequences shape everything later in this track. First, Ansible runs as whichever SSH user you connect as - so "who am I on the target?" is a first-class design question, not an afterthought. Second, because each task is a separate execution, tasks cannot share shell state: a cd in one task does not affect the next, and an environment variable exported in one task is gone by the next.
Network devices, Windows hosts and cloud APIs are handled by the same engine with different connection plugins - WinRM or PSRP for Windows, HTTP APIs for cloud services, and local/network_cli for appliances. The agentless idea generalises; only the transport changes.
Warning: Because tasks do not share a shell,shell: cd /opt && ./build.shin one task andshell: make installin the next will NOT run in the same directory. Use each module's ownchdiroption instead.
Goal: Put this to work in the ansible-become-scope lab. Open/labs/ansible, pickansible-become-scope, and fix the real broken project - Ansible really does SSH into four managed hosts and converge them.