Expert coverage of Ansible network automation across all ansible-core versions: network collections (cisco.ios, arista.eos, junipernetworks.junos), resource modules, connection plugins, Jinja2 templates, inventory design, config backup, and playbook patterns. Use for \"Ansible network\", \"network_cli\", \"resource module\", \"cisco.ios\", \"arista.eos\", \"junos\", \"Ansible playbook network\", \"Jinja2 template network\", \"Ansible VLAN\", \"Ansible BGP\". Do NOT use for cross-vendor compar...
Pro scans all 4 files and shows the line behind each finding
Scanned 9/24/2026
npx -y skills add chrishuffman5/domain-expert --skill ansible-network --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Ansible Network?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/chrishuffman5-ansible-network)More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.
---
name: ansible-network
description: "Expert coverage of Ansible network automation across all ansible-core versions: network collections (cisco.ios, arista.eos, junipernetworks.junos), resource modules, connection plugins, Jinja2 templates, inventory design, config backup, and playbook patterns. Use for \"Ansible network\", \"network_cli\", \"resource module\", \"cisco.ios\", \"arista.eos\", \"junos\", \"Ansible playbook network\", \"Jinja2 template network\", \"Ansible VLAN\", \"Ansible BGP\". Do NOT use for cross-vendor comparison, platform selection, or category-wide architecture -- use the `network-automation` skill. Do NOT use for general-purpose Ansible (playbooks, roles, AWX/Tower, non-network modules) -- that's the `ansible` skill (in the `devops` plugin)."
license: MIT
---
# Ansible Network Automation
This skill covers Ansible for network automation across all supported ansible-core versions. Areas of expertise include:
- Network connection plugins (network_cli, netconf, httpapi)
- Vendor collections (cisco.ios, cisco.nxos, cisco.iosxr, arista.eos, junipernetworks.junos, paloaltonetworks.panos)
- Network resource modules (declarative, idempotent resource management)
- Platform-agnostic modules (ansible.netcommon: cli_command, cli_config, netconf_config, netconf_get)
- Jinja2 templating for config generation
- Inventory design (static, dynamic from NetBox, group/host vars)
- Config backup and compliance checking
- Ansible Vault for secrets management
- Error handling, retry logic, and rescue blocks
- Role and collection development for network
When a question is version-specific, consult the matching `references/versions/` file. When the version is unknown, provide general guidance applicable to recent ansible-core releases.
## How to Approach Tasks
1. **Classify** the request:
- **Playbook development** -- Load `references/best-practices.md` for playbook structure, roles, error handling
- **Architecture** -- Load `references/architecture.md` for collections, connection plugins, resource modules, templates
- **Troubleshooting** -- Identify the platform, connection type, and error message. Common issues: SSH failures, module errors, idempotency problems
- **Migration** -- From scripts to Ansible, or between Ansible versions/collections
2. **Identify the target platform** -- Which network OS (IOS, NX-OS, EOS, Junos, PAN-OS)? This determines the collection and connection plugin.
3. **Identify the connection type** -- network_cli (SSH/CLI), netconf (NETCONF/XML), or httpapi (REST API). This affects module selection and behavior.
4. **Load context** -- Read the relevant reference file for deep knowledge.
5. **Analyze** -- Apply Ansible network-specific reasoning. Prefer resource modules over raw commands; prefer declarative over imperative.
6. **Recommend** -- Provide complete, runnable playbook examples with inventory, variables, and tasks.
7. **Verify** -- Suggest validation steps (`--check --diff`, `assert` tasks, post-change verification commands).
## Connection Plugins
### network_cli (SSH/CLI)
```yaml
ansible_connection: network_cli
ansible_network_os: cisco.ios.ios # or arista.eos.eos, etc.
```
- Connects via SSH, sends CLI commands, parses text output
- Most widely supported; works with any CLI-based device
- Used by `ios_command`, `ios_config`, `eos_command`, resource modules
- Requires `ansible_become: yes` and `ansible_become_method: enable` for privilege escalation
### netconf (NETCONF/XML)
```yaml
ansible_connection: netconf
ansible_network_os: junipernetworks.junos.junos
```
- Connects via SSH on port 830, exchanges structured XML
- Preferred for Junos (all modules use NETCONF)
- Available for IOS-XE, NX-OS, IOS-XR (specific modules)
- Returns structured data (no text parsing needed)
### httpapi (REST/HTTP API)
```yaml
ansible_connection: httpapi
ansible_network_os: arista.eos.eos
ansible_httpapi_use_ssl: true
```
- Connects via HTTPS to device REST API
- Preferred for Arista EOS (eAPI returns structured JSON)
- Used for PAN-OS XML API, F5 iControl REST
- Returns structured data natively
## Network Resource Modules
Resource modules are the preferred approach for network configuration. They manage a specific resource (VLANs, interfaces, OSPF, BGP) declaratively.
### State Parameter
| State | Behavior |
|---|---|
| `merged` | Merge provided config into existing (additive only) |
| `replaced` | Replace config for specified resources only |
| `overridden` | Replace entire resource config (removes anything not specified) |
| `deleted` | Remove specified configuration |
| `gathered` | Read current config into structured data (no changes) |
| `rendered` | Generate config text from data (no device connection) |
| `parsed` | Parse provided text into structured data (no device connection) |
### Resource Module Examples
**VLANs:**
```yaml
- name: Configure VLANs
cisco.ios.ios_vlans:
config:
- vlan_id: 10
name: MGMT
state: active
- vlan_id: 20
name: USERS
state: active
state: merged
```
**Interfaces:**
```yaml
- name: Configure interfaces
cisco.ios.ios_interfaces:
config:
- name: GigabitEthernet0/1
description: "Uplink to Core"
enabled: true
speed: "1000"
duplex: full
state: merged
```
**L2 Interfaces:**
```yaml
- name: Configure access ports
cisco.ios.ios_l2_interfaces:
config:
- name: GigabitEthernet0/1
mode: access
access:
vlan: 10
state: merged
```
**OSPF:**
```yaml
- name: Configure OSPF
cisco.ios.ios_ospfv2:
config:
processes:
- process_id: 1
router_id: 10.0.0.1
network:
- address: 192.168.1.0
wildcard_bits: 0.0.0.255
area: 0
state: merged
```
**BGP:**
```yaml
- name: Configure BGP
cisco.ios.ios_bgp_global:
config:
as_number: 65001
router_id: 10.0.0.1
neighbors:
- neighbor_address: 10.0.0.2
remote_as: 65002
description: "Peer to ISP"
state: merged
```
## Platform-Agnostic Modules
`ansible.netcommon` provides modules that work across platforms:
**cli_command** -- Run any CLI command:
```yaml
- name: Show version
ansible.netcommon.cli_command:
command: show version
register: version_output
```
**cli_config** -- Push config lines:
```yaml
- name: Configure banner
ansible.netcommon.cli_config:
config: "banner motd ^ Authorized access only ^"
```
**netconf_config** -- Push NETCONF config:
```yaml
- name: Apply NETCONF config
ansible.netcommon.netconf_config:
content: "{{ lookup('template', 'interface.xml.j2') }}"
target: candidate
commit: true
```
## Collection Reference
| Collection | Platform | Connection | Key Modules |
|---|---|---|---|
| `cisco.ios` | IOS / IOS-XE | network_cli | ios_vlans, ios_interfaces, ios_ospfv2, ios_bgp_global, ios_config, ios_command |
| `cisco.nxos` | NX-OS | network_cli / httpapi | nxos_vlans, nxos_interfaces, nxos_ospfv2, nxos_bgp_global, nxos_vrf |
| `cisco.iosxr` | IOS-XR | network_cli / netconf | iosxr_config, iosxr_command, iosxr_interfaces |
| `arista.eos` | Arista EOS | httpapi / network_cli | eos_vlans, eos_interfaces, eos_bgp_global, eos_ospfv2, eos_acls |
| `junipernetworks.junos` | Junos | netconf | junos_config, junos_command, junos_interfaces, junos_vlans |
| `paloaltonetworks.panos` | PAN-OS | httpapi | panos_security_rule, panos_address_object, panos_nat_rule |
## Jinja2 Templating
Jinja2 templates generate device configs from data models:
```jinja2
{# templates/ios_interface.j2 #}
{% for interface in interfaces %}
interface {{ interface.name }}
description {{ interface.description | default('No description') }}
{% if interface.ip is defined %}
ip address {{ interface.ip }} {{ interface.mask }}
no shutdown
{% endif %}
{% if interface.access_vlan is defined %}
switchport mode access
switchport access vlan {{ interface.access_vlan }}
{% endif %}
!
{% endfor %}
```
Usage in playbook:
```yaml
- name: Generate and push interface config
cisco.ios.ios_config:
src: "{{ lookup('template', 'ios_interface.j2') }}"
```
### Template Best Practices
- Use `| default()` filter for optional values
- Use `{% if %}` blocks for conditional config sections
- Use `{% for %}` loops for repetitive structures (interfaces, VLANs, neighbors)
- Test templates with `state: rendered` (generates config without connecting to device)
- Keep templates small and focused (one template per config section)
## Config Backup
```yaml
- name: Backup running config
cisco.ios.ios_config:
backup: yes
backup_options:
filename: "{{ inventory_hostname }}_{{ ansible_date_time.date }}.cfg"
dir_path: /backups/configs/
```
Automate scheduled backups via cron or CI/CD pipeline. Compare backups over time to detect drift.
## Facts and Data Collection
```yaml
- name: Gather device facts
cisco.ios.ios_facts:
gather_subset:
- default
- interfaces
- routing
- name: Display network resources
debug:
var: ansible_network_resources
```
`ansible_network_resources` contains structured data for all resource types (VLANs, interfaces, routing). Use this data to build dynamic playbooks.
## Common Pitfalls
1. **Using ios_command instead of resource modules** -- `ios_command` is imperative and not idempotent. Always prefer resource modules (ios_vlans, ios_interfaces) for configuration management.
2. **Forgetting ansible_become for IOS** -- IOS requires `enable` mode for configuration. Without `ansible_become: yes` and `ansible_become_method: enable`, config tasks fail with "% Invalid input detected."
3. **Hardcoding variables in playbooks** -- Use host_vars, group_vars, and inventory variables. Hardcoded values prevent reuse and violate IaC principles.
4. **Not using --check --diff in CI** -- Always run `ansible-playbook --check --diff` in CI/CD to preview changes before production deployment.
5. **Ignoring collection versions** -- Pin collection versions in `requirements.yml`. Unpinned collections may introduce breaking changes on update.
6. **Plaintext passwords in inventory** -- Use Ansible Vault for all credentials. Never commit plaintext passwords to Git.
7. **No error handling** -- Network tasks can fail (SSH timeout, device busy, syntax error). Use `block/rescue` to handle errors gracefully and `retries`/`delay` for transient failures.
8. **Monolithic playbooks** -- Break playbooks into roles (vlans, interfaces, routing, security). Roles are reusable, testable, and maintainable.
## Version-Specific Guidance
| Version | Reference | What's version-specific |
|---|---|---|
| 2.18 | `references/versions/2.18.md` | ansible-core 2.18+ features, collection updates, deprecations |
## Reference Files
Load these when you need deep knowledge:
- `references/architecture.md` -- Collections, connection plugins, resource modules, config backup, Jinja2 templates. Read for "how does X work" architecture questions.
- `references/best-practices.md` -- Inventory design, playbook structure, roles, Vault, error handling, idempotency patterns. Read for design and operations questions.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!