Home » news »

An introduction to network automation with Ansible


Ansible directory and file structure

Ansible can run with a simple configuration, but that path leads to a jumble of different constructs. It’s much better to build a directory structure that segregates different types of configuration data. For our example, we will use the following directory and file structure:

├── ansible.cfg
├── group_vars
│   ├── IOS_switches.yml
├── host_vars
│   └── test_sw.yml
├── inventory.yml
└── sh_arp.yml

The ansible.cfg file contains Ansible’s configuration. Default values are frequently the best choice, so this file may not be needed. It is in INI format, which uses name = value syntax. Device fact gathering is disabled — i.e., gathering = explicit — because it is intended for non-network devices. The inventory file name is identified and retries are disabled, as shown below.

     1  [defaults]
     2  gathering = explicit
     3  inventory = inventory.yml
     4  retry_files_enabled = False

The group_vars directory contains variable definitions that apply to different groups. One YAML-formatted file in this directory contains variables for Internetwork Operating System (IOS) switches.

With IOS_switches.yml, we specify the Ansible module network_cli, set the OS to ios and specify the login credentials. The recommended secure configuration uses either Ansible vaults or SSH keys, so the credentials are not kept in a plain-text file. However, including the credentials in a variable file is much simpler for the demonstration below.

     1  ---
     2  # IOS_switches variables
     3  ansible_connection: network_cli
     4  ansible_network_os: ios
     5  ansible_become: yes
     6  ansible_become_method: enable
     7  ansible_become_password: "foobar"
     9  ansible_user: tester
    10  ansible_ssh_pass: foobar

The host_vars directory contains variable definitions that are specific to each device. A good example is a host variable with its management IP address and hostname. Variables that exist in the host files will supersede the same group variables, enabling users to override variables for specific devices.

For example, here is the test_sw.yml structure:

     1  ---
     2  # test_sw variables
     3  ipaddr:
     4  hostname: test_sw

The inventory.yml file lists the inventory of devices, along with device groups, using YAML format. Devices can be contained in multiple groups. The device test_sw is a member of the groups IOS_switches and access.

     1  ---
     2  all:
     3    children:
     4      IOS_switches:
     5        hosts:
     6          test_sw
     7      IOS_routers:
     8        hosts:
     9          router1
    10      access:
    11        hosts:
    12          test_sw
    13      core:
    14        hosts:
    15          router1

The sh_arp.yml file — in YAML format — is known as an Ansible playbook. It controls Ansible’s execution of the task to show the ARP table and display the output. A playbook can contain multiple plays, and each play can contain multiple tasks.

Below, we name the play Gather ARP data, and the hosts are those listed in the IOS_switches group. This play has two tasks, each with a name. These names are simply text strings that will appear in the output. The ios_command module is used to execute the command show arp. The directive register is used to save the output of ios_command into an Ansible variable named cli_result.

Task 2 simply prints the saved result, referencing the list of stdout_lines that is in the saved cli_result.

     1  ---
     2  - name: Gather ARP data
     3    hosts: IOS_switches
     4    tasks:
     5      - name: "Task 1: Get output of show arp on IOS"
     6        ios_command:
     7          commands: "show arp"
     8        register: cli_result
    10      - name: "Task 2: Display stdout_lines[0]"
    11        debug:
    12          msg: "{{ cli_result.stdout_lines[0] }}"

Below, we run the Ansible script.

     1     $ ansible-playbook sh_arp.yml
     3     PLAY [Gather ARP data] ***************************************************
     5     TASK [Task 1: Get output of show arp on IOS] *****************************
     6     ok: [test_sw]
     8     TASK [Task 2: Display stdout_lines[0]] ***********************************
     9     ok: [test_sw] = {
    10         "msg": [
    11             "Protocol  Address     Age (min)  Hardware Addr   Type   Interface",
    12             "Internet      -   bcc4.933e.49c0  ARPA   Vlan1",
    13             "Internet      5   f894.c220.2177  ARPA   Vlan1",
    14             "Internet      1   88c2.55fb.9ce7  ARPA   Vlan1",
    15             "Internet      0   a860.b60a.7a3a  ARPA   Vlan1"
    16         ]
    17     }
    19     PLAY RECAP ***************************************************************
    20     test_sw                    : ok=2    changed=0    unreachable=0    failed=0  

Related Posts

  • No Related Posts