Académique Documents
Professionnel Documents
Culture Documents
Préface 1.1
Introduction
Infrastructure as a Code 2.1
Description du projet Ansible 2.2
Mise en place
Procédures d'installation Ansible 3.1
Annexes
Toplogie Tripod 5.1
Topologie LAN 5.2
Guide Ansible
Description : Automation réseau et système Ansible
Copyright
Automation réseau Ansible, © François-Emmanuel Goffinet, 2018
Bibliographie
Documentation Ansible
Jason Edelman, Network Automation with Ansible, O’Reilly Media, Inc, 2016.
Lorin Hochstein, Rene Moser, Ansible: Up and Running, 2nd Edition, O’Reilly Media, Inc, 2018.
Ansible Automation Workshops
Versions du document
Date de fabrication : Fri Sep 28 2018 21:29:45 GMT+0200 (CEST)
Version HTML
Version PDF
Version EPUB
Version MOBI
1. Infrastructure as a Code
1. Infrastructure en tant que code (IAC)
2. Caractéristiques des outils d'automation
3. Comparaison des outils de gestion de configuration open source
Ansible
Chef
SaltStack
CFEngine
Puppet Labs
4. Fonctionnalités de Ansible
5. Configuration Management tool
6. Deployment tool
7. Orchestration of Deployment tool
8. Provisioning tool
Notes
Un logiciel comme Ansible qui peut nativement piloter n'importe quel élément d'une infrastructure informatique en un minimum
d'effort de mise en place et qui décrit celle-ci dans un langage simple de représentation comme YAML contribue a atteindre
l'objectif du paradigme "Infrastructure as Code".
2. https://en.wikipedia.org/wiki/Infrastructure_as_Code#Types_of_approaches ↩
Ansible
Ansible --> Playbooks : Ansible combine le déploiement multi-noeuds, l'exécution de tâches ad hoc et la gestion de la
configuration en un seul logiciel. Il gère les noeuds avec SSH et requiert l'installation de python (2.6+ ou 3.5+). Les modules
fonctionnent avec JSON et les sorties standard. Ils peuvent être écrits dans n'importe quel langage. Ansible utilise YAML pour
exprimer des descriptions réutilisables de systèmes.
Chef
Chef --> Cookbook : Chef est un outil de gestion de configuration écrit en Erlang qui utilise un DSL Ruby pur pour la rédaction de
"recettes" de configuration. Ces recettes contiennent des ressources qui doivent être placées dans l'état déclaré. Chef peut être
utilisé comme un outil client-serveur ou utilisé en mode "solo".
SaltStack
SaltStack --> Salt State : Salt a commencé comme un outil de gestion de serveur à distance. Au fur et à mesure de son
utilisation, il a acquis un certain nombre de fonctionnalités étendues, notamment un mécanisme plus complet de configuration de
l’hôte. Elle est une fonctionnalité relativement nouvelle facilitée par le composant Salt States.
CFEngine
CFEngine --> Policy : CFEngine est un système d'agents légers. Il gère la configuration d'un grand nombre d'ordinateurs à l'aide
du paradigme client-serveur ou autonome. Tout état client différent de la description de la politique est rétabli à l'état souhaité.
L'état de configuration est spécifié via un langage déclaratif. Le paradigme de CFEngine est la «immunologie informatique»
convergente.
Puppet Labs
Puppet Labs --> Manifest : Puppet offre un langage déclaratif personnalisé pour décrire la configuration du système, distribué à
l'aide du paradigme client-serveur (utilisant le protocole XML-RPC dans les versions antérieures, avec un commutateur récent
pour REST) et une bibliothèque pour réaliser la configuration. La couche d'abstraction des ressources permet aux
administrateurs de décrire la configuration en termes de haut niveau, tels que les utilisateurs, les services et les packages.
Puppet s'assurera alors que l'état du serveur correspond à la description.
4. Fonctionnalités de Ansible
Ansible peut être considéré comme un :
Provisioning
Configuration Management
App Deployment
Continuous Delivery
Security & Compliance
Orchestration
6. Deployment tool
Le déploiement de logiciels est l'ensemble des activités qui permettent de disposer d'un système logiciel. Le processus de
déploiement comprend plusieurs activités interdépendantes avec des transitions possibles entre elles. Ces activités peuvent
avoir lieu du côté du producteur ou du consommateur ou des deux. Étant donné que chaque système logiciel est unique, les
procédures ou les processus précis au sein de chaque activité peuvent difficilement être définis. Par conséquent, le
"déploiement" doit être interprété comme un processus général qui doit être personnalisé en fonction d'exigences ou de
caractéristiques spécifiques. 4
4
. Software deployment ↩
8. Provisioning tool
Le provisionnement - calque français du mot provisioning, mot anglais désignant l'approvisionnement, est un terme utilisé dans
le monde de l'informatique, désignant l'allocation automatique de ressources. Les outils de provisioning sont des outils de
gestion de configuration (ou de « gestion de paramétrage ») permettant d'installer et de configurer des logiciels à distance
(télédistribution), ou encore d'allouer de l'espace disque, de la puissance ou de la mémoire. Dans le monde des
télécommunications, le provisioning consiste à adapter un service aux besoins d'un client. Dans certains cas, l'utilisateur peut
même effectuer lui-même certaines opérations : il s'agit alors d’auto-provisionnement, en anglais « self-provisioning ». Au sens
large, le provisioning est l'affectation plus ou moins automatisée de ressources à un utilisateur (poste de travail, téléphonie). 6
6. Provisionnement ↩
Notes
kubernetes
Terraform
Docker-swarm
AWS CloudFormation
cloud-init, vagrant
1. Le terme Ansible
Une "ansible" est un dispositif théorique permettant de réaliser des communications à une vitesse supraluminique (supérieure à
la vitesse de la lumière), imaginé en 1966 par Ursula K. Le Guin dans son roman de science-fiction, Le Monde de Rocannon.
Elle en détaillera plus tard le concept dans Les Dépossédés (1974). L'idée est notamment reprise par d'autres auteurs de livres
de science-fiction et des jeux vidéos, la communication étant basée sur l'état d'énergie réciproque de deux particules jumelles.
Par ailleurs, Ansible est le titre d'un magazine anglo-saxon consacré à la science-fiction. Le terme "ansible" fait référence à un
système de communication hyperspace instantané fictif 1.
1. Page Ansible sur Wikipidia FR ↩
2. Projet Ansible
Ansible est une plate-forme logicielle pour la configuration et la gestion des ordinateurs. Le logiciel combine le déploiement de
logiciels multi-noeuds, l'exécution des tâches ad-hoc, et la gestion de configuration.
Il gère les différents noeuds avec un accès à distance natif (tels que les protocoles SSH ou Remote PowerShell ou encore des
APIs natives) et ne nécessite l'installation d'aucun logiciel supplémentaire à distance, avec parallélisation, collecte de
métadonnées et gestion des états. Cet aspect de conception "sans agent" installé sur le périphérique est important car il réduit
les besoins d'infrastructure pour démarrer une gestion. Les modules fonctionnent grâce à JSON et à la sortie standard et
peuvent être écrits dans n'importe quel langage de programmation.
Le système utilise notamment YAML pour exprimer des descriptions réutilisables de systèmes.
Le logiciel Ansible a été conçu par un ancien employé Red Hat, Michael DeHaan, également auteur de l'application de serveur
de "provisionning" Cobbler et co-auteur du framework Func pour l'administration à distance. Le code source du logiciel est sous
2
licence GNU General Public v3.0. Red Hat a racheté la société Ansible, Inc. en octobre 2015.
2
. Page Ansible (software) sur Wikipedia EN) ↩
3. Version d'Ansible
Ansible est développé et publié avec un cycle de révision de 4 mois. Ce cycle peut être étendu afin de permettre la mise en
oeuvre de modifications et de test correctifs. Ansible a une structure de support graduelle qui s'étend à trois versions principales.
https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html
4. Ansible Tower
Ansible Tower est un API, un service Web et une console Web conçue pour rendre Ansible utilisable pour les équipes
informatiques avec différents profils. C'est une console centrale de gestion des tâches d'automatisation. Tower est un produit
commercial pris en charge par Red Hat, Inc. Red Hat a annoncé à l'AnsibleFest 2016 que Tower passait en Open Source. En
2017, Tower est publié en opensoucé sous le nom de AWX. Semaphore est une alternative open source à Ansible Tower, écrit
en Go.3
3
. https://fr.wikipedia.org/wiki/Ansible_(logiciel)). ↩
5. Fonctionnement de Ansible
Contrairement aux logiciels de gestion de la configuration populaire (comme Chef, Puppet, et CFEngine), Ansible utilise une
architecture "agentless" (sans agent).
Avec une architecture basée sur un agent, les noeuds doivent avoir un démon installé localement qui communique avec une
4
machine de contrôle. Avec une architecture sans agent, il n'est pas nécessaire d'installer sur les noeuds un agent quelconque.
4
. https://en.wikipedia.org/wiki/Ansible_(software)). ↩
Minimum par nature. Les systèmes de gestion ne devraient pas imposer des dépendances supplémentaires sur
l'environnement.
Cohérent. cf. notion de test unitaire (procédure permettant de vérifier le bon fonctionnement d'une partie précise d'un
logiciel ou d'une portion d'un programme).
Sécurisé. Ansible ne déploie pas des agents sur les noeuds. Seulement OpenSSH est nécessaire.
Très fiable. Lorsqu'il est écrit soigneusement, un livre de jeux Ansible peut être idempotent afin d'éviter des effets
secondaires inattendus sur les systèmes gérés.
Courbe d'apprentissage faible. Les livres de jeux Ansible utilisent un langage simple et descriptif basé sur YAML et les
modèles Jinja2 .
5
. Page README du projet Ansible ↩
7. Automation d'infrastructures
Ansible s'interface avec du matériel, du logiciel ou des solutions d'un grand nombre de fournisseurs.
Péripériques physiques
Bare Metal avec Cobbler, Stacki, and Red Hat Satellite
Réseau avec Cisco, Juniper, Arista, A10, Cumulus Networks, Dell, F5 BigIP, HPE (OpenSwitch), Nokia, Palo Alto Networks
etc.
Stockage avec NetApp, Infinidat, etc.
Virtualisation
VMware
Red Hat Enterprise Virtualization (RHEV)
Libvirt
Xenserver
Vagrant
Systèmes d'exploitation
Linux (RHEL, CentOS, Fedora, Ubuntu, et autres)
Windows et Windows Server
UNIX
Containers
Ansible Container
Docker
Linux Containers (LXC)
Cloud
Amazon Web Services (AWS)
Microsoft Azure
Cloudstack
OpenStack
Digital Ocean
Google Cloud Platform
Linode
ProfitBricks
Rackspace
Outils DevOps
Development:
Github,
Atlassian Bitbucket Pipelines,
Gitlabs,
Vagrant
...
Integration/Test:
Jenkins,
Travis CI,
Teamcity
...
Deployment:
Cloud Providers,
Containers,
ServiceNow,
Systems,
Virt Platforms
...
Monitoring/Analytics:
Splunk,
AppDynamics,
Dynatrace,
LogicMonitor,
InfluxDB
...
8. Cas d'usage
Provisioning
Configuration Management
App Deployment
Continuous Delivery
Security & Compliance
Orchestration
3. Fonctionnement d'Ansible
1. Terminologie Ansible
2. Machine de contrôle
3. Modules
4. Noeuds gérés
5. Clés SSH
6. L'inventaire
7. Plugins
8. Le mode Ad Hoc
9. Playbooks
10. Idempotence
11. Facts
12. Les rôles
13. Ansible Tower
14. Binaires Ansible
1. Terminologie Ansible
En vue de contrôler des noeuds distants, des utilisateurs lancent des "playbooks" à partir d'un noeud de contrôle grâce à Ansible
Engine.
Modules
Plugins
API
Inventaire (inventory)
Ansible Engine connecte et se pratique de manière différente sur les hôtes terminaux (Linux/Unix et Windows) et les
périphériques du réseau. Il s'agit de périphériques dont les missions et la gestion sont bien différentes.
2. Machine de contrôle
Les machines de contrôle doivent être un hôte Linux / Unix (par exemple, Red Hat Enterprise Linux, Debian, CentOS, OS X,
BSD, Ubuntu), et Python 2.6 ou 2.7 est requis (le support Python 3 est disponible en tant que "tech preview" depuis ansible 2.2).
Avec une version Windows 10 Pro, il est possible d'utiliser de commander Ansible avec WSL, voir Can Ansible run on Windows?
Installation Ansible
3. Modules
Ansible fonctionne en se connectant aux noeuds à gérer et en leur envoyant des petits programmes, appelés «modules
Ansible». Ces programmes sont écrits pour être des modèles de ressources de l'état souhaité du système. Ansible exécute
ensuite ces modules (via SSH par défaut) grâce au protocole JSON sur la sortie standard et les supprime lorsque l'action est
terminée.
La bibliothèque de modules peut résider sur n'importe quelle machine et sans aucun serveur, démon ou base de données. En
général, l'administrateur travaille avec son programme de terminal favori, un éditeur de texte et probablement un système de
contrôle de version pour suivre les modifications apportées à son contenu.
Rien n'interdit d'écrire son propre module. Ces modules peuvent contrôler les ressources comme des services, des paquets ou
des fichiers (n'importe quoi en réalité), ou encore exécuter des commandes système. 1
1
. Working With Modules ↩
4. Noeuds gérés
Les noeuds gérés, s'ils sont en Linux/Unix, doivent disposer de Python 2.4 ou version ultérieure. Pour les noeuds gérés avec
Python 2.5 ou antérieur, le paquet python-simplejson est également requis.
Depuis sa version 1.7, Ansible peut également gérer les noeuds Windows. Dans ce cas, on utilise PowerShell à distance de
manière native au lieu de SSH.
Matériel d'infrastructure réseau (constructeurs), pare-feux, serveurs de stockage, fournisseurs IaaS, solutions de virtualisation
sont supportés via SSH, NETCONF/YANG ou encore via API HTTP REST.
Plugins de connexion
5. Clés SSH
Les mots de passe sont pris en charge, mais la gestion des clés SSH avec ssh-agent est l'un des meilleurs moyens d'utiliser
Ansible. Il est également possible parmi beaucoup de possibilités des authentifications Kerberos ou autres. Les connexions
"root" ne sont pas obligatoires, on peut se connecter en tant qu'utilisateur, et puis utiliser "su" ou "sudo". Le module
"authorized_key" d'Ansible est un excellent moyen d'utiliser Ansible pour contrôler quelles machines peuvent accéder à quels
hôtes.
ssh-agent bash
ssh-add ~/.ssh/id_rsa
protocole SSH
6. L'inventaire
Figure 4 : Inventory
Par défaut, Ansible représente les machines qu'il gère à l'aide d'un fichier INI très simple qui place toutes les machines gérées
dans des groupes de votre choix. On peut le représenter dans d'autres formats comme YAML.
Pour ajouter de nouvelles machines, aucun serveur de signature supplémentaire n'est nécessaire, alors que NTP ou DNS sont
critiques au moment des authentifications.
S'il existe une autre source de confiance dans votre infrastructure, Ansible peut également y ajouter des éléments tels que des
informations d'inventaire, de groupe et variables à partir de sources telles que EC2, Rackspace, OpenStack, etc.
Figure 5 : CMDB
[serveurs web]
www1.example.com
www2.example.com
[dbservers]
db0.example.com
db1.example.com
Une fois que les hôtes d'inventaire sont répertoriés, des variables peuvent leur être attribuées dans des fichiers texte simples
(dans un sous-répertoire appelé ' group_vars/ ' ou ' host_vars/ ') ou directement dans le fichier d'inventaire.
Aussi, on peut utiliser un inventaire dynamique pour extraire un inventaire de sources de données telles que EC2, Rackspace ou
OpenStack.
Fichiers INI
7. Plugins
Figure 6 : Plugins
Types de plugins
8. Le mode Ad Hoc
Le mode Ad-Hoc permet l'exécution de tâches parallèles.
Dès qu'une instance est disponible, on peut lui parler immédiatement, sans aucune configuration supplémentaire, ici sur une
instance Red Hat:
Un accès à des modules de ressources basés sur des états, ainsi qu'à des commandes "raw" est disponible. Ces modules sont
extrêmement faciles à écrire. Par ailleurs, Ansible est livré avec énormément de modules déjà développé (plus de 750) de telle
sorte qu'un bonne partie du travail est déjà réalisée.
Mode Ad-Hoc
9. Playbooks
Figure 7 : Playbooks
Les playbooks sont un langage d'automatisation simple et puissant. Les Playbooks peuvent orchestrer avec précision plusieurs
parties d'une topologie d'infrastructure, avec un contrôle très détaillé du nombre de machines à traiter à la fois.
L’approche d’Ansible en matière d’orchestration est une approche simple et précise : le code d’automatisation devrait être
pérenne et il devrait y avoir très peu de choses à retenir sur la syntaxe ou des fonctionnalités spéciales.
Les "playbooks" (livres de jeux) sont écrits en langage YAML, Ain't Markup Language. YAML expose un minimum de syntaxe et
propose un modèle de configuration ou de processus plutôt qu'un langage de script ou de programmation.
Un "play" est une analogie sportive, qui définit un état ou un modèle et qui se "rejoue" de différentes manières à d'autres
moments. On pourrait traduire "play" par "séance de jeu".
Le but d'un "play" est de faire corresponde un "group" contenant des "hosts" dans des "roles" bien définis représentés par des
objets Ansible appelés des "tasks". Sur le plan fondamental, une "task" n'est rien de plus qu'un appel à un module ansible
accompagné de paramètres. Un module est script Ansible en vue de réaliser certaines actions sur les "hosts".
Un module est généré sur le contrôleur, il est copié, exécuté et effacé sur les noeud dans le cadre de l'automation des serveurs.
Un module est généré et exécuté sur le contrôleur localement quand il s'agit de gérer des périphériques réseau.
En composant un "playbook" avec plusieurs "plays", il est possible d'orchestrer un déploiement multi-machines, en exécutant
certaines tâches dans un groupe de routeurs, certaines tâches dans un groupe de commutateurs, et encore d'autres
commandes dans un autre groupe de périphériques ...
Un "playbook" consiste à :
Alors qu'ils organisent les tâches ("tasks"), les "playbooks" peuvent être organisés en "roles". Un "role" ajoute un niveau
d'abstraction dans l'exécution des playbooks.
10. Idempotence
« Being idempotent allows the defined task to run one time or a thousand times without having an adverse effect on the
target system, only ever making the change once. In other words, if a change is required to get the system into its desired
state, the change is made; and if the device is already in its desired state, no change is made. This is unlike most
traditional custom scripts and the copy and pasting of CLI commands into a terminal window. When the same command
or script is executed repeatedly on the same system, errors are (sometimes) raised. »
Extrait de: Jason Edelman. « Network Automation with Ansible. », O’Reilly Media, 2016.
En français : "Être idempotent permet à une tâche définie d'être exécutée une seule fois ou des centaines de fois sans créer un
effet contraire sur le système cible, ne provoquant un changement à une seule reprise. En d'autres mots, si un changement est
nécessaire pour obtenir le système dans un état désiré, alors le changement est réalisé ; par contre si le périphérique est déjà
dans l'état désiré, aucun changement n'intervient. Ce comportement est différent des pratiques de scripts personnalisés et de
copier/coller de lignes de commandes. Quand on exécute les mêmes commandes ou scripts sur un même système de manière
répétée, le taux d'erreur est souvent élevé."
11. Facts
(...)
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html
Roles are ways of automatically loading certain vars_files, tasks, and handlers based on a known file structure. Grouping content
by roles also allows easy sharing of roles with other users.
ansible-inventory ...
ansible-vault Permet de chiffrer les fichiers qui contiennent des données sensibles
ansible-galaxy ...
ansible-console ...
ansible-connection ...
ansible-pull ...
4. Langages de représentation
Fichiers INI
Langage YAML
Début du fichier
Listes
Dictionnaires
Dictionnaires et listes
Forme abrégée
Valeur booléenne
Valeurs sur plusieurs lignes
Traitement JSON
Variables
Modèles Jinja2
Fichiers INI
Les fichiers INI sont des fichiers texte : ils peuvent être manipulés avec un éditeur de texte.1
Les fichiers sont divisés en sections. Chaque section comporte un certain nombre de paramètres de configuration. Chaque
section commence par un titre placé entre crochets " [ " et " ] "
La valeur de chaque paramètre de configuration est indiquée par une formule : paramètre = valeur .
Les fichiers peuvent contenir des commentaires. Les commentaires sont souvent utilisés pour décrire les paramètres et les
valeurs à introduire. Ils sont précédés d'un point-virgule ou plus rarement d'un croisillon.
[database]
server=192.0.2.42 ; use IP address in case network name resolution is not working
port=143
file = "acme payroll.dat"
1. Wikipedia FR ↩
Langage YAML
Pour Ansible, presque tous les fichiers YAML commencent par une liste. Chaque élément de la liste est une liste de paires clé /
valeur, communément appelée "hash" ou "dictionary". Il est donc nécessaire de savoir écrire des listes et des dictionnaires en
YAML.2
2. YAML Syntax ↩
Début du fichier
Tous les fichiers YAML (indépendamment de leur association avec Ansible ou non) peuvent éventuellement commencer par --
- et se terminer par ... . Cela fait partie du format YAML et indique le début et la fin d'un document.
Listes
Tous les membres d'une liste sont des lignes commençant au même niveau d'indentation commençant par un tiret et un espace
: -
---
# A list of tasty fruits
fruits:
- Apple
- Orange
- Strawberry
- Mango
...
Dictionnaires
Un dictionnaire est représenté sous une forme simple (les deux points doivent être suivis d'un espace): key: value
# An employee record
martin:
name: Martin D'vloper
job: Developer
skill: Elite
Dictionnaires et listes
Des structures de données plus complexes sont possibles, telles que des listes de dictionnaires, des dictionnaires dont les
valeurs sont des listes ou un mélange des deux:
# Employee records
- martin:
name: Martin D'vloper
job: Developer
skills:
- python
- perl
- pascal
- tabitha:
name: Tabitha Bitumen
job: Developer
skills:
- lisp
- fortran
- erlang
Forme abrégée
Les dictionnaires et les listes peuvent également être représentés sous une forme abrégée si vous voulez vraiment:
---
martin: {name: Martin D'vloper, job: Developer, skill: Elite}
fruits: ['Apple', 'Orange', 'Strawberry', 'Mango']
Valeur booléenne
On peut également spécifier une valeur booléenne (true / false) sous plusieurs formes :
create_key: yes
needs_agent: no
knows_oop: True
likes_emacs: TRUE
uses_cvs: false
Les valeurs peuvent couvrir plusieurs lignes en utilisant | ou > . Le fait de couvrir plusieurs lignes en utilisant un "Literal Block
Scalar" | inclura les nouvelles lignes et tous les espaces de fin. L'utilisation d'un "Folded Block Scala" > pliera les lignes
nouvelles dans les espaces; il est utilisé pour rendre ce qui serait autrement une très longue ligne plus facile à lire et à éditer.
Dans les deux cas, l'indentation sera ignorée. Les exemples sont:
include_newlines: |
exactly as you see
will appear these three
lines of poetry
fold_newlines: >
this is really a
single line of text
despite appearances
Alors que dans l'exemple ci-dessus, toutes les nouvelles lignes sont repliées dans des espaces, il existe deux manières de faire
respecter une nouvelle ligne à conserver:
fold_some_newlines: >
a
b
c
d
e
f
same_as: "a b\nc d\n e\nf\n"
Combinons ce que nous avons appris jusqu'ici dans un exemple YAML arbitraire. Cela n'a vraiment rien à voir avec Ansible,
mais vous donnera une idée du format:
---
# An employee record
name: Martin D'vloper
job: Developer
skill: Elite
employed: True
foods:
- Apple
- Orange
- Strawberry
- Mango
languages:
perl: Elite
python: Elite
pascal: Lame
education: |
4 GCSEs
3 A-Levels
BSc in the Internet of Things
Traitement JSON
...
Variables
...
Modèles Jinja2
...
Selon Gartner...
Si vous êtes responsable d'un réseau d'entreprise, vous savez probablement que de nombreuses opérations manuelles sont
effectuées via l'interface de ligne de commande (CLI). Il n’est pas surprenant que le principal défi que nos clients rencontrent en
1
matière de réseau consiste à améliorer leur agilité, et cela est resté vrai au cours des deux dernières années.
1. Look Beyond Network Vendors for Network Innovation ↩
Arista (EOS),
Cisco (IOS, IOS XR, NX-OS),
Juniper (JunOS),
Open vSwitch
VyOS.
Ansible Tower is an enterprise framework for controlling, securing and managing your Ansible automation with a UI and RESTful
API.
Référence
https://docs.ansible.com/ansible/2.5/network/user_guide/network_best_practices_2.5.html
Fonctionnement
Terminologie Ansible
Playbooks
Les "playbooks" sont un langage d'automatisation simple et puissant. Les "Playbooks" peuvent orchestrer avec précision
plusieurs tranches d'une topologie d'infrastructure, avec un contrôle très détaillé du nombre de machines à traiter à la fois.
L’approche d’Ansible en matière d’orchestration est une approche simple et précise : le code d’automatisation devrait être
pérenne et il devrait y avoir très peu de choses à retenir sur la syntaxe ou des fonctionnalités spéciales.
Inventory
Par défaut, Ansible représente les machines qu'il gère à l'aide d'un fichier INI très simple qui place toutes les machines gérées
dans des groupes de votre choix. On peut le représenter dans d'autres formats comme YAML.
Pour ajouter de nouvelles machines, aucun serveur de signature supplémentaire n'est nécessaire, alors que NTP ou DNS sont
critiques au moment des authentifications.
S'il existe une autre source de confiance dans votre infrastructure, Ansible peut également y ajouter des éléments tels que des
informations d'inventaire, de groupe et variables à partir de sources telles que EC2, Rackspace, OpenStack, etc.
Modules et Tasks
Ansible fonctionne en se connectant aux noeuds à gérer et en leur envoyant des petits programmes, appelés «modules
Ansible». Ces programmes sont écrits pour être des modèles de ressources de l'état souhaité du système. Ansible exécute
ensuite ces modules (via SSH par défaut) grâce au protocole JSON sur la sortie standard et les supprime lorsque l'action est
terminée.
Plugins
Figure 10 : Plugins
Comprendre l'inventory
10.1.1.2
10.1.1.3
172.16.1.1
172.16.1.2
192.168.1.2
192.168.1.3
[atl]
access1.atl.com ansible_host=10.1.1.2
access2.atl.com ansible_host=192.168.1.2
[core]
core1.nw.com
core2.nw.com
[access]
access1.nw.com
access2.nw.com
[DC:children]
core
access
[east-coast:children]
DC
atl
[atl]
access1.atl.com ansible_host=10.1.1.2
access2.atl.com ansible_host=192.168.1.2
[core]
core1.nw.com
core2.nw.com
[access]
access1.nw.com
access2.nw.com
Inventory - variables
[all:vars]
ansible_username=admin
ansible_password=pa55w0rd
snmp_ro=public123
snmp_rw=private123
[east-coast:vars]
ntp_server=10.99.99.99
anycast=169.1.1.1
[DC:children]
core
access
[east-coast:children]
DC
atl
[atl]
access1.atl.com ansible_host=10.1.1.2 snmp_ro=atl123
access2.atl.com ansible_host=192.168.1.2
[core]
core1.nw.com snmp_ro=corepub123 snmp_rw=corepri123
core2.nw.com
[access]
access1.nw.com ansible_username=localadmin
access2.nw.com
Les
Les "Group variables" s'appliquent pour tous les périphériques d'un groupe
Les "Host variables" s'appliquent uniquement sur le périphériques et outrepasse les "Group variables"
Mode Playbooks
Terminologie : playbooks, plays, roles, tasks, hosts, module
Les "playbooks" (livres de jeux) sont écrits en langage YAML, Ain't Markup Language. YAML expose un minimum de syntaxe et
propose un modèle de configuration ou de processus plutôt qu'un langage de script ou de programmation.
Un "play" est une analogie sportive, qui définit un état ou un modèle et qui se "rejoue" de différentes manières à d'autres
moments. On pourrait traduire "play" par "séance de jeu".
Le but d'un "play" est de faire corresponde un group de "hosts" dans des "roles" bien définis représentés par des objets Ansible
appelés des "tasks". Sur le plan fondamental, un "task" n'est rien de plus qu'un appel à un module ansible. Un module est script
Ansible en vue de réaliser certaines actions sur les hosts.
Un module est généré sur le contrôleur, il est copié, exécuté et effacé sur les noeud dans le cadre de l'automation des serveurs.
Un module est généré et exécuté sur le contrôleur localement.
En composant un "playbook" avec plusieurs "plays", il est possible d'orchestrer un déploiement multi-machines, en exécutant
certaines tâches dans un groupe de routeurs, certaines tâches dans un groupe de commutateurs, et encore d'autres
commandes dans un autre groupe de périphériques ...
Un "playbook" consiste à :
Alors qu'ils organisent les tâches ("tasks"), les "playbooks" peuvent être organisés en "roles". Un "role" ajoute un niveau
d'abstraction dans l'exécution des playbooks.
Idempotence:
« Being idempotent allows the defined task to run one time or a thousand times without having an adverse effect on the
target system, only ever making the change once. In other words, if a change is required to get the system into its desired
state, the change is made; and if the device is already in its desired state, no change is made. This is unlike most
traditional custom scripts and the copy and pasting of CLI commands into a terminal window. When the same command
or script is executed repeatedly on the same system, errors are (sometimes) raised. »
Extrait de: Jason Edelman. « Network Automation with Ansible. », O’Reilly Media, 2016.
En français : "Être idempotent permet à une tâche définie d'être exécutée une seule fois ou des centaines de fois sans créer un
effet contraire sur le système cible, ne provoquant un changement à une seule reprise. En d'autres mots, si un changement est
nécessaire pour obtenir le système dans un état désiré, alors le changement est réalisé ; par contre si le périphérique est déjà
dans l'état désiré, aucun changement n'intervient. Ce comportement est différent des pratiques de scripts personnalisés et de
copier/coller de lignes de commandes. Quand on exécute les mêmes commandes ou scripts sur un même système de manière
répétée, le taux d'erreur est souvent élevé."
A sample playbook
---
- name: DEPLOY VLANS
hosts: access
connection: network_cli
gather_facts: no
tasks:
Debian/Ubuntu
Les fichiers RPMs pour RHEL 7 sont disponibles dans le repository Ansible Engine. Pour l'activer :
Ansible version 2.4 et ultérieure peut gérer des systèmes d'exploitation plus récents qui disposent de Python 2.6 et plus.
Note : Dans les anciennes versions Ubuntu, “software-properties-common” est appelé “python-software-properties”.
Les paquets Debian/Ubuntu packages peut être construits par les sources :
make deb
Note : Cette méthode a été vérifiée avec des sources Trusty sources en Debian Jessie et Stretch mais pourrait ne pas être
supportée dans les versions plus récentes.
Il n'est pas possible de faire fonctionner Ansible sur un hôte Windows alors qu'il peut le gérer. Mais Ansible peut être exécuté
sous Windows Subsystem for Linux (WSL). Notons que WSL n'est pas supporté par Microsoft ou Ansible; il ne devrait pas être
utilisé sur des systèmes en production.
Pour installer Ansible sur WSL, il est nécessaire d'exécuter ces commandes un terminal bash :
Pour exécuter Ansible à partir des sources plutôt qu'une version pour WSL, il faut désinstaller la version présente de pip et puis
cloner le repo git.
apt-update
apt -y install python-setuptools git
easy_install pip
cd /usr/src/
git clone https://github.com/ansible/ansible.git --recursive
cd ./ansible
source ./hacking/env-setup
pip install -r ./requirements.txt
Centos 7
Configuration de Ansible
Le comportement d'Ansible peut être influencé de différentes manières :
Commande ansible-config
La commande ansible-config list donne la liste des variables de configuration chargée dans le système de contrôle. Voyez-
vous même :
ansible-config list
Le dépot GitHub d'Ansible offre un exemple de fichier de configuration commenté. Il est directement disponible sur cet URL :
https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg
[defaults]
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
Section [defaults]
La section [defaults] est la plus intéressante :
Valeurs habituelles
[defaults]
#inventory = /etc/ansible/hosts
#library = /usr/share/my_modules/
#module_utils = /usr/share/my_module_utils/
#remote_tmp = ~/.ansible/tmp
#local_tmp = ~/.ansible/tmp
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
#forks = 5
#poll_interval = 15
#sudo_user = root
#ask_sudo_pass = True
#ask_pass = True
#transport = smart
#remote_port = 22
#module_lang = C
#module_set_locale = False
forks
remote_port
Callback plugins
# change the default callback, you can only have one 'stdout' type enabled at a time.
#stdout_callback = skippy
## Ansible ships with some plugins that require whitelisting,
## this is done to avoid running all of a type by default.
## These setting lists those that you want enabled for your system.
## Custom plugins should not need this unless plugin author specifies it.
# enable callback plugins, they can output to stdout but cannot be 'stdout' type.
#callback_whitelist = timer, mail
Handlers manquants
Timeout SSH
# SSH timeout
#timeout = 10
Logging
Extensions Jinja2
Affichage
# by default (as of 1.3), Ansible will raise errors when attempting to dereference
# Jinja2 variables that are not set in templates or action lines. Uncomment this line
# to revert the behavior to pre-1.3.
#error_on_undefined_vars = False
# by default (as of 1.6), Ansible may display warnings based on the configuration of the
# system running ansible itself. This may include warnings about 3rd party packages or
# other conditions that should be resolved if possible.
# to disable these warnings, set the following value to False:
#system_warnings = True
# by default (as of 1.4), Ansible may display deprecation warnings for language
# features that should no longer be used and will be removed in future versions.
# to disable these warnings, set the following value to False:
#deprecation_warnings = True
# (as of 1.8), Ansible can optionally warn when usage of the shell and
# command module appear to be simplified by using a default Ansible module
# instead. These warnings can be silenced by adjusting the following
# setting or adding warn=yes or warn=no to the end of the command line
# parameter string. This will for example suggest using the git module
# instead of shelling out to the git command.
# command_warnings = False
#terminal_plugins = /usr/share/ansible/plugins/terminal
#strategy_plugins = /usr/share/ansible/plugins/strategy
Stratégie
# by default, ansible will use the 'linear' strategy but you may want to try
# another one
#strategy = free
Callbacks
# by default callbacks are not loaded for /bin/ansible, enable this if you
# want, for example, a notification or logging callback to also apply to
# /bin/ansible runs
#bin_ansible_callbacks = False
Cows
# set which cowsay stencil you'd like to use by default. When set to 'random',
# a random stencil will be selected for each task. The selection will be filtered
# against the `cow_whitelist` option below.
#cow_selection = default
#cow_selection = random
# when using the 'random' option for cowsay, stencils will be restricted to this list.
# it should be formatted as a comma-separated list with no spaces between names.
# NOTE: line continuations here are for formatting purposes only, as the INI parser
# in python does not support them.
#cow_whitelist=bud-frogs,bunny,cheese,daemon,default,dragon,elephant-in-snake,elephant,eyes,\
# hellokitty,kitty,luke-koala,meow,milk,moofasa,moose,ren,sheep,small,stegosaurus,\
# stimpy,supermilker,three-eyes,turkey,turtle,tux,udder,vader-koala,vader,www
Couleurs
# if set to a persistent type (not 'memory', for example 'redis') fact values
# from previous runs in Ansible will be stored. This may be useful when
# wanting to use, for example, IP information from one group of servers
# without having to talk to them in the same playbook run to get their
# current IP information.
#fact_caching = memory
#This option tells Ansible where to cache facts. The value is plugin dependent.
#For the jsonfile plugin, it should be a path to a local directory.
#For the redis plugin, the value is a host:port:database triplet: fact_caching_connection = localhost:6379:0
#fact_caching_connection=/tmp
Fichier Retry
# retry files
# When a playbook fails by default a .retry file will be created in ~/
# You can disable this feature by setting retry_files_enabled to False
# and you can change the location of the files by setting retry_files_save_path
#retry_files_enabled = False
#retry_files_save_path = ~/.ansible-retry
Squash action
# squash actions
# Ansible can optimise actions that call modules with list parameters
# when looping. Instead of calling the module once per with_ item, the
# module is called once with all items at once. Currently this only works
# under limited circumstances, and only with parameters named 'name'.
#squash_actions = apk,apt,dnf,homebrew,pacman,pkgng,yum,zypper
# prevents logging of tasks, but only on the targets, data is still logged on the master/controller
#no_target_syslog = False
Divers
# controls what compression method is used for new-style ansible modules when
# they are sent to the remote system. The compression types depend on having
# support compiled into both the controller's python and the client's python.
# The names should match with the python Zipfile compression types:
# * ZIP_STORED (no compression. available everywhere)
# * ZIP_DEFLATED (uses zlib, the default)
# These values may be set per host via the ansible_module_compression inventory
# variable
#module_compression = 'ZIP_DEFLATED'
# This controls the cutoff point (in bytes) on --diff for files
# set to 0 for unlimited (RAM may suffer!).
#max_diff_size = 1048576
# This controls how ansible handles multiple --tags and --skip-tags arguments
# on the CLI. If this is True then multiple arguments are merged together. If
# it is False, then the last specified argument is used and the others are ignored.
# This option will be removed in 2.8.
#merge_multiple_cli_flags = True
# This family of modules use an alternative execution path optimized for network appliances
# only update this setting if you know how this works, otherwise it can break module execution
#network_group_modules=eos, nxos, ios, iosxr, junos, vyos
# When enabled, this option allows lookups (via variables like {{lookup('foo')}} or when used as
# a loop with `with_foo`) to return data that is not marked "unsafe". This means the data may contain
# jinja2 templating language which will be run through the templating engine.
# ENABLING THIS COULD BE A SECURITY RISK
#allow_unsafe_lookups = False
[defaults]
inventory = ./hosts
host_key_checking = False
private_key_file = /root/.ssh/id_rsa
callback_whitelist = profile_tasks
forks = 20
#strategy = free
gathering = explicit
become = True
[callback_profile_tasks ]
task_output_limit = 100
Inventaire
Fichier d'inventaire
Fichier d'inventaire
Un livre de jeu précise toujours ses cibles en remplissant le paramètre hosts . Un inventaire identifie les différentes cibles des
livres de jeu.
Il prend aussi bien le format INI que YAML (on le trouvera couramment en format INI). Les sections entre crochets identifient des
groupes d'hôtes.
mail.example.com
[webservers]
foo.example.com
bar.example.com
[dbservers]
one.example.com
two.example.com
three.example.com
all:
hosts:
mail.example.com:
children:
webservers:
hosts:
foo.example.com:
bar.example.com:
dbservers:
hosts:
one.example.com:
two.example.com:
three.example.com:
Sommaire
Lab 1.1. Explorer l'environnement de lab
Lab 1.2. Mode Ad Hoc
Ecrire un premier playbook
Lab 1.3. Ecrire un premier playbook
Modules, sorties, tags
Lab 1.4. Modules, sorties, tags
Depuis sa version 1.7, Ansible peut également gérer les nœuds Windows. Dans ce cas, on utilise PowerShell à distance de
manière native, au lieu de SSH.
Matériel d'infrastructure réseau (constructeurs), pare-feux, serveurs de stockage, fournisseurs IaaS, solutions de virtualisation ...
hostname rtr1
int g0/7
ip add dhcp
no shut
ip domain-name lan
username root privilege 15 password testtest
ip ssh version 2
ip scp server enable
crypto key generate rsa modulus 2048
line vty 0 4
login local
transport input all
end
wr
3. Fichiers source
(...)
mkdir networking-workshop
cd networking-workshop/
ansible --version
ansible 2.6.2
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Jul 13 2018, 13:06:57) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
Cette commande vous indique la version d'Ansible, la version de Python ainsi que les emplacement :
Étape 4 : Inventaire
La portée d'un jeu ("play") au sein du "playbook" est limité aux groupes d'hôtes définis dans l'inventaire ("inventory").
La page de documentation sur l'inventaire est certainement à consulter : Introduction à l'inventaire Ansible.
Une inventaire peut être une collection d'hôtes défini dans un fichier plat ou un script dynamique (qui interroge un CMDB par
exemple) qui génère une liste de périphériques à utiliser dans "playbook".
Voici des fournisseurs supportés par un inventaire dynamique : BSD Jails, DigitalOcean, Google Compute Engine, Linode,
OpenShift, OpenStack Nova, Ovirt, SpaceWalk, Vagrant (à ne pas confondre avec le "provisioner" dans Vagrant, qui est
préféré), Zabbix, ...
Dans ce lab, vous allez travailler avec un fichier d'inventaire plat écrit en format INI. Les consignes indiquent que le fichier doit se
situer dans le dossier ~/networking-workshop/lab_inventory/ dans fichier nommé hosts . Il est nécessaire de créer le dossier
lab_inventory/ au préalable.
mkdir lab_inventory
[routers:children]
cisco
[cisco]
rtr1
rtr2
rtr3
rtr4
[cisco:vars]
ansible_network_os=ios
[dc1]
rtr1
rtr3
[dc2]
rtr2
rtr4
EOF
Les groupes parents sont déclarés en utilisant la directive children . Utiliser des groupes emboités permet plus de flexibilité
dans l'assignation de valeurs plus spécifiques aux variables.
Notes aussi qu'un groupe all existe toujours et reprend tous les groupes et tous les hôtes définis dans l'inventaire.
Les variables hôtes sont définies sur la même ligne que l'hôte lui-même. Un exemple pour l'hôte rtr1 :
rtr1 - Le nom que Ansible utilisera. Il peut être résolu par DNS mais ce n'est pas une obligation.
ansible_host - L'adresse IP que Ansible utilisera. Si cette variable n'est pas définie, DNS est utilisé
ansible_ssh_user - Le compte utilisateur des connexions SSH. Si non défini, c'est l'utilisateur courant d'Ansible qui est
utilisé
private_ip - Cette valeur n'est pas réservée par Ansible. Elle peut donc être utilisée comme variable hôte. Cette variable
peut être utilisé dans les "playbooks" ou être totalement ignorée.
ansible_network_os - Cette variable est nécessaire pour utiliser le type de connexion network_cli (plugin) dans les
jeux qui sont utilisés dans ce document. (voir ansible-doc -t connection -l et ansible-doc -t connection network_cli )
Mode Ad Hoc
Le mode Ad-Hoc permet l'exécution de tâches parallèles.
Dès qu'une instance est disponible, on peut lui parler immédiatement, sans aucune configuration supplémentaire, ici sur une
instance Red Hat:
Un accès à des modules de ressources basés sur des états, ainsi qu'à des commandes raw est disponible. Ces modules sont
extrêmement faciles à écrire. Par ailleurs, Ansible est livré avec énormément de modules déjà développé (plus de 750) de telle
sorte qu'un bonne partie du travail est déjà réalisée.
Now that you have a fundamental grasp of the inventory file and the group/host variables, this section will walk you through
building a playbook.
This section will help you understand the components of a playbook while giving you an immediate baseline for using it
within your own production environment!
About gather_facts
Running a playbook
---
- 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
[root@ansible networking-workshop]#
Displaying output
Use the optional verbose flag during playbook execution
ansible-playbook gather_ios_data.yml -v
Variable Explanation
tasks:
- name: GATHER ROUTER FACTS
ios_facts:
- name: DEBUG MODULE DEMO
debug:
msg: "{{ inventory_hostname }} serial {{ ansible_net_serialnum }}"
ansible-playbook debug-demo.yml
Step 1
Using your favorite text editor ( vim and nano are available on the control host) create a new file called gather_ios_data.yml .
Alternately, you can create it using sublimetext or any GUI editor on your laptop and scp it over)
Ansible playbooks are YAML files. YAML is a structured encoding format that is also extremely human readable (unlike
it's subset - the JSON format)
Step 2
vim gather_ios_data.yml
---
- 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.
Step 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.
Step 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
ansible-playbook gather_ios_data.yml
Step 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.
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.
Step 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
Step 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:
Step 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
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.
Modules
Modules do the actual work in ansible, they are what gets executed in each playbook task.
Network modules
Ansible modules for network automation typically references the vendor OS followed by the module name.
*_facts
*_command
*_config
Arista EOS = eos_* Cisco IOS/IOS-XE = ios_* Cisco NX-OS = nxos_* Cisco IOS-XR = iosxr_* Juniper Junos = junos_*
VyOS = vyos_*
Modules Documentation
http://docs.ansible.com/
Modules Documentation
# 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
...
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):
...
Tags are invoked using the --tags flag while running the playbook
This is useful while working with large playbooks, when you might want to "jump" to a specific task.
In the previous section you learned to use the ios_facts and the debug modules. The debug module had an input parameter
called msg whereas the ios_facts module had no input parameters. As someone just starting out how would you know what
these parameters were for a module?
1. Point your browser to https://docs.ansible.com > Network Modules and read the documentation
1. From the command line, issue the ansible-doc <module-name> to read the documentation on the control host.
Step 1
On the control host read the documentation about the ios_facts module and the debug module.
ansible-doc debug
What happens when you use debug without specifying any parameter?
ansible-doc ios_facts
Step 2
In the previous section, you learned how to use the ios_facts module to collect device details. What if you wanted to collect the
output of a show command that was not provided as a part of ios_facts ?
The ios_command module allows you to do that. Go ahead and add another task to the playbook to collect the output of 2 show
commands to collect the hostname and the output of the show ip interface brief commands:
---
- name: GATHER INFORMATION FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: GATHER ROUTER FACTS
ios_facts:
Note: commands is a parameter required by the ios_command. The input to this parameter is a "list" of IOS commands.
Step 3
Before running the playbook, add a tag to the last task. Name it "show"
Tags can be added to tasks, plays or roles within a playbook. You can assign one or more tags to any given
task/play/role. Tags allow you to selectively run parts of the playbook.
---
- name: GATHER INFORMATION FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: GATHER ROUTER FACTS
ios_facts:
Step 4
Selectively run the last task within the playbook using the --tags option:
[root@ansible networking-workshop]#
1. Only a single task was executed during the playbook run (You no longer can see the serial number and IOS version being
displayed)
Step 5
Re-run the playbook using the -v verbose flag to see the output coming back from the routers.
Step 6
With the ios_facts module, the output was automatically assigned to the ansible_* variables. For any of the ad-hoc
commands we run against remote devices, the output has to be "registered" to a variable in order to use it within the playbook.
Go ahead and add the register directive to collect the output of the show commands into a variable called show_output :
---
- name: GATHER INFORMATION FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: GATHER ROUTER FACTS
ios_facts:
Step 7
Add a task to use the debug module to display the content's of the show_output variable. Tag this task as "show" as well.
---
- name: GATHER INFORMATION FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: GATHER ROUTER FACTS
ios_facts:
commands:
- show run | i hostname
- show ip interface brief
tags: show
register: show_output
Step 8
Re-run the playbook to execute only the tasks that have been tagged. This time run the playbook without the -v flag.
Step 9
The show_output variable can now be parsed just like a Python dictionary. It contains a "key" called stdout . stdout is a list
object, and will contain exactly as many elements as were in the input to the commands parameter of the ios_command task. This
means show_output.stdout[0] will contain the output of the show running | i hostname command and show_output.stdout[1] will
contain the output of show ip interface brief .
Write a new task to display only the hostname using a debug command:
---
- name: GATHER INFORMATION FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: GATHER ROUTER FACTS
ios_facts:
Step 10
Re-run the playbook.
[root@ansible networking-workshop]#
Sommaire
Lab 2.1. Mise à jour de configuration
Sauvegarder et restaurer
Lab 2.2. Sauvegarder une configuration
Lab 2.3. Restaurer une configuration
tasks:
- name: ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT
ios_config:
commands:
- snmp-server community ansible-public RO
- snmp-server community ansible-private RW
- snmp-server community ansible-test RO
tasks:
- name: ENSURE THAT ROUTERS ARE SECURE
ios_config:
src: secure_router.cfg
TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] **********************************************************************
***************************************************************
changed: [rtr3] => {"banners": {}, "changed": true, "commands": ["snmp-server community ansible-test RO"],
"updates": ["snmp-server community ansible-test RO"]}
Using Ansible you can update the configuration of routers either by pushing a configuration file to the device or you can push
configuration lines directly to the device.
Step 1
Create a new file called router_configs.yml (use either vim or nano on the jumphost to do this or use a local editor on your
laptop and copy the contents to the jumphost later). Add the following play definition to it:
---
- name: SNMP RO/RW STRING CONFIGURATION
hosts: cisco
gather_facts: no
connection: network_cli
Step 2
Add a task to ensure that the SNMP strings ansible-public and ansible-private are present on all the routers. Use the
ios_config module for this task
Note: For help on the ios_config module, use the ansible-doc ios_config command from the command line or check
https://docs.ansible.com. This will list all possible options with usage examples.
---
- name: SNMP RO/RW STRING CONFIGURATION
hosts: cisco
gather_facts: no
connection: network_cli
tasks:
Step 3
Run the playbook:
ansible-playbook router_configs.yml
TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] *************************************************
changed: [rtr4]
changed: [rtr1]
changed: [rtr3]
changed: [rtr2]
Step 4
The ios_config module is idempotent. This means, a configuration change is pushed to the device if and only if that
configuration does not exist on the end hosts. To validate this, go ahead and re-run the playbook:
ansible-playbook router_configs.yml
TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] **********************************************************************
***************************************************************
ok: [rtr1]
ok: [rtr2]
ok: [rtr4]
ok: [rtr3]
Note: See that the changed parameter in the PLAY RECAP indicates 0 changes.
Step 5
Now update the task to add one more SNMP RO community string:
---
- name: UPDATE THE SNMP RO/RW STRINGS
hosts: cisco
gather_facts: no
connection: network_cli
tasks:
Step 6
This time however, instead of running the playbook to push the change to the device, execute it using the --check flag in
combination with the -v or verbose mode flag:
TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] **********************************************************************
***************************************************************
changed: [rtr3] => {"banners": {}, "changed": true, "commands": ["snmp-server community ansible-test RO"], "updates": ["snmp-s
erver community ansible-test RO"]}
changed: [rtr1] => {"banners": {}, "changed": true, "commands": ["snmp-server community ansible-test RO"], "updates": ["snmp-s
erver community ansible-test RO"]}
changed: [rtr2] => {"banners": {}, "changed": true, "commands": ["snmp-server community ansible-test RO"], "updates": ["snmp-s
erver community ansible-test RO"]}
changed: [rtr4] => {"banners": {}, "changed": true, "commands": ["snmp-server community ansible-test RO"], "updates": ["snmp-s
erver community ansible-test RO"]}
The --check mode in combination with the -v flag will display the exact changes that will be deployed to the end device
without actually pushing the change. This is a great technique to validate the changes you are about to push to a device before
pushing it.
Go ahead and log into a couple of devices to validate that the change has not been pushed.
Also note that even though 3 commands are being sent to the device as part of the task, only the one command that is missing
on the devices will be pushed.
Step 7
Finally re-run this playbook again without the -v or --check flag to push the changes.
ansible-playbook router_configs.yml
TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] **********************************************************************
***************************************************************
changed: [rtr1]
changed: [rtr2]
changed: [rtr4]
changed: [rtr3]
Step 8
Rather than push individual lines of configuration, an entire configuration snippet can be pushed to the devices. Create a file
called secure_router.cfg in the same directory as your playbook and add the following lines of configuration into it:
line con 0
exec-timeout 5 0
line vty 0 4
exec-timeout 5 0
transport input ssh
ip ssh time-out 60
ip ssh authentication-retries 5
service password-encryption
service tcp-keepalives-in
service tcp-keepalives-out
Step 9
Remember that a playbook contains a list of plays. Add a new play called HARDEN IOS ROUTERS to the router_configs.yml
playbook.
---
- name: UPDATE THE SNMP RO/RW STRINGS
hosts: cisco
gather_facts: no
connection: network_cli
tasks:
Step 10
Add a task to this new play to push the configurations in the secure_router.cfg file you created in STEP 8
---
- name: UPDATE THE SNMP RO/RW STRINGS
hosts: cisco
gather_facts: no
connection: network_cli
tasks:
tasks:
Step 11
Go ahead and run the playbook.
ansible-playbook router_configs.yml
TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] **********************************************************************
***************************************************************
ok: [rtr3]
ok: [rtr2]
ok: [rtr1]
ok: [rtr4]
tasks:
- name: BACKUP THE CONFIG
ios_config:
backup: yes
register: config_output
The backup parameter of the ios_config module triggers the backup and automatically stores device configuration backups
within a backups directory
Building configuration...
The lineinfile module is a general purpose module that is used for manipulating file contents.
In our example we use the Cisco IOS command config replace. This allows for applying only the differences between running
and the copied configuration
---
- name: RESTORE CONFIGURATION
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: COPY RUNNING CONFIG TO ROUTER
command: scp ./backup/{{inventory_hostname}}.config {{inventory_hostname}}:/{{inventory_hostname}}.config
In this realistic scenario, you will create a playbook to back-up Cisco router configurations. In subsequent labs we will use this
backed up configuration, to restore devices to their known good state.
Note: Since this is a common day 2 operation for most network teams, you can pretty much re-use most of this content for
your environment with minimum changes.
Step 1
Create a new file called backup.yml using your favorite text editor and add the following play definition:
---
- name: BACKUP ROUTER CONFIGURATIONS
hosts: cisco
connection: network_cli
gather_facts: no
Step 2
Use the ios_config Ansible module to write a new task. This task should back up the configuration of all devices defined in
cisco group.
The backup parameter automatically creates a directory called backup within the playbook root and saves a time-stamped
backup of the running configuration.
Note: Use ansible-doc ios_config or check out docs.ansible.com for help on the module usage.
---
- name: BACKUP ROUTER CONFIGURATIONS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: BACKUP THE CONFIG
ios_config:
backup: yes
register: config_output
Why are we capturing the output of this task into a variable called config_output ? Step 5 will reveal this.
Step 3
Go ahead and run the playbook:
ansible-playbook backup.yml
Step 4
The playbook should now have created a directory called backup . Now, list the contents of this directory:
ls -l backup
total 1544
-rw-rw-r--. 1 student1 student1 393514 Jun 19 12:45 rtr1_config.2018-06-19@12:45:36
-rw-rw-r--. 1 student1 student1 393513 Jun 19 12:45 rtr2_config.2018-06-19@12:45:38
-rw-rw-r--. 1 student1 student1 390584 Jun 19 12:45 rtr3_config.2018-06-19@12:45:37
-rw-rw-r--. 1 student1 student1 390586 Jun 19 12:45 rtr4_config.2018-06-19@12:45:37
Feel free to open up these files using a text editor ( vim & nano work as well) to validate their content.
Step 5
Since we will be using the backed up configurations as a source to restore the configuration. Let's rename them to reflect the
device name.
In Step 2 you captured the output of the task into a variable called config_output . This variable contains the name of the backup
file. Use the copy Ansible module to make a copy of this file.
---
- name: BACKUP ROUTER CONFIGURATIONS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: BACKUP THE CONFIG
ios_config:
backup: yes
register: config_output
Step 6
Re-run the playbook.
ansible-playbook backup.yml
Step 7
Once again list the contents of the backup directory:
ls -l backup
total 3088
-rw-rw-r--. 1 student1 student1 393514 Jun 19 13:35 rtr1.config
-rw-rw-r--. 1 student1 student1 393514 Jun 19 13:35 rtr1_config.2018-06-19@13:35:14
-rw-rw-r--. 1 student1 student1 393513 Jun 19 13:35 rtr2.config
-rw-rw-r--. 1 student1 student1 393513 Jun 19 13:35 rtr2_config.2018-06-19@13:35:13
-rw-rw-r--. 1 student1 student1 390584 Jun 19 13:35 rtr3.config
-rw-rw-r--. 1 student1 student1 390584 Jun 19 13:35 rtr3_config.2018-06-19@13:35:12
-rw-rw-r--. 1 student1 student1 390586 Jun 19 13:35 rtr4.config
-rw-rw-r--. 1 student1 student1 390586 Jun 19 13:35 rtr4_config.2018-06-19@13:35:13
Notice that the directory now has another backed-up configuration but one that reflects the device's name.
Step 8
If we were to try and manually restore the contents of this file to the respective device there are two lines in the configuration that
will raise errors:
Building configuration...
Write a new task using Ansible's lineinfile module to remove the first line.
---
- name: BACKUP ROUTER CONFIGURATIONS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: BACKUP THE CONFIG
ios_config:
backup: yes
register: config_output
Note: The module parameter line is matching an exact line in the configuration file "Building configuration..."
Step 9
Before we run the playbook, we need to add one more task to remove the second line "Current configuration ...etc". Since this
line has a variable entity (the number of bytes), we cannot use the line parameter of the lineinfile module. Instead, we'll use
the regexp parameter to match on regular expressions and remove the line in the file:
---
- name: BACKUP ROUTER CONFIGURATIONS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: BACKUP THE CONFIG
ios_config:
backup: yes
register: config_output
Step 10
Now run the playbook.
ansible-playbook backup.yml
changed: [rtr1]
changed: [rtr2]
changed: [rtr3]
Step 11
Use an editor to view the cleaned up files. The first 2 lines that we cleaned up in the earlier tasks should be absent:
head -n 10 backup/rtr1.config
!
! Last configuration change at 14:25:42 UTC Tue Jun 19 2018 by ec2-user
!
version 16.8
downward-compatible-config 16.8
no service log backtrace
no service config
no service exec-callback
no service nagle
Note: The head unix command will display the first N lines specified as an argument.
In the previous lab you learned how to backup the configuration of the 4 cisco routers. In this lab you will learn how to restore the
configuration. The backups had been saved into a local directory called backup .
backup
├── rtr1.config
├── rtr1_config.2018-06-07@20:36:05
├── rtr2.config
├── rtr2_config.2018-06-07@20:36:07
├── rtr3.config
├── rtr3_config.2018-06-07@20:36:04
├── rtr4.config
└── rtr4_config.2018-06-07@20:36:06
Our objective is to apply this "last known good configuraion backup" to the routers.
Step 1
On one of the routers ( rtr1 ) manually make a change. For instance add a new loopback interface.
Log into rtr1 using the ssh rtr1 command and add the following:
rtr1#config terminal
Enter configuration commands, one per line. End with CNTL/Z.
rtr1(config)#interface loopback 101
rtr1(config-if)#ip address 169.1.1.1 255.255.255.255
rtr1(config-if)#end
rtr1#
rtr1#
Step 2
Step 1 simulates our "Out of process/band" changes on the network. This change needs to be reverted. So let's write a new
playbook to apply the backup we collected from our previous lab to achieve this.
Create a file called restore_config.yml using your favorite text editor and add the following play definition:
---
- name: RESTORE CONFIGURATION
hosts: cisco
connection: network_cli
gather_facts: no
Step 3
Write the task to copy over the previously backed up configuration file to the routers.
---
- name: RESTORE CONFIGURATION
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: COPY RUNNING CONFIG TO ROUTER
command: scp ./backup/{{inventory_hostname}}.config {{inventory_hostname}}:/{{inventory_hostname}}.config
Note the use of the inventory_hostname variable. For each device in the inventory file under the cisco group, this task
will secure copy (scp) over the file that corresponds to the device name onto the bootflash: of the CSR devices.
Step 4
Go ahead and run the playbook.
ansible-playbook restore_config.yml
Step 5
Log into the routers to check that the file has been copied over
ssh rtr1
rtr1#dir
Directory of bootflash:/
Step 6
Now that the known good configuration is on the destination devices, add a new task to the playbook to replace the running
configuration with the one we copied over.
---
- name: RESTORE CONFIGURATION
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: COPY RUNNING CONFIG TO ROUTER
command: scp ./backup/{{inventory_hostname}}.config {{inventory_hostname}}:/{{inventory_hostname}}.config
Note: Here we take advantage of Cisco's archive feature. The config replace will only update the differences to the router
and not really a full config replace.
Step 7
Let's run the updated playbook:
ansible-playbook restore_config.yml
Step 8
Validate that the new loopback interface we added in Step 1 is no longer on the device.
ssh rtr1
rtr1#sh ip int br
Interface IP-Address OK? Method Status Protocol
GigabitEthernet1 172.16.165.205 YES DHCP up up
Loopback0 192.168.1.101 YES manual up up
Loopback1 10.1.1.101 YES manual up up
Tunnel0 10.100.100.1 YES manual up up
Tunnel1 10.200.200.1 YES manual up up
VirtualPortGroup0 192.168.35.101 YES TFTP up up
rtr1#sh run inter
rtr1#sh run interface Loo
rtr1#sh run interface Loopback 101
^
% Invalid input detected at '^' marker.
rtr1#
You have successfully backed up and restored configurations on your Cisco routers!
Sommaire
Lab 3.1. Introduction modèle Jinja2
Données structurées et rôles
Lab 3.2. Documentation dynamique
Templates
Ansible has native integration with the Jinja2 templating engine
Render data models into device configurations
Render device output into dynamic documentation
Jinja2 enables the user to manipulate variables, apply conditional logic and extend programmability for network automation.
vlans:
- id: 10
name: WEB
- id: 20
name: APP
- id: 30
name: DB
Jinja2 template
vlan {{ vlan.id }}
name {{ vlan.name }}
leaf1.conf
vlan 10
name WEB
vlan 20
name APP
vlan 30
name DB
{{ inventory_hostname.upper() }}
---
{{ ansible_net_serialnum }} : {{ ansible_net_version }}
RTR1
---
9YJXS2VD3Q7 : 16.08.01a
RTR2
---
9QHUCH0VZI9 : 16.08.01a
RTR3
---
9ZGJ5B1DL14 : 16.08.01a
RTR4
---
9TCM27U9TQG : 16.08.01a
RTR1
---
9YJXS2VD3Q7 : 16.08.01a
RTR2
---
9QHUCH0VZI9 : 16.08.01a
RTR3
---
9ZGJ5B1DL14 : 16.08.01a
RTR4
---
9TCM27U9TQG : 16.08.01a
Generally speaking, when one talks about network automation the focus is specifically around configuration management of
devices. In this lab you will learn how to use Ansible as a tool to generate living, dynamic documentation.
This allows the ability to generate reports and documents, using the same information and can cater to the needs of a hands-on-
keyboard network engineer to a manager who needs to understand the state of the network with a glance of a web-page!
Jinja2 is a powerful templating engine for Python. There is native integration of Jinja2 with Ansible. Jinja2 allows for manipulating
variables and implementing logical constructs. In combination with the Ansible template module, the automation engineer has a
powerful tool at their disposal to generate live or dynamic reports.
In this lab you will learn how to use the template module to pass collected data from devices to a Jinja2 template. The template
module then renders the output as a markdown file.
Step 1
Create a new playbook called router_report.yml and add the following play definition to it:
---
- name: GENERATE OS REPORT FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no
Step 2
Add a task that collects the facts using the ios_facts module. Recollect that we used this module in an earlier lab.
---
- name: GENERATE OS REPORT FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: GATHER ROUTER FACTS
ios_facts:
Recall that the facts modules automatically populate the ansible_net_version and ansible_net_serial_number
variables within the play. You can validate this by running the playbook in verbose mode.
Step 3
Rather than using debug or verbose mode to display the output on the screen, go ahead and add a new task using the template
module as follows:
---
- name: GENERATE OS REPORT FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: GATHER ROUTER FACTS
ios_facts:
Let's break this task down a bit. The template module has a src parameter that has a value of os_report.j2 . In the next few
steps, we will create this file. This will be the Jinja2 template, used to generate the desired report. The dest parameter specifies
the destination file name to render the report into.
Step 4
In the previous step we are rendering the generated report into a directory called reports . Go ahead and create this directory.
mkdir reports
Step 5
The next step is to create a Jinja2 template. Ansible will look for the template file in the current working directory and within a
directory called templates automatically. Convention/best-practice is to create the template file within the template directory.
Using vi , nano or another text editor, go ahead and create a new file called os_report.j2 under the templates directory. Add
the following into the template file:
{{ inventory_hostname.upper() }}
---
{{ ansible_net_serialnum }} : {{ ansible_net_version }}
This file simply contains some of the variables we have been using in our playbooks until now.
Note: Python inbuilt methods for datatypes are available natively in Jinja2 making it very easy to manipulate the formatting
etc.
Step 6
With this in place, go ahead and run the playbook:
ansible-playbook router_report.yml
changed: [rtr2]
changed: [rtr3]
changed: [rtr1]
Step 7
After the playbook run, you should see the following files appear in the reports directory:
reports/
├── rtr1.md
├── rtr2.md
├── rtr3.md
└── rtr4.md
0 directories, 4 files
cat reports/rtr4.md
RTR4
---
9TCM27U9TQG : 16.08.01a
Step 8
While it is nice to have the data, it would be even better to consolidate all these individual router reports into a single document.
Let's add a new task to do that
---
- name: GENERATE OS REPORT FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no
tasks:
- name: GATHER ROUTER FACTS
ios_facts:
Here we are using the assemble module. The src parameter specifies the directory that contain file fragments that need to be
consolidated and the dest parameter provides the file to render the fragments into.
Note: The delegate_to can be used to specify tasks that need to be executed locally. The run_once directive will ensure
that the given task is executed only once.
Step 9
Go ahead and run the playbook.
ansible-playbook router_report.yml
Step 10
A new file called network_os_report.md will now be available in the playbook root. Use the cat command to view it's contents:
cat network_os_report.md
RTR1
---
9YJXS2VD3Q7 : 16.08.01a
RTR2
---
9QHUCH0VZI9 : 16.08.01a
RTR3
---
9ZGJ5B1DL14 : 16.08.01a
RTR4
---
9TCM27U9TQG : 16.08.01a
Note: Markdown files can be rendered visually as HTML yum -y install python-markdown python -m markdown input.md >
output.html
At this point, with 3 small tasks, you have an OS report on all the IOS devices in your network. This is a simple example but the
principle remains as you expand upon the capabilities. For example, you can build status reports and dashboards that rely on the
output of device show commands.
Ansible provides the tools and methods to extend network automation beyond configuration management to more robust
capabilities, such as, generating documentation and or reports.
The Ansible network-engine is a role that supports 2 such "translators" - command_parser and textfsm_parser . These are
modules built into the network-engine role that takes a raw text input (pretty formatted) and converts it into structured data. You
will work with each of these to generate dynamic reports in the following sections:
Inventory
Playbook
Roles
Roles help simplify playbooks.
Think of them as callable functions for repeated tasks
Roles can be distributed/shared; similar to libraries
site.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
ospf/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
# site.yml
---
- hosts: routers
roles:
- common
- ospf
Ansible Galaxy
http://galaxy.ansible.com
Ansible Galaxy is a hub for finding, reusing and sharing Ansible roles.
Jump-start your automation project with content contributed and reviewed by the Ansible community.
---
- name: GENERATE INTERFACE REPORT
hosts: cisco
gather_facts: no
connection: network_cli
roles:
- ansible-network.network-engine
On most network devices, show command output is "pretty" formatted but not structured. The Ansible network-engine role
provides support for 2 text parsing engines:
TextFSM
Command Parser
---
- name: GENERATE INTERFACE REPORT
hosts: cisco
gather_facts: no
connection: network_cli
roles:
- ansible-network.network-engine
tasks:
- name: CAPTURE SHOW INTERFACES
ios_command:
commands:
- show interfaces
register: output
rtr2#show interfaces
GigabitEthernet1 is up, line protocol is up
Hardware is CSR vNIC, address is 0e56.1bf5.5ee2 (bia 0e56.1bf5.5ee2)
Internet address is 172.17.16.140/16
MTU 1500 bytes, BW 1000000 Kbit/sec, DLY 10 usec,
reliability 255/255, txload 1/255, rxload 1/255
Encapsulation ARPA, loopback not set
Keepalive set (10 sec)
Full Duplex, 1000Mbps, link type is auto, media type is Virtual
output flow-control is unsupported, input flow-control is unsupported
ARP type: ARPA, ARP Timeout 04:00:00
Last input 00:00:00, output 00:00:00, output hang never
Last clearing of "show interface" counters never
Input queue: 0/375/0/0 (size/max/drops/flushes); Total output drops: 0
Queueing strategy: fifo
Output queue: 0/40 (size/max)
5 minute input rate 1000 bits/sec, 1 packets/sec
5 minute output rate 1000 bits/sec, 1 packets/sec
208488 packets input, 22368304 bytes, 0 no buffer
Received 0 broadcasts (0 IP multicasts)
0 runts, 0 giants, 0 throttles
0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored
0 watchdog, 0 multicast, 0 pause input
250975 packets output, 40333671 bytes, 0 underruns
0 output errors, 0 collisions, 1 interface resets
0 unknown protocol drops
0 babbles, 0 late collision, 0 deferred
0 lost carrier, 0 no carrier, 0 pause output
0 output buffer failures, 0 output buffers swapped out
Loopback0 is up, line protocol is up
Hardware is Loopback
Internet address is 192.168.2.102/24
MTU 1514 bytes, BW 8000000 Kbit/sec, DLY 5000 usec,
reliability 255/255, txload 1/255, rxload 1/255
Encapsulation LOOPBACK, loopback not set
Keepalive set (10 sec)
.
.
.
.
.
<output omitted for brevity>
Let's say your task is to prepare a list of interfaces that are currently up, the MTU setting, the type and description on the
interface. You could log into each device, execute the above command and collect this information. Now imagine if you had to
repeat this for 150 devices in your network. That is a lot of man-hours on a relatively boring task!
In this lab, we will learn how to automate this exact scenario using Ansible.
Step 1
Start by creating a new playbook called interface_report.yml and add the following play definition:
---
- name: GENERATE INTERFACE REPORT
hosts: cisco
gather_facts: no
connection: network_cli
Step 2
Next add the ansible-network.network-engine role into the playbook. Roles are nothing but a higher level playbook abstraction.
Think of them as pre-written playbooks that handle repeated, specific tasks. For this we will need to first install the role. Execute
the following command on the control node to install this role:
The ansible-network.network-engine role specifically makes available the command_parser module, among other things, which
you can then use in subsequent tasks inside your own playbook.
---
- name: GENERATE INTERFACE REPORT
hosts: cisco
gather_facts: no
connection: network_cli
roles:
- ansible-network.network-engine
Step 3
Now we can begin adding our tasks. Add the first task to run the show interfaces command against all the routers and register
the output into a variable.
---
- name: GENERATE INTERFACE REPORT
hosts: cisco
gather_facts: no
connection: network_cli
roles:
- ansible-network.network-engine
tasks:
- name: CAPTURE SHOW INTERFACES
ios_command:
commands:
- show interfaces
register: output
Feel free to run this playbook in verbose mode to view the output returned from the devices.
Step 4
The next task is to send the raw data returned in the previous task to the command_parser module. This module takes the raw
content as one of the inputs along with the name of the parser file.
Note: The parser file is a YAML file that has a similar structure to Ansible playbooks.
---
- name: GENERATE INTERFACE REPORT
hosts: cisco
gather_facts: no
connection: network_cli
roles:
- ansible-network.network-engine
tasks:
- name: CAPTURE SHOW INTERFACES
ios_command:
commands:
- show interfaces
register: output
Let's understand this task in a little more depth. The command_parser is referencing a file called show_interfaces.yaml within the
parsers directory. For this lab, the parser has been pre-populated for you. The parsers are written to handle the output from
standard show commands on various network platforms.
More parsers are being made available in the public domain so you will only have to build them if a specific use case has
not been handled.
Feel free to view the contents of the parser file. You will notice how it uses regular expressions to capture relevant data from the
show command and return it as a variable called interface_facts
Step 5
Add a new task to view the contents being returned by the command_parser
---
- name: GENERATE INTERFACE REPORT
hosts: cisco
gather_facts: no
connection: network_cli
roles:
- ansible-network.network-engine
tasks:
- name: CAPTURE SHOW INTERFACES
ios_command:
commands:
- show interfaces
register: output
Step 6
Go ahead and run this playbook. Since our objective is to simply view the returned data, limit your playbook run to a single
router.
"type": "Virtual"
}
}
}
]
}
How cool is that! Your playbook now converted all that raw text output into structured data: a list of dictionaries where each
dictionary describes the elements you need to build your report.
Step 7
Next create a directory to hold the per device report:
mkdir intf_reports
Step 8
Our next step is to use the template module to generate a report from the above data. Use the same technique you learned in
the previous lab to generate the reports per device and then consolidate them using the assemble module.
---
- name: GENERATE INTERFACE REPORT
hosts: cisco
gather_facts: no
connection: network_cli
roles:
- ansible-network.network-engine
tasks:
- name: CAPTURE SHOW INTERFACES
ios_command:
commands:
- show interfaces
register: output
Note: For this lab the Jinja2 template has been pre-populated for you. Feel free to look at the file interface_facts.j2 in the
templates directory.
Note: The debug task has been commented out so that display is consise
Step 9
Run the playbook:
ansible-playbook interface_report.yml
Step 10
Use the cat command to view the contents of the final report:
cat interfaces_report.md
RTR1
----
GigabitEthernet1:
Description:
Name: GigabitEthernet1
MTU: 1500
Loopback0:
Description:
Name: Loopback0
MTU: 1514
Loopback1:
Description:
Name: Loopback1
MTU: 1514
Tunnel0:
Description:
Name: Tunnel0
MTU: 9976
Tunnel1:
Description:
Name: Tunnel1
MTU: 9976
VirtualPortGroup0:
Description:
Name: VirtualPortGroup0
MTU: 1500
RTR2
----
GigabitEthernet1:
Description:
Name: GigabitEthernet1
MTU: 1500
Loopback0:
Description:
Name: Loopback0
MTU: 1514
Loopback1:
Description:
Name: Loopback1
MTU: 1514
.
.
.
.
.
<output omitted for brevity>
L'interface GigabitEthernet 0/7 sert de console de contrôle TCP/IP et ne participe pas au routage.
2. Topologie de base
Topologie
R1
R2
R3
4. Station d'administration
Appliance Network Automation (GNS3) est connectée au même commutateur que les interfaces de gestion des routeurs.
Un nuage NAT est aussi connecté au commutateur. Il fournit les services Internet, DHCP et DNS dans le réseau
192.168.122.1/24 .
apt-get update && apt-get -y install vim tree git ansible dnsutils
ssh-keygen
[defaults]
inventory = ./hosts
remote_user = root
host_key_checking = False
[core]
R1
R2
R3
[cisco:children]
core
[cisco:vars]
ansible_user=root
ansible_ssh_pass=testtest
ansible_port=22
ansible_connection=network_cli
ansible_network_os=ios
7. Module ios_command
ios_command : http://docs.ansible.com/ansible/latest/ios_command_module.html
---
- name: SHOW IP INTERFACE BRIEF
hosts: all
connection: network_cli
gather_facts: no
tasks:
- name: show interfaces
ios_command:
commands: show ip interface brief
wait_for:
- result[0] contains GigabitEthernet
register: print_output
- debug: var=print_output
8. Module ios_config
ios_config : http://docs.ansible.com/ansible/latest/ios_config_module.html
9. Conditions
https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html
10. Boucles
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
Le dossier host_vars définit les variables des périphériques à configurer et maintenir. Ces fichiers corresspondent à l'énoncé
d'un lab.
cat host_vars/R1
hostname: R1
interface:
- {id: GigabitEthernet0/0,ipv4: 192.168.1.1,netmask: 255.255.255.0}
- {id: GigabitEthernet0/2,ipv4: 192.168.225.1,netmask: 255.255.255.0}
- {id: GigabitEthernet0/3,ipv4: 192.168.226.1,netmask: 255.255.255.0}
interface6:
- {id: GigabitEthernet0/0,net6: 'fe80::1'}
- {id: GigabitEthernet0/2,net6: 'fe80::1'}
- {id: GigabitEthernet0/3,net6: 'fe80::1'}
lan6:
- { id: GigabitEthernet0/0,net6: 'fd00:00:00:1::1/64'}
ipv4routing:
- {rid: 1.1.1.1,passive: GigabitEthernet0/0,area: 0,pid: 1,as: 1}
ipv6routing:
- {rid: 1.1.1.1, passive: GigabitEthernet0/0,area: 0,pid: 1,as: 1}
ospfv2:
- {id: GigabitEthernet0/0,ipv4: 192.168.1.1,pri: 255,cost: 1}
- {id: GigabitEthernet0/2,ipv4: 192.168.225.1,pri: 255,cost: 1}
- {id: GigabitEthernet0/3,ipv4: 192.168.226.1,pri: 255,cost: 1}
ospfv3:
- {id: GigabitEthernet0/0,pri: 255,cost: 1}
- {id: GigabitEthernet0/2,pri: 255,cost: 1}
- {id: GigabitEthernet0/3,pri: 255,cost: 1}
- import_playbook: playbooks/enable_interfaces.yml
- import_playbook: playbooks/configure_ipv4_adresses.yml
- import_playbook: playbooks/enable_ospfv2.yml
- import_playbook: playbooks/enable_ipv6.yml
- import_playbook: playbooks/configure_ipv6_address.yml
- import_playbook: playbooks/enable_ospfv3.yml
- import_playbook: playbooks/write_memory.yml
A adapter : https://docs.ansible.com/ansible/2.4/playbooks_best_practices.html
---
- name: show interfaces configuration
hosts: core
gather_facts: no
tasks:
- name: show interfaces
ios_command:
commands: show ip interface brief
wait_for:
- result[0] contains G
register: print_output
- debug: var=print_output
Topologies
En IOSv-L2.
https://docs.ovh.com/fr/public-cloud/creer-un-acces-a-horizon/
Programmes de formation
Formation Ansible Essentials: Simplicity in Automation Technical Overview
Programme du cours
Cours Red Hat DO407 Automation avec Ansible I
Formation Red Hat DO457 Ansible Network Automation
Formation Red Hat DO409 Automatisation : passez au niveau supérieur avec Ansible Tower
Examen Red Hat Certified Specialist in Ansible Automation exam (EX407)
Programme du cours
Sur inscription : https://www.redhat.com/fr/services/training/do007-ansible-essentials-simplicity-automation-technical-overview
Dans le cadre de travaux pratiques, les participants apprendront à automatiser avec Ansible des tâches d'administration système
sur des hôtes gérés, à écrire des playbooks Ansible pour standardiser l'exécution de tâches, à gérer des playbooks de façon
centralisée et à planifier des exécutions récurrentes via une interface Web avec Ansible Tower. Les participants apprendront
aussi à gérer le chiffrement pour Ansible avec Ansible Vault, à déployer Ansible Tower et à l'utiliser pour gérer des systèmes,
ainsi qu'à utiliser Ansible dans un environnement DevOps avec Vagrant.
Contenu du cours
Installer et résoudre les problèmes d'Ansible sur des nœuds centraux et des hôtes gérés
Utiliser Ansible pour exécuter des commandes ad hoc et des playbooks pour automatiser les tâches
Écrire des playbooks Ansible efficaces
Protéger les données chiffrées nécessaires à certaines tâches avec Ansible Vault
Utiliser Ansible Tower pour simplifier la gestion des déploiements Ansible en entreprise
Utiliser Ansible avec Vagrant dans un environnement DevOps
Présentation d'Ansible
Learn how to use Red Hat Ansible Automation for Networking to remotely automate configuration of network devices, test and
validate the current network state, and perform compliance checks to detect and correct configuration drift.
Install and configure Red Hat Ansible Automation for Networking on a management system
Use Ansible to run ad hoc commands and playbooks to automate tasks
Write effective Ansible playbooks for network automation
Gather information about network infrastructure configuration and backup
Automate specific network administration use cases, including configuration of routers and switches, ports, VLANs, SNMP
monitoring, and routing protocols
Use Ansible playbooks to target devices from various hardware vendors, including Cisco, Juniper, and Arista
Course outline
1. Deploy Ansible
Install Ansible and create Ansible inventories.
2. Run commands and plays
Execute ad hoc commands and prepare Ansible playbooks.
3. Parameterize Ansible
Control tasks with loops and conditions.
4. Administer Ansible
Safeguard information with Ansible Vault and manage inventories.
5. Automate simple network operations
Gather network information with Ansible and configure network devices.
6. Automate complex operations
Solve new MACD challenges and overcome real-world challenges.
Présentation du cours
Pendant ce cours, les participants apprendront à déployer et à utiliser Ansible Tower de Red Hat pour gérer leurs projets,
playbooks et rôles Ansible existants. Ils apprendront également à effectuer la maintenance de base et l'administration de
l'installation d'Ansible Tower, ainsi qu'à configurer des utilisateurs et des équipes afin de les utiliser pour contrôler l'accès aux
systèmes, aux projets et aux autres ressources via la mise en place de contrôles d'accès basés sur les rôles. Les participants
apprendront aussi à utiliser le tableau de bord visuel pour lancer, contrôler et surveiller de manière centralisée les tâches Ansible
Tower, à utiliser l'API Ansible Tower pour lancer des tâches à partir de modèles existants, à planifier automatiquement des
tâches Ansible et à mettre à jour l'inventaire de l'hôte.
Contenu du cours
Programme du cours
Variables
Facts
Plays
Playbooks
Configuration files
2. Run ad-hoc Ansible commands
3. Use both static and dynamic inventories to define groups of hosts
4. Utilize an existing dynamic inventory script
5. Create Ansible plays and playbooks
Know how to work with commonly used Ansible modules
Use variables to retrieve the results of running a commands
Use conditionals to control play execution
Configure error handling
Create playbooks to configure systems to a specified state
Selectively run specific tasks in playbooks using tags
6. Create and use templates to create customized configuration files
7. Work with Ansible variables and facts
8. Create and work with roles
9. Download roles from an Ansible Galaxy and use them
10. Manage parallelism
11. Use Ansible Vault in playbooks to protect sensitive data
12. Install Ansible Tower and use it to manage systems
13. Use provided documentation to look up specific information about Ansible modules and commands
Notes
Tâches supplémentaires
Exemples proposés ICND2
Construction de roles
Modules à exploiter
Mise en place de playbooks
Structure
Définition des Variables
Définition d'un livre de jeux
Source: Ansible Linklight - Networking
Presentation
Ansible Engine Networking Exercises
Network Diagram
Additional information
Tâches supplémentaires
désactiver les bannières
https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html
ansible_connection: network_cli
ansible_network_os: ios
ansible_user: myuser
ansible_ssh_pass: !vault...
ansible_become: yes
ansible_become_method: enable
ansible_become_pass: !vault...
ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q bastion01"'
ansible_connection: network_cli
ansible_network_os: nxos
ansible_user: myuser
ansible_ssh_pass: !vault...
ansible_become: yes
ansible_become_method: enable
ansible_become_pass: !vault...
ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q bastion01"'
ansible_connection: httpapi
ansible_network_os: nxos
ansible_user: myuser
ansible_ssh_pass: !vault...
proxy_env:
http_proxy: http://proxy.example.com:8080
Construction de roles
enable dhcp server
enable dhcp relay server
enable dns cache server
RA disable SLAAC
RA enable dhcpv6 Stateless
RA enable dhcpv6 Stateful
enable dhcpv6 Stateless server
enable dhcpv6 Stateful server
enable ntp server
enable ntp client
Modules à exploiter
http://docs.ansible.com/ansible/latest/ios_system_module.html
http://docs.ansible.com/ansible/latest/ios_banner_module.html
http://docs.ansible.com/ansible/latest/ios_facts_module.html
http://docs.ansible.com/ansible/latest/ios_vrf_module.html
Suggestions
STP Tree
Switchport Hardening
Roles :
OSPF Router
EIGRP Router
Structure
Variables
Langages
YAML
Jinja2
Push Model
Structure
Hosts
hosts_vars
roles
Facts
Variables
handlers
Presentation
Want the Presentation Deck? Its right here: Ansible Networking Linklight Deck
Network Diagram
Additional information
Network Automation with Ansible Homepage
List of Networking Ansible Modules
Module Maintenance & Support
Network Automation GitHub Repo
Red Hat® Ansible® Tower: Built for operationalizing and scaling automation, managing complex deployments and speeding
up productivity. Extend the power of Ansible Tower with Workflows and Surveys to streamline jobs and simple tools to share
solutions with your team.
Red Hat® Ansible® Engine: a fully supported product built on the foundational capabilities of the Ansible project. Also
provides support for select modules including Infoblox.
Red Hat® Ansible® Network Automation: provides support for select networking modules from Arista (EOS), Cisco (IOS,
IOS XR, NX-OS), Juniper (JunOS), Open vSwitch, and VyOS. Includes Ansible Tower, Ansible Engine, and curated content
specifically for network use cases.