Documentation des modules, enregistrer les sorties et tags

1. Théorie

Modules

Les modules sont ces pièces de code qui font le job d’Ansible, ils sont exécutés pour chaque tâche d’un livre de jeu.

  • Il sont typiquement écrits en Python (mais pas seulement).
  • Il sont idempotent (pas nécessairement leur usage).
  • Les modules prennent les entrées des utilisateurs en paramètres (arguments).

Modules pour l’automation du réseau

Les modules Ansible pour l’automation du réseau sont désignés par le constructeur de l’OS suivi d’un nom de module :

  • *_facts
  • *_command
  • *_config

Selon le nom des plateformes :

  • Arista EOS = eos_*
  • Cisco IOS/IOS-XE = ios_*
  • Cisco NX-OS = nxos_*
  • Cisco IOS-XR = iosxr_*
  • Juniper Junos = junos_*
  • VyOS = vyos_*

Mais on trouve aussi un grand nombre des modules spécialisés.

Modules par plateforme

- hosts: all
  connection: network_cli
  tasks:
    - name: configure eos system properties
      eos_system:
        domain_name: ansible.com
        vrf: management
      when: ansible_network_os == 'eos'

    - name: configure nxos system properties
      nxos_system:
        domain_name: ansible.com
        vrf: management
      when: ansible_network_os == 'nxos'

Documentation Web des modules

La documentation de Ansible est très complète : http://docs.ansible.com/ et particulièrement Ansible Network Modules.

Documentation des modules

Commande ansible-doc

Ansible embarque localement toute la documentation des modules comme sur le site Web.

# List out all modules installed
ansible-doc -l
...
ios_banner                                Manage multiline banners on Cisco IOS devices
ios_command                               Run commands on remote devices running Cisco IOS
ios_config                                Manage Cisco IOS configuration sections
...

# Read documentation for installed module
$ ansible-doc ios_command
> IOS_COMMAND

     Sends arbitrary commands to an ios node and returns the results read from the
     device. This module includes an argument that will cause the module to wait for a
     specific condition before returning or timing out if the condition is not met. This
     module does not support running commands in configuration mode. Please use
     [ios_config] to configure IOS devices.

Options (= is mandatory):
...

Limiter les tâches au sein d’un jeu

  • Les Tags permettent à l’utilisateur de sélectionner les tâches à exécuter au sein d’un jeu.
  • On peut attriber plusieurs étiquettes à une tâche (liste).
  • Les étiquettes peuvent être appliquées sur des jeux ou des rôles entiers.
    - name: DISPLAY THE COMMAND OUTPUT
      debug:
        var: show_output
      tags: show

Les étiquettes sont invoquées par l’option --tags ou -t lors de l’exécution du livre de jeu.

ansible-playbook gather_ios_data.yml --tags=show

Cette fonctionnalité peut être intéressante quand on travaille avec un grand livre de jeu pour sauter à une tâche spécifique.

Enregistrer une sortie

Le paramètre register est utilisé pour enregistrer le résultat d’une tâche dans une variable que l’on peut appeler dans une tâche ultérieure du livre de jeu.

    - name: COLLECT OUTPUT OF SHOW COMMANDS
      ios_command:
        commands:
          - show run | i hostname
          - show ip interface brief
      tags: show
      register: show_output

2. Lab

Dans le chapitre précédent, vous avez appris à utiliser les modules ios_facts et debug. Alors que le module ios_facts ne comportement pas d’arguments, on trouvera une paramètre msg avec le module debug.

Comment prendre connaissance des paramètres d’un module ?

Il y a deux options :

  1. Vous consultez la documentation en ligne sur l’adresse https://docs.ansible.com, pages “Network Modules”.
  2. Vous lancez la commande locale ansible-doc <module-name> qui vous livre les même informations sur votre console.

Étape 1

Sur l’hôte de contrôle, veuillez la documentation du module ios_facts et du module debug.

ansible-doc debug

Que se passe-t-il si vous ne précisez pas de paramètre avec le module debug ?

ansible-doc ios_facts

Comment pouvez-vous limiter les facts collectés ?

Étape 2

Dans le chapitre précédent, nous avons appris à utiliser le module ios_facts pour collecter des informations détaillées sur un périphérique. Mais comment récupérer le résultat d’une commande show qui n’est pas fourni avec le module ios_facts ? Le module ios_command le permet.

Il est proposé dans le suite d’ajouter une nouvelle tâche à notre livre de jeu qui collecte la sortie de deux commandes show pour prendre connaissance du hostname et show ip interface brief

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


    - name: COLLECT OUTPUT OF SHOW COMMANDS
      ios_command:
        commands:
          - show run | i hostname
          - show ip interface brief

commands est un paramètre obligatoire du module ios_command et qui prend en entrée une liste de commande.

Étape 3

Avant d’exécuter le livre de jeu, veuillez ajouter un “tag” nommé “show” sur la dernière tâche.

Les “tags” peuvent être associée à des tâches, des jeux ou des rôles au sein d’un livre de jeu. Vous pouvez attribuer plusieurs étiquettes sur une tâche. Les “tags” permettent de sélectionner l’exécution (ou la non-exécution) de certaines tâches du livre de jeu.

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


    - name: COLLECT OUTPUT OF SHOW COMMANDS
      ios_command:
        commands:
          - show run | i hostname
          - show ip interface brief
      tags: show

Étape 4

Veuillez exécuter le livre de jeu avec l’option --tags :

ansible-playbook gather_ios_data.yml --tags=show
PLAY [GATHER INFORMATION FROM ROUTERS] **************************************************************************

TASK [COLLECT OUTPUT OF SHOW COMMANDS] **************************************************************************
ok: [rtr2]
ok: [rtr3]
ok: [rtr1]
ok: [rtr4]

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

Deux éléments importants à retenir :

  1. Une seule tâche du livre de jeu a été exécutée.
  2. La sortie de la commande show n’est pas affichée.

Étape 5

Veuillez exécuter à nouveau le livre de jeu avec le “tag” nommé “show” et l’option de verbosité -v.

ansible-playbook  gather_ios_data.yml --tags=show -v

Étape 6

Le module ios_facts récupère des méta-données de la cible et les assigne automatiquement à des variables ansible_*. Pour récupérer les sorties des commandes, nous devons d’abord les “enregister” avec la directive de tâches register. Et puis seulement, nous pourrons les afficher (avec ou non un traitement prélable de la sortie).

Veuillez ajouter la directive register à la dernière tâche pour enregistrer le résultat dans une variable nommée “show_output” :

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

    - name: COLLECT OUTPUT OF SHOW COMMANDS
      ios_command:
        commands:
          - show run | i hostname
          - show ip interface brief
      tags: show
      register: show_output

Étape 7

Veuillez créer une nouvelle tâche qui utilise le module debug pour afficher le contenu de la variable show_output et qui dispose du “tag” nommé “show”.

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

    - name: COLLECT OUTPUT OF SHOW COMMANDS
      ios_command:
        commands:
          - show run | i hostname
          - show ip interface brief
      tags: show
      register: show_output

    - name: DISPLAY THE COMMAND OUTPUT
      debug:
        var: show_output
      tags: show

Veuillez noter l’usage de l’argument var au lieu de msg avec le module debug.

Quelle est la différence entre l’argument var et l’argument msg du module debug ?

Étape 8

Veuillez à nouveau exécuter le livre de jeu avec l’étiquette “show” mais sans verbosité aucune.

ansible-playbook  gather_ios_data.yml --tags=show
PLAY [GATHER INFORMATION FROM ROUTERS] **************************************************************************

TASK [COLLECT OUTPUT OF SHOW COMMANDS] **************************************************************************
ok: [rtr4]
ok: [rtr1]
ok: [rtr3]
ok: [rtr2]

TASK [DISPLAY THE COMMAND OUTPUT] *******************************************************************************
ok: [rtr4] => {
    "show_output": {
        "changed": false,
        "failed": false,
        "stdout": [
            "hostname rtr4",
            "Interface              IP-Address      OK? Method Status                Protocol\nGigabitEthernet1       172.17.231.181  YES DHCP   up                    up      \nLoopback0              192.168.4.104   YES manual up                    up      \nLoopback1              10.4.4.104      YES manual up                    up      \nTunnel0                10.101.101.4    YES manual up                    up      \nVirtualPortGroup0      192.168.35.101  YES TFTP   up                    up"
        ],
        "stdout_lines": [
            [
                "hostname rtr4"
            ],
            [
                "Interface              IP-Address      OK? Method Status                Protocol",
                "GigabitEthernet1       172.17.231.181  YES DHCP   up                    up      ",
                "Loopback0              192.168.4.104   YES manual up                    up      ",
                "Loopback1              10.4.4.104      YES manual up                    up      ",
                "Tunnel0                10.101.101.4    YES manual up                    up      ",
                "VirtualPortGroup0      192.168.35.101  YES TFTP   up                    up"
            ]
        ]
    }
}
ok: [rtr1] => {
    "show_output": {
        "changed": false,
.
<output omitted for brevity>

Étape 9

La variable show_output peut être désormais traitée comme un simple dictionnaire Python. Il contient une clé nommée stdout. Cette clé stdout est un objet de type liste qui contient autant d’éléments qu’il n’y a de commandes exécutées.

Ainsi le premier élément de la liste, show_output.stdout[0], contiendra le résultat de la commande show running | i hostname et le second élément de la liste, show_output.stdout[1], contiendra le résultat de la commande show ip interface brief.

Veuillez écrire une nouvelle tâche qui affiche seulement le “hostname” en utilisant le module debug.

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

    - name: COLLECT OUTPUT OF SHOW COMMANDS
      ios_command:
        commands:
          - show run | i hostname
          - show ip interface brief
      tags: show
      register: show_output

    - name: DISPLAY THE COMMAND OUTPUT
      debug:
        var: show_output
      tags: show

    - name: DISPLAY THE HOSTNAME
      debug:
        msg: "The hostname is {{ show_output.stdout[0] }}"
      tags: show

Étape 10

Veuillez exécuter une dernière fois le livre de jeu.

ansible-playbook  gather_ios_data.yml --tags=show
PLAY [GATHER INFORMATION FROM ROUTERS] **************************************************************************

TASK [COLLECT OUTPUT OF SHOW COMMANDS] **************************************************************************
ok: [rtr2]
ok: [rtr4]
ok: [rtr1]
ok: [rtr3]

TASK [DISPLAY THE COMMAND OUTPUT] *******************************************************************************
ok: [rtr2] => {
    "show_output": {
        "changed": false,
        "failed": false,
        "stdout": [
.
.
<output omitted for brevity>
. d
.
TASK [DISPLAY THE HOSTNAME] *************************************************************************************
ok: [rtr2] => {
    "msg": "The hostname is hostname rtr2"
}
ok: [rtr1] => {
    "msg": "The hostname is hostname rtr1"
}
ok: [rtr3] => {
    "msg": "The hostname is hostname rtr3"
}
ok: [rtr4] => {
    "msg": "The hostname is hostname rtr4"
}

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

[root@ansible networking-workshop]#

Licence

License MIT github.com/network-automation/linklight