Écrire un premier playbook

1. Rappel théoriques

Maintenant que vous en savez assez sur le fichier d’inventaire et les variables de groupe et d’hôte, nous allons écrire notre premier livre de jeu.

Playbook definition for network automation

  • La cible d’un jeu est défini par la directive hosts
  • Définir le type de connexion : connection : network_cli
  • À propos de gather_facts

Exécuter un livre de jeu

---
- name: GATHER INFORMATION FROM ROUTERS
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: GATHER ROUTER FACTS
      ios_facts:
ansible-playbook gather_ios_data.yml
PLAY [GATHER INFORMATION FROM ROUTERS] ******************************************************************

TASK [GATHER ROUTER FACTS] ******************************************************************************
ok: [rtr1]
ok: [rtr4]
ok: [rtr3]
ok: [rtr2]

PLAY RECAP **********************************************************************************************
rtr1                       : ok=1    changed=0    unreachable=0    failed=0   
rtr2                       : ok=1    changed=0    unreachable=0    failed=0   
rtr3                       : ok=1    changed=0    unreachable=0    failed=0   
rtr4                       : ok=1    changed=0    unreachable=0    failed=0   

[root@ansible networking-workshop]#

Visualiser la sortie

On peut activer la verbosité avec le flag -v avec l’exécution.

ansible-playbook gather_ios_data.yml  -v
Using /root/networking-workshop/ansible.cfg as config file

PLAY [GATHER INFORMATION FROM ROUTERS] ***********************************************************

TASK [GATHER ROUTER FACTS] ***********************************************************************
ok: [rtr3] => {"ansible_facts": {"ansible_net_all_ipv4_addresses": ["192.168.122.180"], "ansible_net_all_ipv6_addresses": [], "ansible_net_filesystems": ["flash0:"], "ansible_net_gather_subset": ["hardware", "default", "interfaces"], "ansible_net_hostname": "rtr3", "ansible_net_image": "flash0:/vios-adventerprisek9-m", "ansible_net_interfaces": {"GigabitEthernet0/0": {"bandwidth": 1000000, "description": null, "duplex": "Auto", "ipv4": [], "lineprotocol": "down ", "macaddress": "0c2c.013f.da00", "mediatype": "RJ45", "mtu": 1500, "operstatus": "administratively down", "type": "iGbE"}, "GigabitEthernet0/1": {"bandwidth": 1000000, "description": null, "duplex": "Auto", "ipv4": [], "lineprotocol": "down ", "macaddress": "0c2c.013f.da01", "mediatype": "RJ45", "mtu": 1500, "operstatus": "administratively down", "type": "iGbE"}, "GigabitEthernet0/2": {"bandwidth": 1000000, "description": null, "duplex": "Auto", "ipv4":
.
.
<output truncated for readability>

Augmentez le niveau de verbosité en ajoutant des “v’s” -vvv

Limiter l’exécution du livre de jeu

L’exécution du livre de jeu peut être limité à un ensemble d’hôte de l’inventaire avec le drapeau –limit.

ansible-playbook gather_ios_data.yml  -v --limit rtr1

Les variables magiques

Enfin des variables définies par les utilisateurs, Ansible supporte des magic inbuilt variables.

VariableExplanation
ansible_*Variables venant du fact gathering
inventory_hostnameNom du périphérique dans l’inventaire
hostvarsUn dictionnaire variable où inventory_hostname est une des clés

Voir les sorties avec le module debug

Le module debug permet d’afficher les sorties.

Les variables sont placées entre doubles accolades ({{ }}) et encadrées par des guillemets ("{{ variable }}") avec l’option msg:

Démonstration :

- name: GATHER INFORMATION FROM ROUTERS
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: GATHER ROUTER FACTS
      ios_facts:
    - name: DEBUG MODULE DEMO
      debug:
        msg: "{{ inventory_hostname }} serial {{ ansible_net_serialnum }}"
ansible-playbook debug-demo.yml
PLAY [GATHER INFORMATION FROM ROUTERS] ***********************************************************

TASK [GATHER ROUTER FACTS] ***********************************************************************
ok: [rtr2]
ok: [rtr3]
ok: [rtr1]
ok: [rtr4]

TASK [DEBUG MODULE DEMO] *************************************************************************
ok: [rtr2] => {
    "msg": "rtr2 serial 92CY5AR6CZG9XCOPUMY7L"
}
ok: [rtr3] => {
    "msg": "rtr3 serial 9FFT4CW16AQ2XMZP8DAWR"
}
ok: [rtr4] => {
    "msg": "rtr4 serial 9HFRMZNWS2JVU4AJO4THG"
}
ok: [rtr1] => {
    "msg": "rtr1 serial 9X1SIJ0FS0CFUA56J3XHI"
}

PLAY RECAP ***************************************************************************************
rtr1                       : ok=2    changed=0    unreachable=0    failed=0
rtr2                       : ok=2    changed=0    unreachable=0    failed=0
rtr3                       : ok=2    changed=0    unreachable=0    failed=0
rtr4                       : ok=2    changed=0    unreachable=0    failed=0

2. Lab

Étape 1

Avec votre éditeur de texte favori (vim ou nano ou encore atom), créer un fichier gather_ios_data.yml.

Les livres de jeu sont écrits en langage YAML.

vim gather_ios_data.yml

Étape 2

Entrez la définition du jeu gather_ios_data.yml:

Pressez la touche “i pour entrer en mode insertion (vi)

---
- name: GATHER INFORMATION FROM ROUTERS
  hosts: cisco
  connection: network_cli
  gather_facts: no

--- indicates that this is a YAML file. We are running this playbook against the group cisco, that was defined earlier in the inventory file. Playbooks related to network devices should use the connection plugin called network_cli. Ansible has different connection plugins that handle different connection interfaces. The network_cli plugin is written specifically for network equipment and handles things like ensuring a persistent SSH connection across multiple tasks.

Étape 3

Next, add the first task. This task will use the ios_facts module to gather facts about each device in the group cisco.

---
- name: GATHER INFORMATION FROM ROUTERS
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: GATHER ROUTER FACTS
      ios_facts:

A play is a list of tasks. Modules are pre-written code that perform the task.

Étape 4

Run the playbook - exit back into the command line of the control host and execute the following:

Use the write/quit method in vim to save your playbook, i.e. Esc :wq!

ansible-playbook gather_ios_data.yml

The output should look as follows.

PLAY [GATHER INFORMATION FROM ROUTERS] ******************************************************************

TASK [GATHER ROUTER FACTS] ******************************************************************************
ok: [rtr1]
ok: [rtr4]
ok: [rtr3]
ok: [rtr2]

PLAY RECAP **********************************************************************************************
rtr1                       : ok=1    changed=0    unreachable=0    failed=0   
rtr2                       : ok=1    changed=0    unreachable=0    failed=0   
rtr3                       : ok=1    changed=0    unreachable=0    failed=0   
rtr4                       : ok=1    changed=0    unreachable=0    failed=0   

Étape 5

The play ran successfully and executed against the 4 routers. But where is the output?! Re-run the playbook using the -v flag.

Note: Ansible has increasing level of verbosity. You can use up to 4 “v’s”, -vvvv.

ansible-playbook  gather_ios_data.yml -v
PLAY [GATHER INFORMATION FROM ROUTERS] ***********************************************************

TASK [GATHER ROUTER FACTS] ***********************************************************************
ok: [rtr3] => {"ansible_facts": {"ansible_net_all_ipv4_addresses": ["192.168.122.180"], "ansible_net_all_ipv6_addresses": [], "ansible_net_filesystems": ["flash0:"], "ansible_net_gather_subset": ["hardware", "default", "interfaces"], "ansible_net_hostname": "rtr3", "ansible_net_image": "flash0:/vios-adventerprisek9-m", "ansible_net_interfaces": {"GigabitEthernet0/0": {"bandwidth": 1000000, "description": null, "duplex": "Auto", "ipv4": [], "lineprotocol": "down ", "macaddress": "0c2c.013f.da00", "mediatype": "RJ45", "mtu": 1500, "operstatus": "administratively down", "type": "iGbE"}, "GigabitEthernet0/1": {"bandwidth": 1000000, "description": null, "duplex": "Auto", "ipv4": [], "lineprotocol": "down ", "macaddress": "0c2c.013f.da01", "mediatype": "RJ45", "mtu": 1500, "operstatus": "administratively down", "type": "iGbE"}, "GigabitEthernet0/2": {"bandwidth": 1000000, "description": null, "duplex": "Auto", "ipv4":
.
.
<output truncated for readability>

Note: The output returns key-value pairs that can then be used within the playbook for subsequent tasks. Also note that all variables that start with ansible_ are automatically available for subsequent tasks within the play.

Par exemple, une sortie complète :

{
  "ansible_facts": {
    "ansible_net_all_ipv4_addresses": [
      "192.168.226.1",
      "192.168.225.1",
      "11.11.11.159",
      "192.168.1.1",
      "11.12.13.145"
    ],
    "ansible_net_all_ipv6_addresses": [
      "FD00:0:0:1::1"
    ],
    "ansible_net_filesystems": [
      "flash0:"
    ],
    "ansible_net_filesystems_info": {
      "flash0:": {
        "spacefree_kb": 1947660,
        "spacetotal_kb": 2092496
      }
    },
    "ansible_net_gather_subset": [
      "hardware",
      "default",
      "interfaces"
    ],
    "ansible_net_hostname": "R1",
    "ansible_net_image": "flash0:/vios-adventerprisek9-m",
    "ansible_net_interfaces": {
      "GigabitEthernet0/0": {
        "bandwidth": 1000000,
        "description": "TODO",
        "duplex": null,
        "ipv4": [
          {
            "address": "192.168.1.1",
            "subnet": "24"
          }
        ],
        "ipv6": [
          {
            "address": "FD00:0:0:1::1",
            "subnet": "FD00:0:0:1::/64"
          }
        ],
        "lineprotocol": "up ",
        "macaddress": "0c3b.6204.1b00",
        "mediatype": "RJ45",
        "mtu": 1500,
        "operstatus": "up",
        "type": "iGbE"
      },
      "GigabitEthernet0/1": {
        "bandwidth": 1000000,
        "description": "TODO",
        "duplex": null,
        "ipv4": [
          {
            "address": "11.11.11.159",
            "subnet": "24"
          }
        ],
        "lineprotocol": "up ",
        "macaddress": "0c3b.6204.1b01",
        "mediatype": "RJ45",
        "mtu": 1500,
        "operstatus": "up",
        "type": "iGbE"
      },
      "GigabitEthernet0/2": {
        "bandwidth": 1000000,
        "description": "TODO",
        "duplex": null,
        "ipv4": [
          {
            "address": "192.168.225.1",
            "subnet": "24"
          }
        ],
        "ipv6": [],
        "lineprotocol": "up ",
        "macaddress": "0c3b.6204.1b02",
        "mediatype": "RJ45",
        "mtu": 1500,
        "operstatus": "up",
        "type": "iGbE"
      },
      "GigabitEthernet0/3": {
        "bandwidth": 1000000,
        "description": "TODO",
        "duplex": null,
        "ipv4": [
          {
            "address": "192.168.226.1",
            "subnet": "24"
          }
        ],
        "ipv6": [],
        "lineprotocol": "up ",
        "macaddress": "0c3b.6204.1b03",
        "mediatype": "RJ45",
        "mtu": 1500,
        "operstatus": "up",
        "type": "iGbE"
      },
      "GigabitEthernet0/4": {
        "bandwidth": 1000000,
        "description": null,
        "duplex": "Auto",
        "ipv4": [],
        "lineprotocol": "down ",
        "macaddress": "0c3b.6204.1b04",
        "mediatype": "RJ45",
        "mtu": 1500,
        "operstatus": "administratively down",
        "type": "iGbE"
      },
      "GigabitEthernet0/5": {
        "bandwidth": 1000000,
        "description": null,
        "duplex": "Auto",
        "ipv4": [],
        "lineprotocol": "down ",
        "macaddress": "0c3b.6204.1b05",
        "mediatype": "RJ45",
        "mtu": 1500,
        "operstatus": "administratively down",
        "type": "iGbE"
      },
      "GigabitEthernet0/6": {
        "bandwidth": 1000000,
        "description": null,
        "duplex": "Auto",
        "ipv4": [],
        "lineprotocol": "down ",
        "macaddress": "0c3b.6204.1b06",
        "mediatype": "RJ45",
        "mtu": 1500,
        "operstatus": "administratively down",
        "type": "iGbE"
      },
      "GigabitEthernet0/7": {
        "bandwidth": 1000000,
        "description": null,
        "duplex": null,
        "ipv4": [
          {
            "address": "11.12.13.145",
            "subnet": "24"
          }
        ],
        "lineprotocol": "up ",
        "macaddress": "0c3b.6204.1b07",
        "mediatype": "RJ45",
        "mtu": 1500,
        "operstatus": "up",
        "type": "iGbE"
      },
      "NVI0": {
        "bandwidth": 56,
        "description": null,
        "duplex": null,
        "ipv4": [],
        "lineprotocol": "up ",
        "macaddress": null,
        "mediatype": null,
        "mtu": 1514,
        "operstatus": "up",
        "type": null
      }
    },
    "ansible_net_memfree_mb": 170619,
    "ansible_net_memtotal_mb": 265782,
    "ansible_net_model": "IOSv",
    "ansible_net_serialnum": "90I6G7VWM6FBM875LG6WJ",
    "ansible_net_version": "15.6(2)T"
  },
  "changed": false
}

Étape 6

Ansible allows you to limit the playbook execution to a subset of the devices declared in the group, against which the play is running against. This can be done using the --limit flag. Rerun the above task, limiting it first to rtr1 and then to both rtr1 and rtr3

ansible-playbook gather_ios_data.yml  -v --limit rtr1
ansible-playbook gather_ios_data.yml  -v --limit rtr1,rtr3

Étape 7

Running a playbook in verbose mode is a good option to validate the output from a task. To work with the variables within a playbook you can use the debug module.

Write 2 tasks that display the routers OS version and serial number.

---
- name: GATHER INFORMATION FROM ROUTERS
  hosts: cisco
  connection: network_cli
  gather_facts: no

  tasks:
    - name: GATHER ROUTER FACTS
      ios_facts:

    - name: DISPLAY VERSION
      debug:
        msg: "The IOS version is: {{ ansible_net_version }}"

    - name: DISPLAY SERIAL NUMBER
      debug:
        msg: "The serial number is:{{ ansible_net_serialnum }}"

Étape 8

Now re-run the playbook but this time do not use the verbose flag and run it against all hosts.

ansible-playbook gather_ios_data.yml

PLAY [GATHER INFORMATION FROM ROUTERS] ******************************************************************

TASK [GATHER ROUTER FACTS] ******************************************************************************
ok: [rtr4]
ok: [rtr1]
ok: [rtr2]
ok: [rtr3]

TASK [DISPLAY VERSION] **********************************************************************************
ok: [rtr4] => {
    "msg": "The IOS version is: 16.08.01a"
}
ok: [rtr1] => {
    "msg": "The IOS version is: 16.08.01a"
}
ok: [rtr2] => {
    "msg": "The IOS version is: 16.08.01a"
}
ok: [rtr3] => {
    "msg": "The IOS version is: 16.08.01a"
}

TASK [DISPLAY SERIAL NUMBER] ****************************************************************************
ok: [rtr1] => {
    "msg": "The serial number is:96F0LYYKYUZ"
}
ok: [rtr4] => {
    "msg": "The serial number is:94KZZ28ZT1Y"
}
ok: [rtr2] => {
    "msg": "The serial number is:9VBX7BSSLGS"
}
ok: [rtr3] => {
    "msg": "The serial number is:9OLKU6JWXRP"
}

PLAY RECAP **********************************************************************************************
rtr1                       : ok=3    changed=0    unreachable=0    failed=0   
rtr2                       : ok=3    changed=0    unreachable=0    failed=0   
rtr3                       : ok=3    changed=0    unreachable=0    failed=0   
rtr4                       : ok=3    changed=0    unreachable=0    failed=0   

Using less than 20 lines of “code” you have just automated version and serial number collection. Imagine if you were running this against your production network! You have actionable data in hand that does not go out of date.

La documentation des variables est dans la page de documentation du module ios_facts.

Note : Le module setup permet de prendre connaissance d’autres variables.

ansible rtr1 -m setup -c network_cli

Offrant par exemple :

{
  "ansible_all_ipv4_addresses": [
    "11.12.13.1",
    "192.168.122.141"
  ],
  "ansible_all_ipv6_addresses": [
    "fe80::e3b:62ff:fec4:8400",
    "fe80::650f:9efe:7bf7:e320"
  ],
  "ansible_apparmor": {
    "status": "disabled"
  },
  "ansible_architecture": "x86_64",
  "ansible_bios_date": "04/01/2014",
  "ansible_bios_version": "1.10.2-1ubuntu1",
  "ansible_cmdline": {
    "BOOT_IMAGE": "/vmlinuz-3.10.0-862.14.4.el7.x86_64",
    "LANG": "en_US.UTF-8",
    "console": "ttyS0",
    "crashkernel": "auto",
    "rd.lvm.lv": "centos_c7/swap",
    "ro": true,
    "root": "/dev/mapper/centos_c7-root"
  },
  "ansible_date_time": {
    "date": "2019-05-24",
    "day": "24",
    "epoch": "1558701055",
    "hour": "14",
    "iso8601": "2019-05-24T12:30:55Z",
    "iso8601_basic": "20190524T143055431529",
    "iso8601_basic_short": "20190524T143055",
    "iso8601_micro": "2019-05-24T12:30:55.431950Z",
    "minute": "30",
    "month": "05",
    "second": "55",
    "time": "14:30:55",
    "tz": "CEST",
    "tz_offset": "+0200",
    "weekday": "Friday",
    "weekday_number": "5",
    "weeknumber": "20",
    "year": "2019"
  },
  "ansible_default_ipv4": {
    "address": "192.168.122.141",
    "alias": "eth1",
    "broadcast": "192.168.122.255",
    "gateway": "192.168.122.1",
    "interface": "eth1",
    "macaddress": "0c:3b:62:c4:84:01",
    "mtu": 1500,
    "netmask": "255.255.255.0",
    "network": "192.168.122.0",
    "type": "ether"
  },
  "ansible_default_ipv6": {},
  "ansible_device_links": {
    "ids": {
      "dm-0": [
        "dm-name-centos_c7-root",
        "dm-uuid-LVM-4qzwGtk5i77k15HQQm1rs8BOLW0zW86xQ4xbpBrfHB9bcgeCPcVMNtx1MpjiyVx0"
      ],
      "dm-1": [
        "dm-name-centos_c7-swap",
        "dm-uuid-LVM-4qzwGtk5i77k15HQQm1rs8BOLW0zW86xH3jeO5MDHHKoImmOR3n5lncw438lOPJK"
      ],
      "sr0": [
        "ata-QEMU_DVD-ROM_QM00003"
      ],
      "vda2": [
        "lvm-pv-uuid-lWn6Dc-024p-fhIv-38AU-D3OV-1alQ-qzRSXD"
      ]
    },
    "labels": {},
    "masters": {
      "vda2": [
        "dm-0",
        "dm-1"
      ]
    },
    "uuids": {
      "dm-0": [
        "0adc1746-d1d1-4b39-855e-4facda93f74e"
      ],
      "dm-1": [
        "ab6df0a2-e298-4f87-aca9-d17fc8bf8a9c"
      ],
      "vda1": [
        "f35879c5-512c-4a33-94d1-31eee186890e"
      ]
    }
  },
  "ansible_devices": {
    "dm-0": {
      "holders": [],
      "host": "",
      "links": {
        "ids": [
          "dm-name-centos_c7-root",
          "dm-uuid-LVM-4qzwGtk5i77k15HQQm1rs8BOLW0zW86xQ4xbpBrfHB9bcgeCPcVMNtx1MpjiyVx0"
        ],
        "labels": [],
        "masters": [],
        "uuids": [
          "0adc1746-d1d1-4b39-855e-4facda93f74e"
        ]
      },
      "model": null,
      "partitions": {},
      "removable": "0",
      "rotational": "1",
      "sas_address": null,
      "sas_device_handle": null,
      "scheduler_mode": "",
      "sectors": "12992512",
      "sectorsize": "512",
      "size": "6.20 GB",
      "support_discard": "0",
      "vendor": null,
      "virtual": 1
    },
    "dm-1": {
      "holders": [],
      "host": "",
      "links": {
        "ids": [
          "dm-name-centos_c7-swap",
          "dm-uuid-LVM-4qzwGtk5i77k15HQQm1rs8BOLW0zW86xH3jeO5MDHHKoImmOR3n5lncw438lOPJK"
        ],
        "labels": [],
        "masters": [],
        "uuids": [
          "ab6df0a2-e298-4f87-aca9-d17fc8bf8a9c"
        ]
      },
      "model": null,
      "partitions": {},
      "removable": "0",
      "rotational": "1",
      "sas_address": null,
      "sas_device_handle": null,
      "scheduler_mode": "",
      "sectors": "1679360",
      "sectorsize": "512",
      "size": "820.00 MB",
      "support_discard": "0",
      "vendor": null,
      "virtual": 1
    },
    "fd0": {
      "holders": [],
      "host": "",
      "links": {
        "ids": [],
        "labels": [],
        "masters": [],
        "uuids": []
      },
      "model": null,
      "partitions": {},
      "removable": "1",
      "rotational": "1",
      "sas_address": null,
      "sas_device_handle": null,
      "scheduler_mode": "deadline",
      "sectors": "8",
      "sectorsize": "512",
      "size": "4.00 KB",
      "support_discard": "0",
      "vendor": null,
      "virtual": 1
    },
    "sr0": {
      "holders": [],
      "host": "",
      "links": {
        "ids": [
          "ata-QEMU_DVD-ROM_QM00003"
        ],
        "labels": [],
        "masters": [],
        "uuids": []
      },
      "model": "QEMU DVD-ROM",
      "partitions": {},
      "removable": "1",
      "rotational": "1",
      "sas_address": null,
      "sas_device_handle": null,
      "scheduler_mode": "deadline",
      "sectors": "2097151",
      "sectorsize": "512",
      "size": "1024.00 MB",
      "support_discard": "0",
      "vendor": "QEMU",
      "virtual": 1
    },
    "vda": {
      "holders": [],
      "host": "",
      "links": {
        "ids": [],
        "labels": [],
        "masters": [],
        "uuids": []
      },
      "model": null,
      "partitions": {
        "vda1": {
          "holders": [],
          "links": {
            "ids": [],
            "labels": [],
            "masters": [],
            "uuids": [
              "f35879c5-512c-4a33-94d1-31eee186890e"
            ]
          },
          "sectors": "2097152",
          "sectorsize": 512,
          "size": "1.00 GB",
          "start": "2048",
          "uuid": "f35879c5-512c-4a33-94d1-31eee186890e"
        },
        "vda2": {
          "holders": [
            "centos_c7-root",
            "centos_c7-swap"
          ],
          "links": {
            "ids": [
              "lvm-pv-uuid-lWn6Dc-024p-fhIv-38AU-D3OV-1alQ-qzRSXD"
            ],
            "labels": [],
            "masters": [
              "dm-0",
              "dm-1"
            ],
            "uuids": []
          },
          "sectors": "14678016",
          "sectorsize": 512,
          "size": "7.00 GB",
          "start": "2099200",
          "uuid": null
        }
      },
      "removable": "0",
      "rotational": "1",
      "sas_address": null,
      "sas_device_handle": null,
      "scheduler_mode": "mq-deadline",
      "sectors": "16777216",
      "sectorsize": "512",
      "size": "8.00 GB",
      "support_discard": "0",
      "vendor": "0x1af4",
      "virtual": 1
    }
  },
  "ansible_distribution": "CentOS",
  "ansible_distribution_file_parsed": true,
  "ansible_distribution_file_path": "/etc/redhat-release",
  "ansible_distribution_file_variety": "RedHat",
  "ansible_distribution_major_version": "7",
  "ansible_distribution_release": "Core",
  "ansible_distribution_version": "7.5.1804",
  "ansible_dns": {
    "nameservers": [
      "192.168.122.1",
      "127.0.0.1"
    ]
  },
  "ansible_domain": "",
  "ansible_effective_group_id": 0,
  "ansible_effective_user_id": 0,
  "ansible_env": {
    "HISTCONTROL": "ignoredups",
    "HISTSIZE": "1000",
    "HOME": "/root",
    "HOSTNAME": "controller",
    "LANG": "en_US.UTF-8",
    "LESSOPEN": "||/usr/bin/lesspipe.sh %s",
    "LOGNAME": "root",
    "LS_COLORS": "rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:",
    "MAIL": "/var/spool/mail/root",
    "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin",
    "PWD": "/root/networking-workshop",
    "SHELL": "/bin/bash",
    "SHLVL": "3",
    "SSH_CLIENT": "172.16.253.6 63448 22",
    "SSH_CONNECTION": "172.16.253.6 63448 192.168.122.141 22",
    "SSH_TTY": "/dev/pts/0",
    "TERM": "xterm-256color",
    "USER": "root",
    "XDG_RUNTIME_DIR": "/run/user/0",
    "XDG_SESSION_ID": "3",
    "_": "/usr/bin/python"
  },
  "ansible_eth0": {
    "active": true,
    "device": "eth0",
    "features": {
      "busy_poll": "off [fixed]",
      "fcoe_mtu": "off [fixed]",
      "generic_receive_offload": "on",
      "generic_segmentation_offload": "off [requested on]",
      "highdma": "on [fixed]",
      "hw_tc_offload": "off [fixed]",
      "l2_fwd_offload": "off [fixed]",
      "large_receive_offload": "off [fixed]",
      "loopback": "off [fixed]",
      "netns_local": "off [fixed]",
      "ntuple_filters": "off [fixed]",
      "receive_hashing": "off [fixed]",
      "rx_all": "off [fixed]",
      "rx_checksumming": "off [fixed]",
      "rx_fcs": "off [fixed]",
      "rx_udp_tunnel_port_offload": "off [fixed]",
      "rx_vlan_filter": "on [fixed]",
      "rx_vlan_offload": "off [fixed]",
      "rx_vlan_stag_filter": "off [fixed]",
      "rx_vlan_stag_hw_parse": "off [fixed]",
      "scatter_gather": "off",
      "tcp_segmentation_offload": "off",
      "tx_checksum_fcoe_crc": "off [fixed]",
      "tx_checksum_ip_generic": "off [fixed]",
      "tx_checksum_ipv4": "off [fixed]",
      "tx_checksum_ipv6": "off [fixed]",
      "tx_checksum_sctp": "off [fixed]",
      "tx_checksumming": "off",
      "tx_fcoe_segmentation": "off [fixed]",
      "tx_gre_csum_segmentation": "off [fixed]",
      "tx_gre_segmentation": "off [fixed]",
      "tx_gso_partial": "off [fixed]",
      "tx_gso_robust": "off [fixed]",
      "tx_ipip_segmentation": "off [fixed]",
      "tx_lockless": "off [fixed]",
      "tx_nocache_copy": "off",
      "tx_scatter_gather": "off [fixed]",
      "tx_scatter_gather_fraglist": "off [fixed]",
      "tx_sctp_segmentation": "off [fixed]",
      "tx_sit_segmentation": "off [fixed]",
      "tx_tcp6_segmentation": "off [fixed]",
      "tx_tcp_ecn_segmentation": "off [fixed]",
      "tx_tcp_mangleid_segmentation": "off [fixed]",
      "tx_tcp_segmentation": "off [fixed]",
      "tx_udp_tnl_csum_segmentation": "off [fixed]",
      "tx_udp_tnl_segmentation": "off [fixed]",
      "tx_vlan_offload": "off [fixed]",
      "tx_vlan_stag_hw_insert": "off [fixed]",
      "udp_fragmentation_offload": "off [fixed]",
      "vlan_challenged": "off [fixed]"
    },
    "hw_timestamp_filters": [],
    "ipv4": {
      "address": "11.12.13.1",
      "broadcast": "11.12.13.255",
      "netmask": "255.255.255.0",
      "network": "11.12.13.0"
    },
    "ipv6": [
      {
        "address": "fe80::e3b:62ff:fec4:8400",
        "prefix": "64",
        "scope": "link"
      }
    ],
    "macaddress": "0c:3b:62:c4:84:00",
    "module": "virtio_net",
    "mtu": 1500,
    "pciid": "virtio0",
    "promisc": false,
    "timestamping": [
      "rx_software",
      "software"
    ],
    "type": "ether"
  },
  "ansible_eth1": {
    "active": true,
    "device": "eth1",
    "features": {
      "busy_poll": "off [fixed]",
      "fcoe_mtu": "off [fixed]",
      "generic_receive_offload": "on",
      "generic_segmentation_offload": "off [requested on]",
      "highdma": "on [fixed]",
      "hw_tc_offload": "off [fixed]",
      "l2_fwd_offload": "off [fixed]",
      "large_receive_offload": "off [fixed]",
      "loopback": "off [fixed]",
      "netns_local": "off [fixed]",
      "ntuple_filters": "off [fixed]",
      "receive_hashing": "off [fixed]",
      "rx_all": "off [fixed]",
      "rx_checksumming": "off [fixed]",
      "rx_fcs": "off [fixed]",
      "rx_udp_tunnel_port_offload": "off [fixed]",
      "rx_vlan_filter": "on [fixed]",
      "rx_vlan_offload": "off [fixed]",
      "rx_vlan_stag_filter": "off [fixed]",
      "rx_vlan_stag_hw_parse": "off [fixed]",
      "scatter_gather": "off",
      "tcp_segmentation_offload": "off",
      "tx_checksum_fcoe_crc": "off [fixed]",
      "tx_checksum_ip_generic": "off [fixed]",
      "tx_checksum_ipv4": "off [fixed]",
      "tx_checksum_ipv6": "off [fixed]",
      "tx_checksum_sctp": "off [fixed]",
      "tx_checksumming": "off",
      "tx_fcoe_segmentation": "off [fixed]",
      "tx_gre_csum_segmentation": "off [fixed]",
      "tx_gre_segmentation": "off [fixed]",
      "tx_gso_partial": "off [fixed]",
      "tx_gso_robust": "off [fixed]",
      "tx_ipip_segmentation": "off [fixed]",
      "tx_lockless": "off [fixed]",
      "tx_nocache_copy": "off",
      "tx_scatter_gather": "off [fixed]",
      "tx_scatter_gather_fraglist": "off [fixed]",
      "tx_sctp_segmentation": "off [fixed]",
      "tx_sit_segmentation": "off [fixed]",
      "tx_tcp6_segmentation": "off [fixed]",
      "tx_tcp_ecn_segmentation": "off [fixed]",
      "tx_tcp_mangleid_segmentation": "off [fixed]",
      "tx_tcp_segmentation": "off [fixed]",
      "tx_udp_tnl_csum_segmentation": "off [fixed]",
      "tx_udp_tnl_segmentation": "off [fixed]",
      "tx_vlan_offload": "off [fixed]",
      "tx_vlan_stag_hw_insert": "off [fixed]",
      "udp_fragmentation_offload": "off [fixed]",
      "vlan_challenged": "off [fixed]"
    },
    "hw_timestamp_filters": [],
    "ipv4": {
      "address": "192.168.122.141",
      "broadcast": "192.168.122.255",
      "netmask": "255.255.255.0",
      "network": "192.168.122.0"
    },
    "ipv6": [
      {
        "address": "fe80::650f:9efe:7bf7:e320",
        "prefix": "64",
        "scope": "link"
      }
    ],
    "macaddress": "0c:3b:62:c4:84:01",
    "module": "virtio_net",
    "mtu": 1500,
    "pciid": "virtio1",
    "promisc": false,
    "timestamping": [
      "rx_software",
      "software"
    ],
    "type": "ether"
  },
  "ansible_fips": false,
  "ansible_form_factor": "Other",
  "ansible_fqdn": "controller",
  "ansible_hostname": "controller",
  "ansible_interfaces": [
    "lo",
    "eth1",
    "eth0"
  ],
  "ansible_is_chroot": false,
  "ansible_iscsi_iqn": "",
  "ansible_kernel": "3.10.0-862.14.4.el7.x86_64",
  "ansible_lo": {
    "active": true,
    "device": "lo",
    "features": {
      "busy_poll": "off [fixed]",
      "fcoe_mtu": "off [fixed]",
      "generic_receive_offload": "on",
      "generic_segmentation_offload": "on",
      "highdma": "on [fixed]",
      "hw_tc_offload": "off [fixed]",
      "l2_fwd_offload": "off [fixed]",
      "large_receive_offload": "off [fixed]",
      "loopback": "on [fixed]",
      "netns_local": "on [fixed]",
      "ntuple_filters": "off [fixed]",
      "receive_hashing": "off [fixed]",
      "rx_all": "off [fixed]",
      "rx_checksumming": "on [fixed]",
      "rx_fcs": "off [fixed]",
      "rx_udp_tunnel_port_offload": "off [fixed]",
      "rx_vlan_filter": "off [fixed]",
      "rx_vlan_offload": "off [fixed]",
      "rx_vlan_stag_filter": "off [fixed]",
      "rx_vlan_stag_hw_parse": "off [fixed]",
      "scatter_gather": "on",
      "tcp_segmentation_offload": "on",
      "tx_checksum_fcoe_crc": "off [fixed]",
      "tx_checksum_ip_generic": "on [fixed]",
      "tx_checksum_ipv4": "off [fixed]",
      "tx_checksum_ipv6": "off [fixed]",
      "tx_checksum_sctp": "on [fixed]",
      "tx_checksumming": "on",
      "tx_fcoe_segmentation": "off [fixed]",
      "tx_gre_csum_segmentation": "off [fixed]",
      "tx_gre_segmentation": "off [fixed]",
      "tx_gso_partial": "off [fixed]",
      "tx_gso_robust": "off [fixed]",
      "tx_ipip_segmentation": "off [fixed]",
      "tx_lockless": "on [fixed]",
      "tx_nocache_copy": "off [fixed]",
      "tx_scatter_gather": "on [fixed]",
      "tx_scatter_gather_fraglist": "on [fixed]",
      "tx_sctp_segmentation": "on",
      "tx_sit_segmentation": "off [fixed]",
      "tx_tcp6_segmentation": "on",
      "tx_tcp_ecn_segmentation": "on",
      "tx_tcp_mangleid_segmentation": "on",
      "tx_tcp_segmentation": "on",
      "tx_udp_tnl_csum_segmentation": "off [fixed]",
      "tx_udp_tnl_segmentation": "off [fixed]",
      "tx_vlan_offload": "off [fixed]",
      "tx_vlan_stag_hw_insert": "off [fixed]",
      "udp_fragmentation_offload": "on",
      "vlan_challenged": "on [fixed]"
    },
    "hw_timestamp_filters": [],
    "ipv4": {
      "address": "127.0.0.1",
      "broadcast": "host",
      "netmask": "255.0.0.0",
      "network": "127.0.0.0"
    },
    "ipv6": [
      {
        "address": "::1",
        "prefix": "128",
        "scope": "host"
      }
    ],
    "mtu": 65536,
    "promisc": false,
    "timestamping": [
      "rx_software",
      "software"
    ],
    "type": "loopback"
  },
  "ansible_local": {},
  "ansible_lsb": {},
  "ansible_lvm": {
    "lvs": {
      "root": {
        "size_g": "6.20",
        "vg": "centos_c7"
      },
      "swap": {
        "size_g": "0.80",
        "vg": "centos_c7"
      }
    },
    "pvs": {
      "/dev/vda2": {
        "free_g": "0",
        "size_g": "7.00",
        "vg": "centos_c7"
      }
    },
    "vgs": {
      "centos_c7": {
        "free_g": "0",
        "num_lvs": "2",
        "num_pvs": "1",
        "size_g": "7.00"
      }
    }
  },
  "ansible_machine": "x86_64",
  "ansible_machine_id": "67837007899b48a4969ab2c2e43c20da",
  "ansible_memfree_mb": 675,
  "ansible_memory_mb": {
    "nocache": {
      "free": 787,
      "used": 204
    },
    "real": {
      "free": 675,
      "total": 991,
      "used": 316
    },
    "swap": {
      "cached": 0,
      "free": 819,
      "total": 819,
      "used": 0
    }
  },
  "ansible_memtotal_mb": 991,
  "ansible_mounts": [
    {
      "block_available": 1215238,
      "block_size": 4096,
      "block_total": 1621504,
      "block_used": 406266,
      "device": "/dev/mapper/centos_c7-root",
      "fstype": "xfs",
      "inode_available": 3193621,
      "inode_total": 3248128,
      "inode_used": 54507,
      "mount": "/",
      "options": "rw,relatime,attr2,inode64,noquota",
      "size_available": 4977614848,
      "size_total": 6641680384,
      "uuid": "0adc1746-d1d1-4b39-855e-4facda93f74e"
    },
    {
      "block_available": 192929,
      "block_size": 4096,
      "block_total": 259584,
      "block_used": 66655,
      "device": "/dev/vda1",
      "fstype": "xfs",
      "inode_available": 523947,
      "inode_total": 524288,
      "inode_used": 341,
      "mount": "/boot",
      "options": "rw,relatime,attr2,inode64,noquota",
      "size_available": 790237184,
      "size_total": 1063256064,
      "uuid": "f35879c5-512c-4a33-94d1-31eee186890e"
    }
  ],
  "ansible_nodename": "controller",
  "ansible_os_family": "RedHat",
  "ansible_pkg_mgr": "yum",
  "ansible_processor": [
    "0",
    "GenuineIntel",
    "QEMU Virtual CPU version 2.5+",
    "1",
    "GenuineIntel",
    "QEMU Virtual CPU version 2.5+"
  ],
  "ansible_processor_cores": 1,
  "ansible_processor_count": 2,
  "ansible_processor_threads_per_core": 1,
  "ansible_processor_vcpus": 2,
  "ansible_product_name": "Standard PC (i440FX + PIIX, 1996)",
  "ansible_product_serial": "NA",
  "ansible_product_uuid": "9861876C-2A57-4E3D-8B97-2A5CC777C484",
  "ansible_product_version": "pc-i440fx-bionic",
  "ansible_python": {
    "executable": "/usr/bin/python",
    "has_sslcontext": true,
    "type": "CPython",
    "version": {
      "major": 2,
      "micro": 5,
      "minor": 7,
      "releaselevel": "final",
      "serial": 0
    },
    "version_info": [
      2,
      7,
      5,
      "final",
      0
    ]
  },
  "ansible_python_version": "2.7.5",
  "ansible_real_group_id": 0,
  "ansible_real_user_id": 0,
  "ansible_selinux": {
    "status": "disabled"
  },
  "ansible_selinux_python_present": true,
  "ansible_service_mgr": "systemd",
  "ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHFgDdiWalyoZDTTyEhKkHAgHVtFnSO1qOIrv7BsYZXQMADSCcr8ycM8NnIW833pGzAx0WiQPCJ1kdUIgAPSmpM=",
  "ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAIMpAULUx2ilr+eq106KqbcwsgxA0iNo7ggJkWOlZQd67",
  "ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDKDhzOs5nDGmYzFGFaBHz6+bOCGk93mFAo0mNcWyibdtOqwXK+gfhRJAg8tm3A5b/SirSrTM0Esv9vQiQVsp1w5VmnAKn7JpI4FCtKmkkh+zKSpsOhfpc1mDazKPXgSBpJD09O63ZgqV2tVxQMwRTR6Cti8AcbGdfXBUH5usqLuQmjtTbtTyZVIRPIA0m9RgRtA6LyWvt4/VnvcJYDGwqmIip/YBAR5Jy7i8pe8B2FPSgQ1tCetXgvExE9gAT4GmIgrLnTWsDYHXS6XVkQ+KI/RWsjuGnjCo92pdr1q0ozX6/2hoBuybMgYrad0kHkWBOvVs6BArkAzKZ/r9Ha0t0p",
  "ansible_swapfree_mb": 819,
  "ansible_swaptotal_mb": 819,
  "ansible_system": "Linux",
  "ansible_system_capabilities": [
    "cap_chown",
    "cap_dac_override",
    "cap_dac_read_search",
    "cap_fowner",
    "cap_fsetid",
    "cap_kill",
    "cap_setgid",
    "cap_setuid",
    "cap_setpcap",
    "cap_linux_immutable",
    "cap_net_bind_service",
    "cap_net_broadcast",
    "cap_net_admin",
    "cap_net_raw",
    "cap_ipc_lock",
    "cap_ipc_owner",
    "cap_sys_module",
    "cap_sys_rawio",
    "cap_sys_chroot",
    "cap_sys_ptrace",
    "cap_sys_pacct",
    "cap_sys_admin",
    "cap_sys_boot",
    "cap_sys_nice",
    "cap_sys_resource",
    "cap_sys_time",
    "cap_sys_tty_config",
    "cap_mknod",
    "cap_lease",
    "cap_audit_write",
    "cap_audit_control",
    "cap_setfcap",
    "cap_mac_override",
    "cap_mac_admin",
    "cap_syslog",
    "35",
    "36+ep"
  ],
  "ansible_system_capabilities_enforced": "True",
  "ansible_system_vendor": "QEMU",
  "ansible_uptime_seconds": 2929,
  "ansible_user_dir": "/root",
  "ansible_user_gecos": "root",
  "ansible_user_gid": 0,
  "ansible_user_id": "root",
  "ansible_user_shell": "/bin/bash",
  "ansible_user_uid": 0,
  "ansible_userspace_architecture": "x86_64",
  "ansible_userspace_bits": "64",
  "ansible_virtualization_role": "guest",
  "ansible_virtualization_type": "kvm",
  "gather_subset": [
    "all"
  ],
  "module_setup": true
}