Ansible

Ansible je populární software pro správu konfigurace. Hlavní myšlenkou je deklarativní popis toho, co "má na serveru být" a nikoli toho co "se má udělat, aby na serveru bylo to, co tam má být". V našem případě je jeho účelem primárně bootstrap jednotlivých prostředí, ale používá se i pro jejich průběžnou správu. Playbooky jsou autoritou pro to, co má na serverech být nainstalováno jako nutné minimum; přebývající balíčky se neřeší.

Ansible se instaluje na "správcovský stroj", v našem případě stroj, na kterém máme uloženy playbooky (viz. dále). Ansible klient se na servery připojuje pomocí SSH. Není tedy potřeba na serveru mít nic jiného, než funkční konfiguraci sítě.

Pro naše účely je potřeba mít nainstalovaný alespoň Ansible 2.8. Instaluje se ze systémových balíčků.

Základní pojmy

  • Inventory

    • Inventory je .ini nebo (v našem případě) .yml soubor s popisem infrastruktury - jednotlivých serverů a jim přiřazených proměnných. Při běhu Ansiblu se z něj tyto informace berou a doplňují do právě běžícím příkazů a playbooků.

  • Playbook

    • Playbook je .yml soubor se seznamem tasků a handlerů. Ansible prochází souborem odshora dolů a vykonává jednotlivé tasky, které projde všechny (pokud nejsou specifikovány if-podmínky). Následně se spouští (také odshora dolů) některé handlery, podle toho, které jsou notifikovány. Notifikaci handleru obstarává task při svém běhu.

  • Fakta

    • Ansible po připojení na server sesbírá základní sadu informací o stroji. Tomuto balíku dat, který se propaguje ze serveru na správcovský stroj, se říká fakta. Fakta jsou dostupná při běhu playbooku a je možné pomocí nich realizovat např. větvení.

Další podrobnosti jsou v oficiální dokumentaci.

Základní příkazy

V našem repozitáři se nachází inventory.yml soubor s inventory. Soubor používáme namísto defaultu, takže se na něj musíme explicitně odkázat. To je možné buď přepínačem -i při spuštění Ansible, nebo nastavením proměnné prostředí ANSIBLE_INVENTORY=…​. Pokud na serveru nemáme SSH klíč, je nutné přidávat příkazům parametr --ask-pass.

Takto zkusíme ad-hoc příkazem spojení na všechny stroje v inventory.

export ANSIBLE_INVENTORY=./inventory.yml
fiisch@seeker:~/git-repo/iam-appliance-infrastructure (develop *%)> ansible all -m ping --ask-pass
SSH password:

iam-osbuild.bcv | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

Takto na nich spustíme nějaký vzdálený příkaz.

fiisch@seeker:~/git-repo/iam-appliance-infrastructure (develop *%)> ansible all -a 'ping -c1 www.google.com' --ask-pass -i inventory.yml
SSH password:
iam-osbuild.bcv | CHANGED | rc=0 >>

PING www.google.com (172.217.23.196) 56(84) bytes of data.
64 bytes from prg03s05-in-f4.1e100.net (172.217.23.196): icmp_seq=1 ttl=120 time=3.76 ms

--- www.google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 3.761/3.761/3.761/0.000 ms

Playbooky

Celé prostředí se konfiguruje přes playbooky, aby bylo možné konfiguraci strojů verzovat a automatizovat jejich bootstrapping, pokud to bude potřeba.

Příklad spuštění playbooku.

fiisch@seeker:~/git-repo/iam-appliance-infrastructure (develop *%)> ansible-playbook -i inventory.yml iam-appliance-baseos/base.yml --ask-pass
SSH password:

PLAY [iam-osbuild.bcv] ********************************************************

TASK [Gathering Facts] ********************************************************
ok: [iam-osbuild.bcv]

TASK [install EPEL] ***********************************************************
ok: [iam-osbuild.bcv]

TASK [install yum-config-manager] *********************************************
changed: [iam-osbuild.bcv]

TASK [install Cockpit] ********************************************************
changed: [iam-osbuild.bcv]

RUNNING HANDLER [enable Cockpit] **********************************************
changed: [iam-osbuild.bcv]

PLAY RECAP ********************************************************************
iam-osbuild.bcv            : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0