É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.

Définition d’un premier livre de jeu

  • Le livre de jeu est une liste (de jeux) qui commence par trois “dash” : ---
  • La cible d’un jeu est défini par la directive hosts qui désigne soit :
    • un hôte ou un groupe
    • le groupe all
    • l’hôte implicite localhost
  • Il est utile définir le plugin de connexion : connection : network_cli
  • La collection de facts est générée par le module ios_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

Les données sont collectées mais n’apparaissent pas sur la sortie.

Visualiser les résultats sur la sortie

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

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>

Augmentez le niveau de verbosité en ajoutant plusieurs “v” -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

Veuillez entrer la définition du jeu gather_ios_data.yml.

Pressez la touche “i” pour entrer en mode insertion (vi) et puis ESC et puis “:x” pour enregistrer et sortir.

---
- name: GATHER INFORMATION FROM ROUTERS
  hosts: cisco
  connection: network_cli
  gather_facts: no
  • Le livre de jeu est une liste qui commence par trois “dash” : ---
  • La cible d’un jeu est défini par la directive hosts qui désigne soit :
    • un hôte ou un groupe
    • le groupe all
    • l’hôte implicite localhost
  • Il est utile définir le plugin de connexion : connection : network_cli
  • La collection de facts est générée par le module ios_facts.

Étape 3

Ensuite, veuillez ajouter la première tâche. Cette tâche utilise le module ios_facts pour récupérer les métadonnées (“facts”) des périphériques du groupe cisco.

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

  tasks:
    - name: GATHER ROUTER FACTS
      ios_facts:

Un livre de jeu est une liste de jeux.

Un jeu est une liste de tâches (ou semblables).

Un module est du code pré-écrit qui exécute une tâche.

Étape 4

Veuillez sortir de l’édition du texte (:x) et exécutez le livre de jeu :

ansible-playbook gather_ios_data.yml

La sortie devrait ressembler à ceci :

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

Le jeu a été bien été exécuté mais rien n’apparait sur la sortie. On active la verbosité activée en ajoutant l’option -v :

On peut augmenter la verbosité avec plusieur “v” -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 : La sortie retourne des paires de clé/valeurs qui peuvent être appelées dans les tâches suivantes du livre de jeu. Aussi, notez que toutes les variables qui commencent par ansible_ sont directement disponibles dans la suite.

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 permet de limiter l’exécution du livre de jeu contre certains hôtes de l’inventaire avec l’option --limit ou -l. Par exemple les commandes suivantes lancent le livre de jeu d’abord seulement sur rtr1 et puis sur rtr1 et rtr3.

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

Ou encore :

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

Étape 7

Excécuter un livre de jeu en mode verbeux est une bonne option pour valider la sortie d’une tâche. Pour travailler avec les variables au sein d’un livre de jeu, on peut utiliser le module debug.

Veuillez ajouter une seconde tâche qui affiche l’OS du routeur et son numéro de série.

---
- 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

Maintenant, veuillez relancer le livre de jeu mais sans aucune option de verbosité contre tous les hôtes.

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

En utilisant moins de 20 lignes de “code”, vous avez automatisé la collection des versions et des numéros de série. Imaginez que vous faites fonctionner cette procédure sur un réseau de production !

La documentation des variables se situe 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
}

Licence

License MIT github.com/network-automation/linklight