Back to skills
SKILL.md
Ansible Network
ASecurityExpert 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...
- 4 stars
- 0 votes
- 0 copies
- 0 views
- Added September 24, 2026
Works with
Security analysis
100/100Pro scans all 4 files and shows the line behind each finding
npx -y skills add chrishuffman5/domain-expert --skill ansible-network --agent claude-codeAre you the author of Ansible Network?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/chrishuffman5-ansible-network)---
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.
Files in this skill
- SKILL.md
- references/architecture.md
- references/best-practices.md
- references/versions/2.18.md
Attribution
Comments
Loading comments…