Chapter 2. Use a Playbook to establish a connection to a managed node To confirm your credentials, you can connect to a network device manually and retrieve its configuration. Replace the sample user and device name with your real credentials. For example, for a VyOS router: ssh my_vyos_user@vyos.example.net show config exit 2.1. Run a network Ansible command Instead of manually connecting and running a command on the network device, you can retrieve its configuration with a single Ansible command. ansible all -i vyos.example.net, -c ansible.netcommon.network_cli -u \ my_vyos_user -k -m vyos.vyos.vyos_facts -e \ ansible_network_os=vyos.vyos.vyos The flags in this command set seven values: the host group(s) to which the command should apply (in this case, all ) the inventory ( -i , the device or devices to target - without the trailing comma -i points to an inventory file) the connection method ( -c , the method for connecting and executing ansible) the user ( -u , the username for the SSH connection) the SSH connection method (- k , prompt for the password) the module ( -m , the Ansible module to run, using the fully qualified collection name (FQCN)) an extra variable ( -e , in this case, setting the network OS value) Note If you use ssh-agent with ssh keys, Ansible loads them automatically. You can omit the -k flag. If you are running Ansible in a virtual environment, you must also add the variable ansible_python_interpreter=/path/to/venv/bin/python . 2.2. Running a network Ansible Playbook If you want to run a particular command every day, you can save it in a playbook and run it with ansible-playbook instead of ansible. The playbook can store a lot of the parameters you provided with flags at the command line, leaving less to type at the command line. You need two files for this, a playbook and an inventory file. Prerequisites Download first_playbook.yml from here . The playbook looks like this: --- - name: Network Getting Started First Playbook connection: ansible.netcommon.network_cli gather_facts: false 1 hosts: all tasks: - name: Get config for VyOS devices vyos.vyos.vyos_facts: gather_subset: all - name: Display the config debug: msg: "The hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}" Label Description gather_facts Ansible's native fact gathering ( ansible.builtin.setup ) is disabled here because the playbook relies on the facts provided by a platform-specific module ( vyos.vyos.vyos_facts ) in this networking collection. The playbook sets three of the seven values from the command line above: the group ( hosts: all ) the connection method ( connection: ansible.netcommon.network_cli ) and the module (in each task). With those values set in the playbook, you can omit them on the command line. The playbook also adds a second task to show the configuration output. When facts are gathered from a system, either through a collection-specific fact module such as vyos.vyos.vyos_facts or ansible.builtin.setup , the gathered data is held in memory for use by future tasks instead of being written to the console. When a module runs in a playbook, the output is held in memory for use by future tasks instead of written to the console. With most other modules you must explicitly register a variable to store and reuse the output of a module or task. For more information about facts, see [Ansible facts] in the Ansiible Playbook Reference Guide . The following debug task lets you see the results in your shell. Procedure Run the playbook with the following command. ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos.vyos.vyos first_playbook.yml The playbook contains one play with two tasks, and generates output like this. USD ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos.vyos.vyos first_playbook.yml PLAY [Network Getting Started First Playbook] *************************************************************************************************************************** TASK [Get config for VyOS devices] *************************************************************************************************************************** ok: [vyos.example.net] TASK [Display the config] *************************************************************************************************************************** ok: [vyos.example.net] => { "msg": "The hostname is vyos and the OS is VyOS 1.1.8" } Now that you can retrieve the device configuration, you can try updating it with Ansible. Download first_playbook_ext.yml from here , which is an extended version of the first playbook: The playbook looks like this: --- - name: Network Getting Started First Playbook Extended connection: ansible.netcommon.network_cli gather_facts: false hosts: all tasks: - name: Get config for VyOS devices vyos.vyos.vyos_facts: gather_subset: all - name: Display the config debug: msg: "The hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}" - name: Update the hostname vyos.vyos.vyos_config: backup: yes lines: - set system host-name vyos-changed - name: Get changed config for VyOS devices vyos.vyos.vyos_facts: gather_subset: all - name: Display the changed config debug: msg: "The new hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}" The extended first playbook has five tasks in a single play. Run the playbook with the following command. USD ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos.vyos.vyos first_playbook_ext.yml The output shows you the change Ansible made to the configuration: USD ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos.vyos.vyos first_playbook_ext.yml PLAY [Network Getting Started First Playbook Extended] ************************************************************************************************************************************ TASK [Get config for VyOS devices] ********************************************************************************************************************************** ok: [vyos.example.net] TASK [Display the config] ************************************************************************************************************************************* ok: [vyos.example.net] => { "msg": "The hostname is vyos and the OS is VyOS 1.1.8" } TASK [Update the hostname] ************************************************************************************************************************************* changed: [vyos.example.net] TASK [Get changed config for VyOS devices] ************************************************************************************************************************************* ok: [vyos.example.net] TASK [Display the changed config] ************************************************************************************************************************************* ok: [vyos.example.net] => { "msg": "The new hostname is vyos-changed and the OS is VyOS 1.1.8" } PLAY RECAP ************************************************************************************************************************************ vyos.example.net : ok=5 changed=1 unreachable=0 failed=0 2.3. Gather facts from network devices The gather_facts keyword supports gathering network device facts in standardized key/value pairs. You can feed these network facts into further tasks to manage the network device. You can also use the gather_network_resources parameter with the network *_facts modules (such as arista.eos.eos_facts ) to return a subset of the device configuration, as shown below. - hosts: arista gather_facts: True gather_subset: interfaces module_defaults: arista.eos.eos_facts: gather_network_resources: interfaces The playbook returns the following interface facts: "network_resources": { "interfaces": [ { "description": "test-interface", "enabled": true, "mtu": "512", "name": "Ethernet1" }, { "enabled": true, "mtu": "3000", "name": "Ethernet2" }, { "enabled": true, "name": "Ethernet3" }, { "enabled": true, "name": "Ethernet4" }, { "enabled": true, "name": "Ethernet5" }, { "enabled": true, "name": "Ethernet6" }, ] } Note gather_network_resources renders configuration data as facts for all supported resources ( interfaces/bgp/ospf/etc` ), whereas gather_subset is primarily used to fetch operational data. You can store these facts and use them directly in another task, such as with the eos_interfaces resource module.

Commands:
ssh my_vyos_user@vyos.example.net show config exit
ansible all -i vyos.example.net, -c ansible.netcommon.network_cli -u my_vyos_user -k -m vyos.vyos.vyos_facts -e ansible_network_os=vyos.vyos.vyos
--- - name: Network Getting Started First Playbook connection: ansible.netcommon.network_cli gather_facts: false 1 hosts: all tasks: - name: Get config for VyOS devices vyos.vyos.vyos_facts: gather_subset: all - name: Display the config debug: msg: "The hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}"
ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos.vyos.vyos first_playbook.yml
ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos.vyos.vyos first_playbook.yml PLAY [Network Getting Started First Playbook] *************************************************************************************************************************** TASK [Get config for VyOS devices] *************************************************************************************************************************** ok: [vyos.example.net] TASK [Display the config] *************************************************************************************************************************** ok: [vyos.example.net] => { "msg": "The hostname is vyos and the OS is VyOS 1.1.8" }
--- - name: Network Getting Started First Playbook Extended connection: ansible.netcommon.network_cli gather_facts: false hosts: all tasks: - name: Get config for VyOS devices vyos.vyos.vyos_facts: gather_subset: all - name: Display the config debug: msg: "The hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}" - name: Update the hostname vyos.vyos.vyos_config: backup: yes lines: - set system host-name vyos-changed - name: Get changed config for VyOS devices vyos.vyos.vyos_facts: gather_subset: all - name: Display the changed config debug: msg: "The new hostname is {{ ansible_net_hostname }} and the OS is {{ ansible_net_version }}"
ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos.vyos.vyos first_playbook_ext.yml
ansible-playbook -i vyos.example.net, -u ansible -k -e ansible_network_os=vyos.vyos.vyos first_playbook_ext.yml PLAY [Network Getting Started First Playbook Extended] ************************************************************************************************************************************ TASK [Get config for VyOS devices] ********************************************************************************************************************************** ok: [vyos.example.net] TASK [Display the config] ************************************************************************************************************************************* ok: [vyos.example.net] => { "msg": "The hostname is vyos and the OS is VyOS 1.1.8" } TASK [Update the hostname] ************************************************************************************************************************************* changed: [vyos.example.net] TASK [Get changed config for VyOS devices] ************************************************************************************************************************************* ok: [vyos.example.net] TASK [Display the changed config] ************************************************************************************************************************************* ok: [vyos.example.net] => { "msg": "The new hostname is vyos-changed and the OS is VyOS 1.1.8" } PLAY RECAP ************************************************************************************************************************************ vyos.example.net : ok=5 changed=1 unreachable=0 failed=0
- hosts: arista gather_facts: True gather_subset: interfaces module_defaults: arista.eos.eos_facts: gather_network_resources: interfaces
"network_resources": { "interfaces": [ { "description": "test-interface", "enabled": true, "mtu": "512", "name": "Ethernet1" }, { "enabled": true, "mtu": "3000", "name": "Ethernet2" }, { "enabled": true, "name": "Ethernet3" }, { "enabled": true, "name": "Ethernet4" }, { "enabled": true, "name": "Ethernet5" }, { "enabled": true, "name": "Ethernet6" }, ] }