Skip to main content

WORKSHOP 4: Variabelen

In de vorige oefeningen leerden we eenvoudige playbooks op te stellen. Eenmaal we langere en complexere playbooks gaan maken zal de noodzaak groter worden om variabelen te gaan gebruiken.

Doelstelling

In deze workshop leer je:

  • Hoe Ansible variable delimiters gebruikt {{ en }}.
  • Wat host_vars en group_vars zijn en wanneer deze te gebruiken.
  • Hoe ansible_facts te gebruiken
  • Hoe je de debug module kan gebruiken om variabelen naar de console te schrijven.

Workshop

Variabelen kunnen in Ansible playbooks gebruikt worden door een variabele naam tussen dubbele accolades te plaatsen {{ en }}.

Here comes a variable {{ variable1 }}

Variabelen en hun waardes kunnen op veel verschillende plaatsen gedefinieerd worden: de inventory, de playbook zelf, extra files, command line, etc... Ansible zal alle mogelijke plaatsen bekijken om mogelijke variabelen op te nemen.
De aanbevolen plaats (best practice en afhankelijk van de situatie) is om bestanden met variabelen te voorzien in de mappen host_vars en group_vars:

  • Variabelen definiëren voor een groep servers doe je met een YAML-bestand met de naam group_vars/servers.
  • Variabelen definiëren voor een specifieke host (vb node1) doe je in een YAML-file met de naam host_vars/node1.yml.
warning

Hostvariabelen zijn specifieker dan groepsvariabelen. Bijgevolg nemen hostvariabelen dus voorrang op de groepsvariabelen.

note

Zoals je wel zal gemerkt hebben, werden er reeds enkele variabelen gebruikt in de inventory die we tot nu toe gebruikten.

Stap 1 - Bestand voor variabelen voorzien

Om het gebruik van groeps- en hostvariabelen en de locaties om deze te plaatsen goed te begrijpen werken we onze vorige setup met webservers verder uit.

In deze workshop zullen we inhoud van de index.html laten afhangen van het feit of een webserver voor development(dev) of production(prod) zal gebruikt worden.

  • Creëer alvast eerst de extra mappen onder je Ansible project:

    [student@ControlHost ansible-files]$ mkdir host_vars group_vars
  • Maak nu twee bestanden aan met de variabele. We definiëren een variabele met de naam stage die als waarde dev of prod zal meekrijgen.

  • in ./ansible-files/group_vars/web.yml plaats je de volgende YAML-content:

    web.yml
    ---
    stage: dev
  • in ./ansible-files/host_vars/node2.yml plaats je volgende content:

    node2.yml
    ---
    stage: prod
note

Bovenstaande betekent dus dat we voor "alle" hosts van de groep web de variabele stage op dev gezet hebben. Op die manier kunnen we deze hosts aanduiden als onderdeel van de dev-omgeving. Voor node2 wordt dit dus overschreven door een specifiekere variabele die aangeeft dat de host behoort tot de prod-omgeving.

Stap 2 - web.html bestanden aanmaken

Bedoeling is nu 2 verschillende web.html bestanden aan te maken zodat de content i.f.v. de stage zal aangepast worden.

  • Maak een bestand prod_web.html aan in ./ansible-files/files/ met onderstaande content:

    prod_web.html
    <body>
    <h1>This is a production webserver, take care!</h1>
    </body>
  • Maak ook een dev_web.html aan op dezelfde locatie met voglende content:

    dev_web.html
    <body>
    <h1>This is a development webserver, have fun!</h1>
    </body>

Stap 3 - Playbook aanmaken

In deze stap maken we een playbook aan die de juiste web.html-file kopieert afhankelijk van de stage variabele.

  • Maak een nieuwe playbook aan met de naam deploy_index_html.yml in de map ./ansible-files/:

    deploy_index_html.yml
    ---
    - name: Copy web.html
    hosts: web
    become: true
    tasks:
    - name: Copy web.html
    ansible.builtin.copy:
    src: "{{ stage }}_web.html"
    dest: /var/www/html/index.html

  • Playbook uitvoeren

    [student@ControlHost ansible-files]$ ansible-playbook deploy_index_html.yml

Stap 4 - Resultaat testen

De makkelijkste test is uiteraard eens surfen naar de respectievelijke webserver. Ook dit kunnen we dus in Ansible met 1 ad-hoc command snel controleren:

tip

Mocht curl nog niet geïnstalleerd zijn op je nodes om onderstaande playbook uit te voeren, dan kan je dat snel realiseren via het ad hoc command:

ansible web -m apt -a "name=curl state=present" --become

Je zou het ook kunnen toevoegen als een extra task aan je bestaande playbook.

[student@ControlHost ansible-files]$ ansible web -m command -a "curl http://localhost"

node1 | CHANGED | rc=0 >>
<body>
// highlight-next-line
<h1>This is a development webserver, have fun!</h1>
</body> % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 67 100 67 0 0 13400 0 --:--:-- --:--:-- --:--:-- 13400
node2 | CHANGED | rc=0 >>
<body>
// highlight-next-line
<h1>This is a production webserver, take care!</h1>
</body> % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 67 100 67 0 0 13400 0 --:--:-- --:--:-- --:--:-- 13400
node3 | CHANGED | rc=0 >>
<body>
// highlight-next-line
<h1>This is a development webserver, have fun!</h1>
</body> % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 67 100 67 0 0 13400 0 --:--:-- --:--:-- --:--:-- 13400
caution

Bovenstaande manier zal zeker niet de meest efficiënte manier (verschillende, aparte html-files voorzien) zijn om content aan te passen i.f.v. een variabelen. Templates zullen hier geschikter voor zijn (zie Templates - Jinja2).

Stap 5 - Ansible Facts

Ansible Facts zijn variabelen die automatisch "ontdekt" en "ingevuld" worden door Ansible voor elke host. We kwamen eerder al de impliciete task Gathering Facts tegen telkens bij het uitvoeren van onze playbook. Het is op dat moment dat Ansible alle info verzamelt van elke host en in gepaste variabelen steekt. We kunnen ook "manueel" deze variabelen opvragen via een ad-hoc command en de module setup.

  • Om even een idee te hebben van welke informatie door Ansible verzameld wordt per host voer je volgende command uit:

    [student@ControlHost ansible-files]$ ansible node1 -m setup
  • Zoals je vaststelt is dit gigantisch veel informatie. Die kan je dan beter ook even filteren (bv. netwerk-adapter ens160, zie documentatie):

    [student@ControlHost ansible-files]$ ansible node1 -m setup -a "filter=ansible_ens192"

Stap 6 - Nog Facts

  • Probeer nu zelf eens via de module setup de variabele te zoeken die de distributie weergeeft van je hosts. Pas de juiste filter toe...
Spoiler Alert

Oplossing hieronder....

[student@ControlHost ansible-files]$ ansible all -m setup|grep distribution
[student@ControlHost ansible-files]$ ansible all -m setup -a "filter=ansible_distribution"

Stap 7 - Facts gebruiken in Playbooks

Facts kunnen we nu heel handig als variabelen gaan gebruiken in Playbooks.

  • Maak een nieuwe playbook aan met de naam facts.yml in de map ./ansible-files/:

    facts.yml
    ---
    - name: Output facts within a playbook
    hosts: all
    tasks:
    - name: Prints Ansible facts
    ansible.builtin.debug:
    msg: The default IPv4 address of {{ ansible_fqdn }} is {{ ansible_default_ipv4.address }}

tip

De module debug is zeer handig om te debuggen en om dus waardes, variabelen op de console te zien te krijgen.

[student@ControlHost ansible-files]$ ansible-playbook facts.yml

PLAY [Output facts within a playbook] ****************************************************************************

TASK [Gathering Facts] *****************************************************
ok: [ansible-1]
ok: [node1]
ok: [node2]
ok: [node3]

TASK [Prints Ansible facts] ************************************************
ok: [node1] => {
"msg": "The default IPv4 address of ip6-localhost is X.X.X.X"
}
ok: [node2] => {
"msg": "The default IPv4 address of ip6-localhost is Y.Y.Y.Y"
}
ok: [node3] => {
"msg": "The default IPv4 address of ip6-localhost is Z.Z.Z.Z"
}
ok: [ansible-1] => {
"msg": "The default IPv4 address of localhost.localdomain is A.A.A.A"
}

PLAY RECAP *****************************************************************
ansible-1 : ok=2 changed=0 unreachable=0 failed=0
node1 : ok=2 changed=0 unreachable=0 failed=0
node2 : ok=2 changed=0 unreachable=0 failed=0
node3 : ok=2 changed=0 unreachable=0 failed=0

© Deze workshop werd gebaseerd op de informatie van Red Hat Ansible Automation Platform