WORKSHOP 7: Roles
Tot nu toe creëerden we playbooks met meerdere taken erin.
Maar we willen graag deeltaken die we in de playbooks gebruikten liefst hergebruiken in meerdere situaties.
Hiervoor kunnen Ansible roles gebruikt worden.
Doelstelling
In deze workshop leer je:
- de folder-structuur opbouwen van een
Ansible Role. - hoe een Ansible Role op te bouwen.
- een Ansible
Playte maken om eenRolete gebruiken.
Workshop
Bij een Ansible role gaan we onze playbook terug uiteen rafelen in kleinere, herbruikbare stukken en in een aparte mappen-structuur plaatsen. Dit is meer in detail besproken in de online documentatie.
Stap 1 - De Ansible Role-structuur
Roles volgen een heel bepaalde structuur. De naam van de rol wordt bepaald door de "bovenste" map (top-level directory). Veel van de onderliggende mappen bevatten YAML-files met de naam main.yml.
De bestands- en templates-folders bevatten elementen waarnaar in die YAML-files gerefereerd wordt.
Een voorbeeld-structuur van een role met de naam apache ziet er als volgt uit:
roles/
apache/
├── defaults/
│ └── main.yml
├── files/
├── handlers/
│ └── main.yml
├── meta/
│ └── main.yml
├── README.md
├── tasks/
│ └── main.yml
├── templates/
├── tests/
│ ├── inventory
│ └── test.yml
└── vars/
└── main.yml
De verschillende main.yml bestanden bevatten inhoud i.f.v. hun locatie in de mappenstructuur. De vars/main.yml bevat referenties naar variabelen, de handlers/main.yml beschrijft de handlers, enzovoort.
In tegenstelling tot playbooks bevatten de main.yml-bestanden enkel de specifieke inhoud en niet de klassieke playbook-informatie zoals hosts, become,...
Er zijn eigenlijk 2 mappen voorzien voor variabelen: vars en default. "default"-variabelen hebben de laagste prioriteit en bevatten meestal enkel variabelen vastgelegd door de role-auteurs en zullen meestal overschreven worden door specifiekere waarden, meestal in vars/main.yml (meer info in de documentatie).
Ansible gaat dus standaard zoeken in elke map binnen de role naar bestanden met de naam main.yml.
Gebruik van meerdere rollen samen met hun playbooks organiseer je als volgt:
(Ansible verwacht een map roles onderliggend aan de playbook(s) waarin de rollen opgenomen werden)
site.yml # main playbook
webservers.yml # playbook for webserver tier
fooservers.yml # playbook for fooserver tier
roles/
common/ # this hierarchy represents a "role"
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
handlers/
files/
...
Roles gebruiken is vrij eenvoudig aan te geven in een playbook:
---
- name: launch roles
hosts: web
roles:
- common
- webservers
Voor elke rol hierboven onder roles zullen de tasks, de handlers en de vars van die rol opgenomen worden.
Elk script, elke template, elke... in de rol kan refereren naar relevante bestanden, templates of taken zonder absolute of relatieve paden! Ansible zal die bestanden automatisch zoeken in de mappen files,templates of tasks van de respectievelijke rol.
Stap 2 - role mappen-structuur aanmaken
Zoals eerder gezegd zal Ansible zoeken naar roles in de submappen van de map roles van je projectmap.
Elke rol heeft dus zijn eigen mappenstructuur en kunnen we makkelijk automatisch aanmaken met de tool ansible-galaxy.
Ansible Galaxy website is een centrale plaats waar je community-inhoud kan vinden (typisch "roles" en "collections") om veel gebruikte taken uit te voeren. Voor gecertificeerde en door Red Hat ondersteunde content bestaat ook Automation Hub.
-
We bouwen nu eerst een rol die Apache zal installeren en configureren om virtuele sites te hosten.\
-
Voer volgende opdrachten uit in je projectfolder
./ansible-files:[student@ControlHost ansible-files]$ mkdir roles[student@ControlHost ansible-files]$ ansible-galaxy init roles/apache_vhost -
Bekijk de folder-structuur die Ansible-galaxy aangemaakt heeft:
[student@ControlHost ansible-files]$ tree rolesroles└── apache_vhost├── defaults│ └── main.yml├── files├── handlers│ └── main.yml├── meta│ └── main.yml├── README.md├── tasks│ └── main.yml├── templates├── tests│ ├── inventory│ └── test.yml└── vars└── main.yml
Stap 3 - het Tasks-bestand in Roles
Het bestand main.yml in de folder tasks van deze rol moet het volgende uitvoeren:
- er voor zorgen dat Apache geïnstalleerd is
- er voor zorgen dat Apache gestart is en dat permanent (na reboots)
- HTML-inhoud voorzien in de Apache root-folder
- de voorziene template installeren om een virtuele host (vhost) te configureren.
Zoals eerder al aangegeven kan de main.yml enkel tasks bevatten en géén klassieke playbook-informatie.
-
Pas de inhoud van
roles/apache_vhost/tasks/main.ymlaan:main.yml---# tasks file for roles/apache_vhost- name: Install Apache2ansible.builtin.apt:name: apache2state: latest- name: Start and enable Apache2 serviceansible.builtin.service:name: apache2state: startedenabled: trueBovenstaande zorgt nu al voor een correct werkende Apache-installatie!
-
Voeg nog 2 extra taken toe die de vhost mappen-structuur voorzien en html-pagina's kopieert.
main.yml- name: Ensure vhost directory is presentansible.builtin.file:path: "/var/www/vhosts/{{ ansible_hostname }}"state: directorymode: "655"- name: Deliver html contentansible.builtin.copy:src: web.htmldest: "/var/www/vhosts/{{ ansible_hostname }}/index.html"mode: "644"Bovenstaande gebruikt de module
fileom de mappen-structuur eventueel aan te maken (zie documentatie). Het bestandweb.htmlwordt gekopieerd van de control host naar de juiste locatie op de doelhost.
Het bestandweb.htmlwordt verder in deze workshop nog aangemaakt. -
een volgende taak die we nog toevoegen aan deze YAML-file gebruikt de
templatemodule om devhost-configuratie van de webserver aan te maken en te kopiëren.main.yml- name: Template vhost fileansible.builtin.template:src: vhost.conf.j2dest: "/etc/apache2/sites-available/{{ ansible_hostname }}.conf"owner: rootgroup: rootmode: "644"Ook hier moet de template zelf (
vhost.conf.j2) nog aangemaakt worden. Dit doen we wat verder in deze workshop. De module kopieert de template over het default bestand000-default.confom de vhosts te definiëren. -
Na het toevoegen van een virtuele host aan Apache moet deze "enabled" worden. Dit gebeurt met de
apache-toola2ensite. Zoals je hieronder ziet gebruikt deze deeltaak eenhandlermet de naamRestart_apache2. De handler wordt ook later aangemaakt. -
De volledige
taskbinnen deze rol (tasks/main.yml) ziet er nu als volgt uit:---# tasks file for roles/apache_vhost- name: Install Apache2ansible.builtin.apt:name: apache2state: latest- name: Start and enable Apache2 serviceansible.builtin.service:name: apache2state: startedenabled: true- name: Ensure vhost directory is presentansible.builtin.file:path: "/var/www/vhosts/{{ ansible_hostname }}"state: directorymode: "655"- name: Deliver html contentansible.builtin.copy:src: web.htmldest: "/var/www/vhosts/{{ ansible_hostname }}/index.html"mode: "644"- name: Template vhost fileansible.builtin.template:src: vhost.conf.j2dest: "/etc/apache2/sites-available/{{ ansible_hostname }}.conf"owner: rootgroup: rootmode: "644"- name: Enable new siteansible.builtin.shell:cmd: /usr/sbin/a2ensite {{ ansible_hostname }}notify:- Restart_apache2
Stap 4 - De handler voorzien
In het bestand roles/apache_vhost/handlers/main.yml maken we de handler aan die Apache zal herstarten als die aangeroepen wordt door een notify in de "template"-taak.
---
# handlers file for roles/apache_vhost
- name: Restart_apache2
ansible.builtin.service:
name: apache2
state: restarted
Stap 5 - Voorzie een web.html bestand en vhost.conf.j2 template
-
Maak een bestand
web.htmlaan met de HTML-content voor de webserver in de mapfilesvan de rol:<html><head><title>Welcome to Apache virtual host!</title></head><body><h1>Success! The virtual host is working!</h1></body></html> -
Maak een template aan met de naam
vhost.conf.j2in de maptemplatesvan de rol:# {{ ansible_managed }}<VirtualHost *:80>ServerAdmin webmaster@{{ ansible_hostname }}ServerName {{ ansible_hostname }}ErrorLog ${APACHE_LOG_DIR}/{{ ansible_hostname }}-error.logCustomLog ${APACHE_LOG_DIR}/{{ ansible_hostname }}-common.log commonDocumentRoot /var/www/vhosts/{{ ansible_hostname }}/<Directory /var/www/vhosts/{{ ansible_hostname }}/>Options +Indexes +FollowSymlinks +IncludesRequire all grantedAllow from all</Directory></VirtualHost>
Stap 6 - Test de role
We gaan deze role toepassen op node2. Maar aangezien we een rol niet rechtstreeks kunnen toewijzen aan een node moeten we eerst een playbook voorzien waarin we de hosts en de roles samenbrengen.
-
Maak een playbook aan met de naam
test_apache_role.ymlin je projectmap:test_apache_role.yml---- name: Use apache_vhost role playbookhosts: node2become: truepre_tasks:- name: Pre tasksansible.builtin.debug:msg: 'Beginning web server configuration.'roles:- apache_vhostpost_tasks:- name: Post tasksansible.builtin.debug:msg: 'Web server has been configured.'In bovenstaande zie je 2 nieuwe
keywords⇒pre_tasksenpost_tasks. Normaal gesproken worden de taken van rollen uitgevoerd vóór de taken van een playbook. Om de volgorde van uitvoering te controleren, wordenpre_tasksuitgevoerd voordat rollen worden toegepast.post_tasksworden uitgevoerd nadat alle rollen zijn voltooid. Hier gebruiken we ze gewoon om beter te markeren wanneer de daadwerkelijke rol wordt uitgevoerd. -
playbook uitvoeren:
[student@ControlHost ansible-files]$ ansible-playbook test_apache_role.yml -
Controleer of je op node2 de nieuwe virtuele site kan bekijken:
[student@ControlHost ansible-files]$ ansible node2 -m setup | grep ansible_hostname"ansible_hostname": "iac-Managed-Host-2",[student@ControlHost ansible-files]$ ansible node2 -m command -a "curl -s http://iac-Managed-Host-2"node2 | CHANGED | rc=0 >><html><head><title>Welcome to Apache virtual host!</title></head><body><h1>Success! The virtual host is working!</h1></body></html>[student@ControlHost ansible-files]$ -
Controleer het verschil met de default site van je webserver:
[student@ControlHost ansible-files]$ ansible node2 -m command -a "curl -s http://localhost"Aangezien je nu met virtuele sites (vhosts) werkt zou Apache nu bij bovenstaand commando een andere, eerder geconfigureerde, site moeten tonen.
© Deze workshop werd gebaseerd op de informatie van Red Hat Ansible Automation Platform