greenbutterfly - stock.adobe.com
Einführung in die Netzwerkautomatisierung mit Ansible
Ansible bietet Admins mehr Kontrolle über die Konfiguration von Geräten. Mit unseren Tipps und Tricks können Sie sich schnell mit den Funktionen von Ansible vertraut machen.
Dank Tools wie Ansible können Netzwerkadministratoren die Netzwerkgeräte eines Herstellers konfigurieren, ohne deren Befehlszeilensyntax zu kennen. Benutzer können zudem Konfigurationen gleichzeitig auf mehreren Geräten implementieren.
Dieser Artikel zeigt, wie Sie Ansible zur Netzwerkautomatisierung einsetzen, von den ersten Schritten über die Ausführung von Ansible Playbooks bis hin zum Troubleshooting. Es sind keine Vorkenntnisse zu Ansible erforderlich, da der Artikel praxisnahe Beispiele enthält, um die einzelnen Prozesse zu veranschaulichen.
Erste Schritte mit Ansible zur Netzwerkautomatisierung
Wenn Sie Ansible einrichten, installieren Sie es auf einem Kontrollknoten, der sich mit Netzwerkgeräten verbindet und diese verwaltet. Sie müssen die Netzwerkkonfiguration in einer YAML-Datei definieren, die als Playbook bezeichnet wird. Das folgende Playbook erfasst beispielsweise die Schnittstellen auf einem Router.
- hosts: R1
gather_facts: false
tasks:
- name: Gather router interfaces
raw: 'show ip int brief'
Ansible verwendet drei Kommunikationsprotokolle, um den Kontrollknoten mit Netzwerkgeräten zu verbinden:
- CLI über Secure Socket Shell (SSH): Die Konfiguration eines Netzwerkgeräts über die Kommandozeile (Command-line interface, CLI) wird in ein Modul abstrahiert und in einem Playbook definiert. Um etwa die Schnittstelle eines Routers anzuzeigen, müssen Sie im Playbook lediglich ein Argument wie l3_interfaces angeben. Ansible versteht, dass Sie show ip interface brief meinen, und führt dies über SSH aus.
- XML über SSH: Ansible nutzt das XML-basierte Network Configuration Protocol (NETCONF), um mit dem Netzwerkgerät über SSH zu interagieren. Es sendet XML-Befehle, um die Gerätekonfigurationen abzurufen oder zu ändern. Dies wird ebenfalls in einem Playbook definiert.
- API über HTTP oder HTTPS: Hier interagiert Ansible mit einem Netzwerkgerät per REST APIs über HTTP oder HTTPS. Die Konfiguration wird im JSON-Format an das Gerät gesendet. Diese API-Aufrufe sind auch in einem Playbook definiert.
Sehen wir uns an, wie sich mit Ansible Netzwerkkonfigurationen automatisch auf zwei Netzwerkgeräten implementieren lassen. Sie können die Konfiguration mithilfe von CLI über SSH anwenden.
Ansible für Netzwerkgeräte konfigurieren
Sehen wir uns zunächst die Anforderungen für dieses Lab an, wie Sie die Ansible- und Netzwerkgeräteumgebung vor der Automatisierung vorbereiten und wie Sie die Ansible-Dokumentation eines Herstellers oder Anbieters richtig lesen.
Sie benötigen Folgendes, um Ansible für Ihre Netzwerkgeräte zu konfigurieren:
- Ein vorzugsweise virtualisiertes Homelab, zum Beispiel Graphical Network Simulator-3 (GNS3) oder EVE-NG.
- Ein lizenziertes Cisco- oder Arista-Router-Image.
- Ansible, das Sie auf Ihrem Rechner installiert haben.
Verzeichnis- und Dateistruktur von Ansible
Standardmäßig speichert Ansible Dateien unter /etc/ansible, unter anderem systemweite Konfigurationsdateien, Rollen und das Inventory.
ansible.cfg
root@Charles:/etc/ansible# tree
.
|-- ansible.cfg
`-- hosts
Die Datei ansible.cfg ist die zentrale Konfigurationsdatei, in der Sie den Standardspeicherort für bestimmte Dateien festlegen, wie Inventory, Logs, Remote-Portnummern, Rollen und andere Assets.
Machen Sie sich zunächst mit dem Inventory File (Inventardatei) vertraut. Die anderen Dateien werden mit zunehmender Erfahrung nützlich sein.
hosts
Dies ist die Inventardatei. Sie enthält die IP-Adressen beziehungsweise Host-Namen der Geräte, mit denen Sie eine Verbindung herstellen. Sie können die Geräte gruppieren und ihnen einen Namen geben. Gruppieren Sie die Geräte beispielsweise nach ihrem Standort, etwa München oder Hamburg.
Der Inhalt der Inventar-Host-Datei von Ansible liegt standardmäßig im INI-Format vor. Es handelt sich üblicherweise um Klartext, der aufgrund der Struktur aber schwer zu lesen ist. Viele Netzwerkadministratoren bevorzugen YAML, da es leichter verständlich ist. Dadurch wird die Datei im YAML-Format gespeichert.
DNS-Auflösung auf dem Ansible-Kontrollknoten konfigurieren
Sie müssen die IP-Adresse der Router-Schnittstelle zu Ihrer Host-Datei hinzufügen, damit Ihr Kontrollknoten Router wie R1, R2, R3 und R4 erkennt.
Außerdem muss die IP-Adresse des Routers im gleichen Bereich wie der Ansible-Kontrollknoten liegen.
vi /etc/hosts
192.168.122.161 R1
192.168.122.162 R2
192.168.122.163 R3
192.168.122.164 R4
Verwechseln Sie diese Host-Datei nicht mit der im Ansible-Verzeichnis.
Managementschnittstelle und Host-Namen des Routers manuell konfigurieren
Die Managementschnittstelle muss sich im gleichen Bereich wie der Ansible-Kontrollknoten befinden, um zu verhindern, dass der Knoten mit ihr interagiert.
In einem Produktionsnetzwerk werden diese Schnittstellen in der Regel automatisch mithilfe von Zero Touch Provisioning (ZTP) oder dem Dynamic Host Configuration Protocol (DHCP) erstellt.
So konfigurieren Sie unsere Beispiel-Cisco-Router R1 und R2:
configure terminal
hostname R1
interface Eth0/0
ip address 192.168.122.161 255.255.255.0
no shutdown
end
----------------------------------------
configure terminal
hostname R2
interface Eth0/0
ip address 192.168.122.162 255.255.255.0
no shutdown
end
Und so sieht das Ganze für unsere Arista-Router R3 und R4 aus:
configure terminal
hostname R3
interface Eth0/0
ip address 192.168.122.163 255.255.255.0
no shutdown
---------------------------------------------------------------
configure terminal
hostname R4
interface Eth0/0
ip address 192.168.122.164 255.255.255.0
no shutdown
SSH auf Ihren Geräten manuell konfigurieren
Der nächste Schritt besteht darin, sicherzustellen, dass SSH auf den Routern konfiguriert ist.
So funktioniert‘s für die Cisco-Router R1 und R2:
configure terminal
username cisco password cisco
username cisco privilege 15
line vty 0 4
transport input all
login local
exit
ip domain-name homelab.com
crypto key generate rsa
1024
end
write
Der SSH-Konfigurationsprozess für die Arista-Pendants R3 und R4 sieht folgendermaßen aus:
username arista privilege 15 secret arista
dns domain homelab.com
management ssh
Als Nächstes verbinden Sie sich über SSH von Ihrem Ansible-Kontrollknoten aus mit den Routern, um zu gewährleisten, dass die SSH-Konfiguration des Routers korrekt ist. Dadurch werden auch die SSH-Schlüssel des Routers lokal zur Datei known_hosts Ihres Kontrollknotens hinzugefügt.
ssh cisco@R1
ssh cisco@R2
------------
ssh arista@R3
ssh arista@R4
Nun können Sie in Ihrer Inventardatei auf die SSH-Anmeldedaten und den Host-Namen des Routers verweisen.
Benutzerdefinierte Inventardatei erstellen
Obwohl es in Ansible eine standardmäßige Inventardatei unter /etc/ansible/hosts gibt, können Sie eine benutzerdefinierte Datei in einem anderen Verzeichnis erstellen und bei der Ausführung darauf verweisen.
Nachfolgend finden Sie eine benutzerdefinierte Inventardatei mit Anweisungen, wie Sie sich mit Ihren Geräten verbinden. Denken Sie daran, SSH zuerst manuell auf Ihren Geräten zu konfigurieren. Weitere Optionen für die Inventarverbindung finden Sie hier.
Die Datei inventory.yaml definiert und organisiert die von Ansible verwalteten Hosts und Gruppen, wie im Folgenden zu sehen ist.
local:
hosts:
R1:
ansible_connection: network_cli
ansible_host: R1
ansible_user: cisco
ansible_password: cisco
ansible_network_os: cisco.ios.ios
ansible_become: true
ansible_become_method: enable
R2:
ansible_connection: network_cli
ansible_host: R2
ansible_user: cisco
ansible_password: cisco
ansible_network_os: cisco.ios.ios
ansible_become: true
ansible_become_method: enable
R3:
ansible_connection: network_cli
ansible_host: R3
ansible_user: arista
ansible_password: arista
ansible_network_os: arista.eos.eos
ansible_become: true
ansible_become_method: enable
R4:
ansible_connection: network_cli
ansible_host: R4
ansible_user: arista
ansible_password: arista
ansible_network_os: arista.eos.eos
ansible_become: true
ansible_become_method: enable
So lesen Sie die Ansible-Dokumentation eines Herstellers
Bei der Implementierung der Netzwerkautomatisierung mit Ansible ist es wichtig, Parameter anzugeben, wenn Sie ein Playbook definieren möchten, um das Gerät eines Herstellers zu konfigurieren. Es kann allerdings schwierig sein, die Datentypen der Parameter zu verstehen. Konzentrieren wir uns auf die folgenden drei Datentypen:
- dictionary
- list / elements=dictionary
- list / elements=string
1. dictionary (Wörterbuch)
Diese Datenstruktur speichert Schlüssel-Wert-Paare und wird häufig für komplexe Konfigurationen verwendet, um ein strukturiertes, lesbares Format zu gewährleisten.
key_1: value_1
key_2: value_2
2. list / elements=dictionary (Liste mit Wörterbüchern als Elemente)
Hierbei handelt es sich um eine Liste von Wörterbüchern. Ein Index der Liste kann ein Wörterbuch mit mehreren Schlüssel-Wert-Paaren enthalten.
list_of_dictionaries:
- key_1: value_1
key_2: value_2
- key_3: value_3
key_4: value_4
Dieses Beispiel zeigt eine Liste mit zwei Elementen, die jeweils durch einen Bindestrich markiert sind. Mit anderen Worten: Jeder Bindestrich stellt einen Index einer Liste dar. Diese Struktur kommt oft in Modulparametern, Variablendefinitionen und Schleifenkonstruktionen zum Einsatz.
3. list / elements=string (Liste mit Zeichenketten als Elemente)
Diese Notation steht für eine Liste, in der jedes Element Zeichenkettenwerte enthält. Jeder Index in der folgenden Liste enthält genau eine Zeichenkette:
list_of_strings:
- "value_1"
- "value_2"
Diese Struktur ist einfacher als list / elements=dictionary, da sie keine verschachtelten Strukturen enthält.
Eine Collection installieren
Kommen wir nun zur Praxis und installieren die Cisco- beziehungsweise Arista-Collection. Eine Collection (Sammlung) ist ein Modul, das die Befehlszeilensyntax einer Aktion abstrahiert, zum Beispiel das Anzeigen von Schnittstellen oder das Konfigurieren einer Schnittstelle.
ansible-galaxy collection install cisco.ios
ansible-galaxy collection install arista.eos
Konfiguration von OSPF auf den Netzwerkgeräten
Anschließend definieren Sie die Konfigurationen in einem Playbook. Ein Playbook kann zahlreiche Aufgaben, sogenannte Tasks, enthalten, beispielsweise:
- Das Netzwerk R1 über Open Shortest Path First (OSPF) bekannt geben.
- Die Ergebnisse der Konfiguration anzeigen.
Definieren Sie in Ihrem Playbook zunächst den Host, mit dem Sie sich verbinden, die Aufgabe, die Sie ausführen, und die Modulkonfiguration, die Sie verwenden möchten.
Cisco und Arista nutzen ios_ospfv2 beziehungsweise os_ospfv2, um OSPFv2 zu konfigurieren.
Öffnen Sie die Seite Modules (Module) in der Dokumentation des Geräteherstellers, und gehen Sie zum Abschnitt Examples (Beispiele), um zu erfahren, wie das Modul verwendet wird und was es macht.
Konfigurieren Sie OSPF auf R1 und R2 mithilfe der in der Dokumentation unter Modules aufgeführten Parameter.
Wenn Sie die OSPFv2-Dokumentation von Cisco oder Arista öffnen, ist der erste Parameter config mit dem Datentyp Dictionary. Das Dictionary enthält ein einzelnes Schlüssel-Wert-Paar, key1: value1, wie zuvor beschrieben.
Der zweite Parameter nennt sich processes. Sie sind bereits mit der Konfiguration von OSPF auf Cisco- oder Arista-Geräten per CLI vertraut und wissen daher, dass Sie einen OSPF-Prozess einbinden müssen. Der Parameter processes ist vom Datentyp list / elements=dictionary. Das heißt, Sie müssen eine Liste definieren, die mehrere Indizes mit jeweils mehreren Schlüssel-Wert-Paaren enthalten kann.
Wenn Sie die Dokumentation auf diese Weise lesen, können Sie Ihre Ansible-Konfiguration im Handumdrehen erstellen.
Konfiguration von OSPF auf R1 und R2 (Cisco)
Im Folgenden wird OSPF auf den Cisco-Routern R1 und R2 mithilfe des Playbooks cisco-ospf.yaml konfiguriert.
- hosts: R1
tasks:
- name: advertise R1 network to ospf
cisco.ios.ios_ospfv2:
config:
processes:
- process_id: 1
areas:
- area_id: "0"
network:
- address: 192.168.122.0
wildcard_bits: 0.0.0.255
area: 0
register: r1_ospf
- name: show the r1_ospf output
ansible.builtin.debug:
var: r1_ospf
- hosts: R2
tasks:
- name: advertise R2 network to ospf
cisco.ios.ios_ospfv2:
config:
processes:
- process_id: 1
areas:
- area_id: "0"
network:
- address: 192.168.122.0
wildcard_bits: 0.0.0.255
area: 0
register: r2_ospf
- name: show the r2_ospf output
ansible.builtin.debug:
var: r2_ospf
Konfiguration von OSPF auf R3 und R4 (Arista)
Im nächsten Beispiel wird OSPF auf den Arista-Routern R3 und R4 mithilfe des Playbooks arista-ospf.yaml konfiguriert.
- hosts: R3
tasks:
- name: advertise R3 network to ospf
arista.eos.eos_ospfv2:
config:
processes:
- process_id: 1
areas:
- area_id: "0"
networks:
- area: 0
network_address: 192.168.122.0
mask: 0.0.0.255
register: r3_ospf
- name: show the r3_ospf output
ansible.builtin.debug:
var: r3_ospf
- hosts: R4
tasks:
- name: advertise R4 network to ospf
arista.eos.eos_ospfv2:
config:
processes:
- process_id: 1
areas:
- area_id: "0"
networks:
- area: 0
network_address: 192.168.122.0
mask: 0.0.0.255
register: r4_ospf
- name: show the r4_ospf output
ansible.builtin.debug:
var: r4_ospf
In Ansible müssen Sie einen Ausgabe-Task definieren, wenn Sie das Ergebnis einer angewendeten Konfiguration anzeigen möchten. Dies können Sie mit der Variablen register erreichen, wie sie im vorherigen Playbook verwendet wurde. Die Variable erfasst die Ausgabe und zeigt sie mit dem integrierten Ansible-Debug-Modul an.
So führen Sie Ansible-Playbooks aus
Ein Playbook in Ansible lässt sich mit dem Befehl ansible-playbook ausführen. Bei diesem Befehl können Sie auch das Flag -i verwenden, um das benutzerdefinierte Inventory zu definieren, das Sie verwenden wollen.
So führen Sie das Playbook cisco-ospf aus:
ansible-playbook cisco-ospf.yaml -i inventory.yaml
Und so sieht die Ausgabe des Cisco-R1-Tasks aus:
TASK [advertise R1 network to ospf] ********************************************
changed: [R1]
TASK [show the r1_ospf output] **************************************************************
ok: [R1] => {
"r1_ospf": {
"after": {
"processes": [
{
"network": [
{
"address": "192.168.122.0",
"area": "0",
"wildcard_bits": "0.0.0.255"
}
],
"process_id": 1
}
]
},
"before": {},
"changed": true,
"commands": [
"router ospf 1",
"network 192.168.122.0 0.0.0.255 area 0"
],
"failed": false
}
}
So führen Sie das Playbook arista-ospf aus:
ansible-playbook arista-ospf.yaml -i inventory.yaml
Und das ist die Ausgabe des Arista-R3-Tasks:
TASK [advertise R3 network to ospf] ****************************************************
changed: [R3]
TASK [show the r3_ospf output] **********************************************************************
ok: [R3] => {
"r3_ospf": {
"after": {
"processes": [
{
"max_lsa": {
"count": 12000
},
"networks": [
{
"area": "0.0.0.0",
"prefix": "192.168.122.0/24"
}
],
"process_id": 1
}
]
},
"before": [],
"changed": true,
"commands": [
"router ospf 1",
"network 192.168.122.0 0.0.0.255 area 0",
"exit"
],
"failed": false
}
}
Diese Ausgaben bedeuten, dass OSPF erfolgreich konfiguriert wurde. Aus Gründen der Übersichtlichkeit enthält dieser Artikel nur jeweils eine Ausgabe pro Hersteller.
Beachten Sie den Abschnitt commands bei den Ausgaben.
"commands": [
"router ospf 1",
"network 192.168.122.0 0.0.0.255 area 0",
"exit"
],
Obwohl der CLI-Befehl nicht im Playbook angegeben war, hat das Ansible-Modul die Anfrage verstanden und in den CLI-Befehl übersetzt.
Troubleshooting in Ansible
In diesem Abschnitt stellen wir zahlreiche Fehler vor, die beim Arbeiten mit Ansible auftreten können, sowie Möglichkeiten zu deren Behebung. Die hierbei verwendeten Installationsbefehle beziehen sich auf eine Debian-basierte Linux-Distribution. Für Nicht-Debian-Benutzer empfiehlt es sich, einfach nach Informationen zur Installation von Anwendungen zu suchen.
Ansible kann sich nicht erfolgreich per SSH mit dem Gerät verbinden
Installieren Sie ansible-pylibssh, um für eine alternative SSH-Implementierung zu sorgen und Verbindungsprobleme zu beheben.
sudo apt install python3-pip -y
pip3 install ansible-pylibssh --break-system-packages
Überprüfen Sie zusätzlich die SSH-Schlüsselberechtigungen, überprüfen Sie, ob manuelle SSH-Verbindungen funktionieren, und verwenden Sie das Flag -vvv, um während der Ausführung mehr Details in der Ausgabe zu sehen, zum Beispiel:
- Den ausgeführten SSH-Befehl.
- SSH-Verbindungsparameter.
- Detaillierte SSH-Fehlermeldungen.
- Informationen zum Verbindungs-Timeout.
- Eingesetzte Authentifizierungsmethoden.
Ansible lehnt mein SSH-Passwort ab
Installieren Sie das Tool sshpass mit dem folgenden Befehl:
sudo apt install sshpass -y
Dieser Workaround ist nützlich, wenn Sie mit Systemen arbeiten, die keine schlüsselbasierte Authentifizierung unterstützen, bei vollständig automatisierten Bereitstellungen ohne interaktive Passwortabfragen und in Fällen, in denen korrekte Anmeldedaten vorliegen.
Diese Methode birgt jedoch Sicherheitsrisiken, unter anderem die Offenlegung von Passwörtern und die unsichere Speicherung von Passwörtern.
Ansible lehnt die von mir verwendete Cisco- und Ansible-Collection ab, wenn ich ein Playbook ausführe
In diesem Fall aktualisieren Sie Ihr Ansible auf die neueste Version. Die Cisco- und Ansible-Collection erfordert Ansible ab Version 2.16.0.
Weitere Schritte mit Ansible
Netzwerkadministratoren können auch erweiterte Funktionen nutzen. Beispiele hierfür sind Rollen und asynchrone Aktionen:
- Rollen: Dabei handelt es sich um wiederverwendbare, strukturierte Ordner, die alle notwendigen Komponenten enthalten, um ein Automatisierungsziel zu erreichen. Wenn Sie eine Rolle erstellen, können Sie diese optional online auf Ansible Galaxy veröffentlichen. Ein Beispiel ist eine Cisco-Rolle, die Backups für Cisco-Geräte mit Adaptive Security Appliance (ASA) und Internetworking Operating System (IOS) erstellt, oder eine Arista-Rolle, die EOS-Routemaps (Extensible Operating System) und die Konfiguration statischer IPv4-Routen verwaltet.
- Asynchrone Aktionen: Manche Tasks benötigen viel Zeit zur Ausführung, beispielsweise das Neustarten eines Netzwerkgeräts. Passen Sie Ihr Ansible-Playbook so an, dass andere Tasks gestartet werden, ohne auf den Abschluss einer langwierigen Aufgabe zu warten.
Die Einarbeitung in ein neues Tool kann schwierig sein, aber Netzwerkadministratoren haben Gelegenheit, sich im Community-Forum von Ansible mit anderen Ansible-Anwendern auszutauschen. Das Forum und andere öffentliche Online-Communities bieten ein reichhaltiges Wissen erfahrener Netzwerktechniker, die sich mit Ansible auskennen und Anfängern den Einstieg erleichtern können.