Compare
6.7 Compare agent vs. agentless orchestration tools
Aligned to Cisco's 350-401 ENCOR v1.2 exam topics.
On this page
What this objective tests
This is a compare objective. The exam asks which tool fits a scenario. The core question is: does the managed device need an installed agent?
Agentless tools connect over existing management interfaces. Agent-based tools install software on each managed node. Network devices rarely support agents. This is why agentless tools dominate network automation.
Agent versus agentless
| Area | Agent-based | Agentless |
|---|---|---|
| Managed node software | Agent installed and running | No agent needed |
| Transport | Agent protocol to the server | SSH, NETCONF, RESTCONF, or API |
| Direction | Agent pulls work from the server | Control node pushes work to the device |
| Enforcement | Continuous. The agent re-checks state | On demand or scheduled runs |
| Network device fit | Poor. Routers do not run third-party agents | Strong. Devices already have SSH and APIs |
| Main failure mode | Agent down or stale | Credential or reachability failure |
Note: Agentless does not mean no authentication. The control node still needs credentials and reachability.
The four tools
| Tool | Model | Transport | Push or pull | Language of definitions |
|---|---|---|---|---|
| Ansible | Agentless | SSH (network_cli for IOS) | Push from control node | YAML playbooks |
| Puppet | Agent-based | Agent over HTTPS | Agent pulls from primary server | Puppet DSL manifests |
| Chef | Agent-based | Agent over HTTPS | Agent pulls from Chef server | Ruby recipes |
| SaltStack | Agent-based by default, agentless option (SSH) | ZeroMQ bus or SSH | Push from master, minions react | YAML states |
Puppet and Chef agents check in on a schedule. They pull the desired state and enforce it continuously. Ansible pushes changes only when you run a playbook. SaltStack can run both ways, but its classic model uses an agent called a minion.
Idempotency
Idempotency means the same run produces the same result every time. Run the task once or ten times. The end state is identical.
Example: a task sets NTP server 10.10.10.5. The first run adds the line. Later runs see the line exists and change nothing. This property makes automation safe to repeat. Puppet, Chef, SaltStack, and Ansible modules are all designed around idempotency. Raw CLI scripts usually are not.
Example: an Ansible playbook for NTP on IOS
Inventory file inventory.ini:
[ios]
R1 ansible_host=10.10.10.11
R2 ansible_host=10.10.10.12
[ios:vars]
ansible_network_os=cisco.ios.ios
ansible_connection=ansible.netcommon.network_cli
ansible_user=adminPlaybook ntp.yml:
---
- name: Configure NTP on IOS devices
hosts: ios
gather_facts: false
tasks:
- name: Set NTP server
cisco.ios.ios_ntp_global:
config:
servers:
- server: 10.10.10.5
prefer: true
state: mergedRead each line:
name: a label for the play and the task. It appears in the output.hosts: iostargets theiosgroup from the inventory. Both routers get the change.gather_facts: falseskips server-style fact collection. Network modules do not need it. This saves time.cisco.ios.ios_ntp_globalis the module. It manages NTP configuration on IOS.servers:lists the NTP servers. The playbook sets10.10.10.5as preferred.state: mergedadds the config without removing other NTP lines. This gives idempotent behavior.
Run it:
ansible-playbook -i inventory.ini ntp.ymlExpected output:
PLAY [Configure NTP on IOS devices] *******************************************
TASK [Set NTP server] *********************************************************
changed: [R1]
changed: [R2]
PLAY RECAP ********************************************************************
R1 : ok=1 changed=1 unreachable=0 failed=0
R2 : ok=1 changed=1 unreachable=0 failed=0Run the same playbook again. The module reports ok=1 changed=0. That is idempotency in practice.
Lab: push NTP and prove idempotency
Topology: one control node with Ansible and two IOS XE routers. The routers permit SSH from the control node.
[Control node: Ansible] ---- SSH ---- [R1 10.10.10.11]
\---- [R2 10.10.10.12]Do these steps:
- Create
inventory.iniandntp.ymlfrom the example above. - Run
ansible-playbook -i inventory.ini ntp.yml. - Check the recap. Expect
changed=1per router on the first run. - Run
show run | include ntpon each router. Expectntp server 10.10.10.5 prefer. - Run the playbook a second time.
- Check the recap. Expect
changed=0per router. This proves idempotency. - Block SSH from the control node to R1. Run the playbook again. Note the
unreachable=1result. This is the classic agentless failure mode.
Exam traps
- Ansible is agentless and pushes over SSH. Puppet and Chef are agent-based and pull on a schedule.
- SaltStack uses a master and minions by default. It also supports agentless SSH.
- Agentless still needs credentials, reachability, and correct permissions.
- Idempotency means repeated runs stop making changes. It does not mean the first run makes no change.
- A controller such as Catalyst Center is not an orchestration agent. It is a separate automation target with its own API.
Pass check
You are ready when you can do these things:
- Sort Ansible, Puppet, Chef, and SaltStack into agent-based or agentless in one pass.
- Explain push versus pull with one example each.
- Explain idempotency and recognize it in playbook output (
changed=0). - Read an IOS Ansible playbook and name the hosts, the module, and the state.
- Give one reason agentless tools fit network devices better than agent-based tools.
Sources used
- Cisco ENCOR 350-401 v1.2 exam topics: https://learningcontent.cisco.com/documents/marketing/exam-topics/350-401-ENCORE-v1.2.pdf
- Ansible Community documentation: https://docs.ansible.com/projects/ansible/latest/getting_started/introduction.html
- Ansible installation guide, agentless control node model: https://docs.ansible.com/projects/ansible/latest/installation_guide/intro_installation.html