Ansible - interfészek konfigurálása

Az előző leírásban még nem volt említve, de az egyik legfontosabb információforrás Ansible playbookok írásakor az eredeti dokumentációs oldal:

Interfészek módosítása

Hozzunk létre egy playbookot, amivel beállítjuk egy interfész leírását. Ehhez az ios_interfaces modulra lesz szükség.

- name: Set interface
  hosts: all
  tasks:
    - name: Set description
      cisco.ios.interfaces:
        config:
          - name: GigabitEthernet1
            description: Management interface

Mit csináljunk, ha több interfészt is szeretnénk módosítani? Mivel a config egy lista, így a kézenfekvő megoldás a következő:

- name: Set interface
  hosts: all
  tasks:
    - name: Set description
      cisco.ios.interfaces:
        config:
          - name: GigabitEthernet1
            description: Management interface
          - name: GigabitEthernet2
            description: UNUSED

Ekkor máris egy problémába ütközünk: a playbook eszköz-specifikus lesz. (Már így is az volt az interfésznevek/leírások statikus megadásával.)

Ezt érdemes elkerülni, a megoldás pedig az inventory-fájl. Szervezzük ki oda a változókat:

routers:
  hosts:
    r1:
      ansible_host: 192.168.86.201
      interfaces:
        - name: GigabitEthernet1
          description: Management interface
        - name: GigabitEthernet2
          description: UNUSED
  vars:
    ansible_connection: ansible.netcommon.network_cli
    ansible_network_os: cisco.ios.ios
    ansible_user: ansible
    ansible_password: ansible

Így módosítani kell a playbookot is, hogy az inventory fájl változóit használja.

- name: Set interface
  hosts: all
  tasks:
    - name: Set description
      cisco.ios.interfaces:
        config:
          - name: "{{ item['name'] }}"
            description: "{{ item['description'] }}"
      loop: "{{ interfaces }}"

A loop kulcsszó végig-iterál a megadott listán - ebben az esetben a host-hoz tartozó interfészeken, amit az inventory fájlban megadtunk. Ekkor a task annyiszor fog lefutni eszközönként, amilyen hosszú a lista az adott eszközön. Ilyenkor a taskon belül használható az item változó, ami egyenlő az iteráció jelenlegi elemével. A fenti példában lévő task például kétszer fog lefutni az adott eszközön, egyszer az item = { "name": "GigabitEthernet1", "description": "Management interface" }, a második futáskor pedig item = { "name": "GigabitEthernet2", "description": "UNUSED" }.

Feltételek használata

Mi történik, ha több eszközünk is van, de nem mindegyiken szeretnénk egy adott taskot végrehajtani? Persze a play-ben korlátozhatjuk a hostokat, de akár a taskon belül is szabhatunk feltételeket. Vegyük a következő inventory fájlt:

routers:
  hosts:
    r1:
      ansible_host: 192.168.86.201
      interfaces:
        - name: GigabitEthernet1
          description: Management interface
          address4: 192.168.1.2/24
        - name: GigabitEthernet2
          description: UNUSED
          address6: fe80::def link-local
  vars:
    ansible_connection: ansible.netcommon.network_cli
    ansible_network_os: cisco.ios.ios
    ansible_user: ansible
    ansible_password: ansible

Tegyük fel, hogy egy playt szeretnénk futtatni ami beállítja az interfészeken a címzéseket, viszont van, ahol IPv4-re, van ahol IPv6-ra van szükség.

- name: Set interface IP
  hosts: all
  tasks:
    - name: Set IPv4
      cisco.ios.ios_config:
        lines:
          - ip address {{ item.address4 }}
        parents:
          - interface {{ item.name }}
      loop: "{{ interfaces }}"
      when: item.address4 is defined

    - name: Set IPv6
      cisco.ios.ios_config:
        lines:
          - ipv6 address {{ item.address6 }}
        parents:
          - interface {{ item.name }}
      loop: "{{ interfaces }}"
      when: item.address6 is defined

Az itt használt ios_config modul egy általános konfigurációs modul, amivel bármit be lehet állítani az eszközön. Leírása itt található.

Így a task az adott interfészen csak akkor fog lefutni, ha az interfészen létezik az address4/address6 adattag, ellenkező esetben a task SKIPPED állapotba kerül. (Ha nem tennénk meg ezt, akkor FAILED lenne, mert megpróbálunk egy olyan változót elérni, ami nem létezik.)

Önálló feladatok

Töltsd le az AnsiblePlayground.gns3project fájlt. A topológián már el van helyezve 4 felkonfigurált IOSv router:

  • R1, 192.168.86.11/24
  • R2, 192.168.86.12/24
  • R3, 192.168.86.13/24
  • R4, 192.168.86.14/24

Már az SSH is konfigurálva lett az eszközökön, ansible/ansible felhasználóval.

Kiinduló inventory fájl:

all:
  hosts:
    r1:
      ansible_host: 192.168.86.11
    r2:
      ansible_host: 192.168.86.12
    r3:
      ansible_host: 192.168.86.13
    r4:
      ansible_host: 192.168.86.14
  vars:
    ansible_connection: ansible.netcommon.network_cli
    ansible_network_os: cisco.ios.ios
    ansible_user: ansible
    ansible_password: ansible

A feladatokat próbáld úgy megoldani, hogy minél több változót az inventoryba szervezel ki, és nem a playbookban szerepel! A feladatok megoldásához próbáld ki a specifikus, célra készült modulokat, pl. ios_interfaces, ios_l3_interfaces, ios_ospfv2, ios_ospfv3, illetve az általános modullal is: ios_config. Érd el, hogy a playbook második lefutásakor ne kapj CHANGED üzenetet!

Feladatok:

  • Konfiguráld a pont-pont kapcsolatokat IPv4 és IPv6 címekkel!
  • Konfigurálj Loopback interfészeket, IPv4 és IPv6 címekkel!
  • Konfigurálj OSPFv2-t, vegyél be minden IPv4-es címet a forgalomirányításba.
  • Konfigurálj OSPFv3-t, vegyél be minden IPv6-os címet a forgalomirányításba.