Introductie
In het kort is serverconfiguratiebeheer (ook populair bekend als IT-automatisering) een oplossing om uw infrastructuurbeheer om te zetten in een codebase, waarin alle processen die nodig zijn voor het implementeren van een server worden beschreven in een reeks provisioning-scripts die kunnen worden versiebeheerd en gemakkelijk hergebruikt. Het kan aanzienlijk de integriteit van elke serverinfrastructuur in de loop van de tijd verbeteren.
In een vorige handleiding spraken we over de belangrijkste voordelen van het implementeren van een configuratiebeheerstrategie voor uw serverinfrastructuur, hoe configuratiebeheertools werken, en wat deze tools doorgaans gemeen hebben.
In dit deel van de serie zullen we u door het proces leiden van het automatiseren van serverprovisioning met behulp van Ansible, een configuratiebeheertool die een volledig automatiseringsframework en orkestratiemogelijkheden biedt, met behoud van het doel van ultieme eenvoud en minimalisme. We zullen ons richten op de taalterminologie, syntaxis en functies die nodig zijn om een vereenvoudigd voorbeeld te maken om de implementatie van een Ubuntu 18.04-webserver met Apache volledig te automatiseren.
De volgende lijst bevat alle stappen die we moeten automatiseren om ons doel te bereiken:
- Update de
apt
-cache - Installeer Apache
- Maak een aangepaste document root-directory
- Plaats een
index.html
bestand in de aangepaste document root - Pas een sjabloon toe om onze aangepaste virtuele host in te stellen
- Herstart Apache
We beginnen met het bekijken van de terminologie die wordt gebruikt door Ansible, gevolgd door een overzicht van de belangrijkste taalkenmerken die kunnen worden gebruikt om playbooks te schrijven. Aan het einde van de gids vindt u de inhoud van een volledig voorbeeld van provisioning om de stappen te automatiseren die zijn beschreven voor het instellen van Apache op Ubuntu 18.04.
Opmerking: deze gids is bedoeld om u kennis te laten maken met de Ansible-taal en hoe u playbooks kunt schrijven om uw serverprovisioning te automatiseren. Voor een meer introductieve kijk op Ansible, inclusief de stappen die nodig zijn voor het installeren en aan de slag gaan met deze tool, evenals hoe u Ansible-opdrachten en playbooks kunt uitvoeren, bekijk onze Hoe u Ansible installeert en configureert op Ubuntu 18.04 gids.
Aan de slag
Voordat we naar een meer praktische weergave van Ansible kunnen gaan, is het belangrijk dat we vertrouwd raken met belangrijke terminologie en concepten die door deze tool worden geïntroduceerd.
Terminologie
De volgende lijst bevat een snel overzicht van de meest relevante termen die worden gebruikt door Ansible:
- Besturingsknooppunt: de machine waarop Ansible is geïnstalleerd, verantwoordelijk voor het uitvoeren van de provisioning op de servers die u beheert.
- Inventaris: een
INI
-bestand dat informatie bevat over de servers die u beheert. - Playbook: een
YAML
-bestand met een reeks procedures die geautomatiseerd moeten worden. - Taak: een blok dat een enkele procedure definieert die moet worden uitgevoerd, bijvoorbeeld: het installeren van een pakket.
- Module: een module abstraheert typisch een systeemtaak, zoals het omgaan met pakketten of het maken en wijzigen van bestanden. Ansible heeft een veelheid aan ingebouwde modules, maar u kunt ook aangepaste modules maken.
- Rol: een set gerelateerde playbooks, sjablonen en andere bestanden, georganiseerd op een vooraf gedefinieerde manier om hergebruik en delen te vergemakkelijken.
- Play: een provisioning die van begin tot einde wordt uitgevoerd, wordt een play genoemd.
- Feiten: globale variabelen die informatie bevatten over het systeem, zoals netwerkinterfaces of besturingssysteem.
- Handlers: gebruikt om wijzigingen in de servicestatus te activeren, zoals het opnieuw starten of herladen van een service.
Taakindeling
A task defines a single automated step that should be executed by Ansible. It typically involves the usage of a module or the execution of a raw command. This is how a task looks:
- name: This is a task
apt: name=vim state=latest
Het name
-gedeelte is eigenlijk optioneel, maar aanbevolen, omdat het verschijnt in de uitvoer van de provisioning wanneer de taak wordt uitgevoerd. Het apt
-gedeelte is een ingebouwde Ansible-module die het beheer van pakketten op op Debian gebaseerde distributies abstract maakt. Deze voorbeeldtaak vertelt Ansible dat het pakket vim
van staat moet veranderen naar latest
, wat ervoor zal zorgen dat de pakketbeheerder dit pakket installeert als het nog niet is geïnstalleerd.
Opmaak van Playbook
Playbooks zijn YAML
-bestanden met een reeks aanwijzingen om de provisioning van een server te automatiseren. Het volgende voorbeeld is een eenvoudig playbook dat twee taken uitvoert: de apt
-cache bijwerken en vervolgens vim
installeren:
---
- hosts: all
become: true
tasks:
- name: Update apt-cache
apt: update_cache=yes
- name: Install Vim
apt: name=vim state=latest
YAML
vertrouwt op inspringing om gegevensstructuren te serialiseren. Daarom moet je bij het schrijven van playbooks en vooral bij het kopiëren van voorbeelden extra voorzichtig zijn om de juiste inspringing te behouden.
Voor het einde van deze gids zullen we een meer realistisch voorbeeld van een playbook zien, uitvoerig uitgelegd. Het volgende gedeelte geeft een overzicht van de belangrijkste elementen en functies die kunnen worden gebruikt om Ansible-playbooks te schrijven.
Playbooks schrijven
Nu je bekend bent met de basisbegrippen en de algemene opmaak van playbooks en taken in Ansible, zullen we enkele functies van playbooks leren die ons kunnen helpen bij het maken van meer veelzijdige automatiseringen.
Werken met variabelen
Er zijn verschillende manieren waarop je variabelen kunt definiëren in Ansible. De eenvoudigste manier is door de vars
-sectie van een playbook te gebruiken. Het onderstaande voorbeeld definieert bijvoorbeeld een variabele package
die later wordt gebruikt binnen een taak:
---
- hosts: all
become: true
vars:
package: vim
tasks:
- name: Install Package
apt: name={{ package }} state=latest
De variabele package
heeft een globale reikwijdte, wat betekent dat deze vanuit elk punt van de voorziening kan worden benaderd, zelfs vanuit opgenomen bestanden en sjablonen.
Gebruik van lussen
Lussen worden typisch gebruikt om een taak te herhalen met verschillende invoerwaarden. In plaats van 10 taken te maken voor het installeren van 10 verschillende pakketten, kun je een enkele taak maken en een lus gebruiken om de taak te herhalen met alle verschillende pakketten die je wilt installeren.
Om een lus binnen een taak te maken, voeg je de optie with_items
toe met een array van waarden. De inhoud kan worden benaderd via de lusvariabele item
, zoals getoond in het onderstaande voorbeeld:
- name: Install Packages
apt: name={{ item }} state=latest
with_items:
- vim
- git
- curl
Je kunt ook een array-variabele gebruiken om je items te definiëren:
---
- hosts: all
become: true
vars:
packages: [ 'vim', 'git', 'curl' ]
tasks:
- name: Install Package
apt: name={{ item }} state=latest
with_items: "{{ packages }}"
Het gebruik van Conditionals
Conditionals kunnen worden gebruikt om dynamisch te beslissen of een taak moet worden uitgevoerd, op basis van een variabele of een uitvoer van een opdracht, bijvoorbeeld.
Het volgende voorbeeld zal alleen Debian-gebaseerde systemen uitschakelen:
De conditional when
ontvangt als argument een expressie die moet worden geëvalueerd. De taak wordt alleen uitgevoerd als de expressie wordt geëvalueerd naar true
. In ons voorbeeld hebben we een feit getest om te controleren of het besturingssysteem afkomstig is van de Debian-familie.
A common use case for conditionals in IT automation is when the execution of a task depends on the output of a command. With Ansible, the way we implement this is by registering a variable to hold the results of a command execution, and then testing this variable in a subsequent task. We can test for the command’s exit status (if failed or successful). We can also check for specific contents inside the output, although this might require the usage of regex expressions and string parsing commands.
Het volgende voorbeeld toont twee conditionele taken op basis van de uitvoer van een php -v
-opdracht. We zullen de exit-status van de opdracht testen, aangezien we weten dat deze niet zal worden uitgevoerd als PHP niet is geïnstalleerd op deze server. Het gedeelte ignore_errors
van de taak is belangrijk om ervoor te zorgen dat de provisioning doorgaat, zelfs wanneer de opdracht mislukt.
De gebruikte debug
-module hier is een handige module voor het tonen van de inhoud van variabelen of debugberichten. Het kan ofwel een string afdrukken (bij het gebruik van het msg
-argument) of de inhoud van een variabele afdrukken (bij het gebruik van het var
-argument).
Werken met Templates
Templates worden meestal gebruikt om configuratiebestanden in te stellen, waardoor het gebruik van variabelen en andere functies mogelijk is die bedoeld zijn om deze bestanden veelzijdiger en herbruikbaar te maken. Ansible gebruikt de Jinja2 template-engine.
Het volgende voorbeeld is een sjabloon voor het instellen van een Apache virtuele host, waarbij een variabele wordt gebruikt voor het instellen van de documentroot voor deze host:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot {{ doc_root }}
<Directory {{ doc_root }}>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
De ingebouwde module template
wordt gebruikt om de sjabloon vanuit een taak toe te passen. Als je het bovenstaande sjabloonbestand bijvoorbeeld vhost.tpl
hebt genoemd en het in dezelfde map als je playbook hebt geplaatst, is dit hoe je de sjabloon zou toepassen om de standaard Apache virtuele host te vervangen:
Hanlers Definiëren en Activeren
Handlers worden gebruikt om een statuswijziging in een service te activeren, zoals een herstart of een stop. Ook al lijken ze misschien vrij veel op gewone taken, handlers worden alleen uitgevoerd wanneer ze eerder zijn geactiveerd vanuit een notify
-instructie in een taak. Ze worden meestal gedefinieerd als een array in een handlers
-sectie van het playbook, maar ze kunnen ook in afzonderlijke bestanden staan.
Laten we ons vorige voorbeeld van het gebruik van een sjabloon in overweging nemen, waar we een Apache virtuele host hebben ingesteld. Als je ervoor wilt zorgen dat Apache opnieuw wordt gestart na een wijziging in de virtuele host, moet je eerst een handler voor de Apache-service maken. Zo worden handlers gedefinieerd in een playbook:
De name
directive hier is belangrijk omdat het de unieke identifier van deze handler zal zijn. Om deze handler te activeren vanuit een taak, moet je de notify
optie gebruiken:
We hebben enkele van de belangrijkste functies gezien die je kunt gebruiken om te beginnen met het schrijven van Ansible-playbooks. In de volgende sectie duiken we in een meer realistisch voorbeeld van een playbook dat de installatie en configuratie van Apache op Ubuntu automatiseert.
Voorbeeld Playbook
Laten we nu eens kijken naar een playbook dat de installatie van een Apache-webserver automatiseert binnen een Ubuntu 18.04-systeem, zoals besproken in de inleiding van deze gids.
Het volledige voorbeeld, inclusief het sjabloonbestand voor het opzetten van Apache en een HTML-bestand dat door de webserver wordt geserveerd, is te vinden op Github. De map bevat ook een Vagrantfile waarmee je het playbook kunt testen in een vereenvoudigde opstelling, met behulp van een virtuele machine beheerd door Vagrant.
Inhoud van het Playbook
De volledige inhoud van het playbook is hier beschikbaar voor jouw gemak:
- ---
- - hosts: all
- become: true
- vars:
- doc_root: /var/www/example
- tasks:
- - name: Update apt
- apt: update_cache=yes
-
- - name: Install Apache
- apt: name=apache2 state=latest
-
- - name: Create custom document root
- file: path={{ doc_root }} state=directory owner=www-data group=www-data
-
- - name: Set up HTML file
- copy: src=index.html dest={{ doc_root }}/index.html owner=www-data group=www-data mode=0644
-
- - name: Set up Apache virtual host file
- template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
- notify: restart apache
- handlers:
- - name: restart apache
- service: name=apache2 state=restarted
-
Laten we elk deel van dit playbook in meer detail bekijken:
hosts: all
Het playbook begint met te verklaren dat het moet worden toegepast op alle
hosts in uw inventaris (hosts: all
). Het is mogelijk om de uitvoering van het playbook te beperken tot een specifieke host of een groep hosts. Deze optie kan worden overschreven bij uitvoeringstijd.
become: true
Het gedeelte become: true
vertelt Ansible om privilege-escalatie (sudo) te gebruiken voor het uitvoeren van alle taken in dit playbook. Deze optie kan per taak worden overschreven.
vars
Definieert een variabele, doc_root
, die later wordt gebruikt in een taak. Deze sectie kan meerdere variabelen bevatten.
taken
Het gedeelte waar de daadwerkelijke taken worden gedefinieerd. De eerste taak werkt de apt
-cache bij, en de tweede taak installeert het pakket apache2
.
De derde taak gebruikt de ingebouwde module file om een directory aan te maken om te dienen als onze documentroot. Deze module kan worden gebruikt om bestanden en mappen te beheren.
De vierde taak gebruikt de module copy om een lokaal bestand naar de externe server te kopiëren. We kopiëren een eenvoudig HTML-bestand om te dienen als onze website gehost door Apache.
handlers
Tenslotte hebben we de handlers
-sectie, waar de services worden gedeclareerd. We definiëren de restart apache
handler die wordt geactiveerd door de vierde taak, waar de Apache-template wordt toegepast.
Het uitvoeren van een Playbook
Zodra u de inhoud van dit playbook hebt gedownload naar uw Ansible-besturingsknooppunt, kunt u ansible-playbook
gebruiken om het uit te voeren op een of meer knooppunten uit uw inventaris. Het volgende commando voert het playbook uit op alle hosts uit uw standaardinventarisbestand, met SSH-sleutelpaarverificatie om verbinding te maken als de huidige systeemgebruiker:
U kunt ook -l
gebruiken om de uitvoering te beperken tot een enkele host of een groep hosts uit uw inventaris:
Als u een andere SSH-gebruiker moet opgeven om verbinding te maken met de externe server, kunt u het argument -u gebruiker
opnemen in dat commando:
Voor meer informatie over het uitvoeren van Ansible-opdrachten en playbooks kunt u onze handleiding raadplegen over Hoe Ansible te installeren en configureren op Ubuntu 18.04.
Conclusie
Ansible is een minimalistisch IT-automatiseringstool dat een lage leercurve heeft en YAML
gebruikt voor zijn voorzieningsscripts. Het heeft een groot aantal ingebouwde modules die kunnen worden gebruikt om taken zoals het installeren van pakketten en werken met sjablonen abstract te maken. De vereenvoudigde infrastructuurvereisten en eenvoudige taal kunnen een goede keuze zijn voor degenen die beginnen met configuratiebeheer. Het kan echter wel enkele geavanceerde functies missen die je kunt vinden bij complexere tools zoals Puppet en Chef.
In het volgende deel van deze serie zullen we een praktisch overzicht zien van Puppet, een populair en goed gevestigd configuratiebeheerstool die een expressieve en krachtige aangepaste DSL op basis van Ruby gebruikt om voorzieningsscripts te schrijven.