Praktische gids voor Ansible-playbooks: Inventory, Idempotentie, Vault en Rolling Updates
AI_Manager
Ansible-playbooks: Door pakketten, configuratiebestanden en servicestatussen op meerdere Linux-servers declaratief te beheren, kunt u het risico op vergeten handmatige opdrachten en omgevingsverschillen verkleinen. Echter, als u direct op alle servers acties uitvoert na slechts een geslaagde ping, onbezonnen gebruikmaakt van command- of shell-taken, of wachtwoorden in YAML-bestanden opslaat, kan automatisering leiden tot snellere verspreiding van storingen en datalekken.
Deze gids is niet gebonden aan een specifieke distributie of verouderde Ansible-versie. We bespreken een verifieerbare operationele workflow die gebruikmaakt van geïsoleerde Python-omgevingen, YAML-inventory, ansible.builtin FQCN, idempotentie, handlers, check/diff, Vault, serial en block/rescue. Controleer vóór implementatie de officiële documentatie van uw huidige ansible-core en collecties.

Kerncomponenten van Ansible-playbooks
| Component | Rol | Operationele standaarden |
|---|---|---|
| Inventory | Doelhosts, groepen en verbindingsvariabelen | Scheid dev-, stage- en prod-omgevingen en minimaliseer dubbele variabelen |
| Play | Doelgroep en uitvoeringsbeleid | Specificeer hosts, become, serial en failure-beleid |
| Task | Eén eenheid van module-aanroepen | Gebruik namen, FQCN en expliciete statussen |
| Module | Feitelijke taken zoals pakketten, bestanden en services | Kies waar mogelijk voor specifieke modules in plaats van command of shell |
| Handler | Vervolgacties die alleen worden uitgevoerd bij wijzigingen | Gebruik voor het herstarten van services na een gevalideerde configuratiewijziging |
| Role | Een verzameling herbruikbare taken, handlers, sjablonen en standaardwaarden. | Verdeel verantwoordelijkheden in kleine delen en documenteer interfacevariabelen. |
| Collectie | Distributie-eenheid voor modules, plug-ins en rollen. | Bevries geteste versies en controleer wijzigingslogboeken. |
In de statusrapportage van Ansible betekent ‘ok’ dat de gewenste status al is bereikt, ‘changed’ dat er een daadwerkelijke wijziging heeft plaatsgevonden en ‘failed’ dat er een fout is opgetreden. Kijk niet alleen naar het succes, maar controleer of changed=0 is bij een heruitvoering en of alleen de verwachte handlers worden uitgevoerd om de idempotentie te verifiëren.
De uitvoeringsomgeving voor Ansible-playbooks voorbereiden
Meng geen pakketten direct in de systeem-Python van de control node, maar maak een venv per project aan. Leg de geïnstalleerde ansible-core, Python, configuratiebestanden en collectiepaden vast om dezelfde automatisering opnieuw te kunnen reproduceren.
Ansible installeren in een Python venv
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install ansible-core ansible-lint
ansible --version
ansible-playbook --version
ansible-lint --version
python -m pip freeze > requirements-lock.txt
Voor productieprojecten moeten de versies van ansible-core en bibliotheken worden vastgelegd via een lock-bestand of een goedgekeurde pakketrepository. De methode om altijd de nieuwste versie te installeren leidt tot verlies van reproduceerbaarheid wanneer collectiecompatibiliteit en Python-vereisten veranderen.
Projectmap
install -d inventories/dev/group_vars/all inventories/prod/group_vars/all
install -d roles/web/{tasks,handlers,templates,defaults}
install -d playbooks/templates
find . -maxdepth 3 -type d | sort
Veilige standaardwaarden voor ansible.cfg
[defaults]
inventory = inventories/dev/hosts.yml
roles_path = roles
host_key_checking = True
retry_files_enabled = False
interpreter_python = auto_silent
forks = 10
timeout = 15
[privilege_escalation]
become = False
become_ask_pass = True
Voorbeelden waarbij host_key_checking is uitgeschakeld, voorkomen het detecteren van man-in-the-middle-aanvallen. Controleer de SSH-vingerafdruk van de doelsleutel via een betrouwbaar pad en registreer deze in known_hosts. Schakel ‘become’ alleen in voor de benodigde Play of Task en sla wachtwoorden nooit op in configuratiebestanden.
Ansible playbook YAML-inventaris
Groepsnamen moeten rollen en de omvang van de impact aangeven, terwijl ansible_host het daadwerkelijke verbindingsadres bevat. In plaats van productie en ontwikkeling alleen te scheiden met tags in één bestand, is het veiliger om de inventarisbron zelf te splitsen om te voorkomen dat per ongeluk ‘prod’ wordt geselecteerd.
inventories/dev/hosts.yml
all:
children:
web:
hosts:
dev-web-01:
ansible_host: 192.0.2.11
dev-web-02:
ansible_host: 192.0.2.12
database:
hosts:
dev-db-01:
ansible_host: 192.0.2.21
vars:
ansible_user: automation
ansible_become: true
Inventarissyntaxis en doelverificatie
ansible-inventory -i inventories/dev/hosts.yml --graph
ansible-inventory -i inventories/dev/hosts.yml --list | jq .
ansible web -i inventories/dev/hosts.yml -m ansible.builtin.ping --limit dev-web-01
ansible.builtin.ping is geen ICMP-ping, maar controleert de uitvoering van Python op afstand en de Ansible-verbinding. Het is slechts een signaal dat SSH-toegang, Python en rechten in orde zijn; het betekent niet dat de pakketrepository, schijfruimte of serviceafhankelijkheden gereed zijn.
Het eerste Ansible-playbook schrijven en handlers gebruiken
De onderstaande Play declareert pakketinstallatie, configuratiesjablonen en servicestatus. Gebruik voor elke taak een voor mensen leesbare naam en de FQCN. Een handler wordt alleen aangestuurd wanneer het resultaat van een sjabloon daadwerkelijk is gewijzigd, waardoor onnodige herstarts worden vermeden.
playbooks/web.yml
---
- name: Configure web servers
hosts: web
become: true
gather_facts: true
tasks:
- name: Ensure Nginx is installed
ansible.builtin.package:
name: nginx
state: present
- name: Render Nginx virtual host
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
validate: '/usr/sbin/nginx -t -c %s'
notify: Restart Nginx
- name: Ensure Nginx is enabled and running
ansible.builtin.service:
name: nginx
enabled: true
state: started
handlers:
- name: Restart Nginx
ansible.builtin.service:
name: nginx
state: restarted
Dit voorbeeld beheert de volledige /etc/nginx/nginx.conf van een nieuwe oefenhost. Om ervoor te zorgen dat nginx -t -c %s tijdelijke bestanden als onafhankelijke hoofdconfiguraties kan controleren, zijn events en http opgenomen in het onderstaande sjabloon. Overschrijf de hoofdconfiguratie van een bestaande Nginx-productieomgeving niet, aangezien dit andere virtuele hosts kan verwijderen. Productierollen die slechts een deel van een vhost distribueren, vereisen een aparte verificatieprocedure die de volledige configuratie combineert.
Jinja-sjabloonvoorbeeld
Sla de inhoud op in playbooks/templates/nginx.conf.j2. Variabelen worden als volgt in inventories/dev/group_vars/all/app.yml geplaatst. Specificeer in app_port de poort waarop de applicatie daadwerkelijk draait.
app_server_name: app.example.internal
app_port: 8080
events {
worker_connections 1024;
}
http {
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
server {
listen 80;
server_name {{ app_server_name }};
location /healthz {
access_log off;
return 200 "ok\n";
}
location / {
proxy_pass http://127.0.0.1:{{ app_port }};
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
Voorafgaande verificatie van Ansible-playbooks: syntax, check en diff
Voer na een syntaxcontrole de check-modus uit op een enkele host in de ontwikkelingsinventaris en bekijk de diff. De check-modus simuleert wijzigingen, maar wordt niet door alle modules ondersteund; bovendien kunnen Plays die waarden van eerdere taken in voorwaardelijke uitspraken gebruiken, er anders uitzien dan bij een daadwerkelijke uitvoering.
ansible-playbook -i inventories/dev/hosts.yml playbooks/web.yml --syntax-check
ansible-playbook -i inventories/dev/hosts.yml playbooks/web.yml --check --diff --limit dev-web-01
De diff toont waarden voor en na de configuratie, wat kan leiden tot het blootstellen van geheimen. Controleer bij gevoelige sjabloontaken of diff: false en no_log: true nodig zijn, en beperk de toegangsrechten en bewaartermijn van CI-logs. Zodra de verificatie is voltooid, voert u de actie uit met behoud van –limit en breidt u het bereik daarna per groep uit.
ansible-lint playbooks/web.yml
ansible-playbook -i inventories/dev/hosts.yml playbooks/web.yml --limit dev-web-01
ansible-playbook -i inventories/dev/hosts.yml playbooks/web.yml --check --limit dev-web-01
Idempotentie creëren in Ansible-playbooks
| Onveilige aanpak | Aanbevolen aanpak | Reden |
|---|---|---|
| shell: echo >> file | lineinfile, blockinfile, template | Voorkomt duplicaten bij heruitvoering |
| shell: yum install | package·dnf | Leest de huidige status en voert alleen de noodzakelijke wijzigingen uit |
| Elke keer opnieuw initialiseren met command | creates·removes of een specifieke module | Specificeer de voltooiingsvoorwaarden |
| Elke keer de service herstarten | Handler notify | Alleen herstarten wanneer de configuratie wijzigt |
| Alle fouten negeren | failed_when·block/rescue | Onderscheid maken tussen verwachte fouten en werkelijke mislukkingen |
Voltooiingsvoorwaarden opgeven in command
- name: Initialize application database once
ansible.builtin.command:
argv:
- /usr/local/bin/myapp-init
- --database
- /var/lib/myapp/app.db
creates: /var/lib/myapp/.initialized
register: init_result
# Laat de command-module de status skipped/changed rapporteren op basis van creates.
De parameter creates zorgt ervoor dat het command niet wordt uitgevoerd als het opgegeven pad bestaat. Controleer of het initialisatieprogramma daadwerkelijk een marker aanmaakt nadat het succesvol is voltooid. Als changed_when onvoorwaardelijk op false wordt gezet, worden de wijziging en de Handler-trigger verborgen; baseer dit daarom op de exit-code en de output van het commando.
Ansible Playbook Vault en het beveiligen van geheimen
Ansible Vault versleutelt variabelen en bestanden om platte tekst-geheimen in de repository te verminderen. Zoals de officiële documentatie echter benadrukt, beschermt Vault alleen gegevens in rust. Ontsleutelde waarden tijdens uitvoering kunnen verschijnen in module-argumenten, diffs, debug-output en foutmeldingen, waardoor no_log, beperkingen op diffs en toegangscontrole voor logs noodzakelijk zijn.
Tekstreeksen versleutelen via terminalinvoer
read -rsp 'Secret value: ' SECRET_VALUE
echo
printf '%s' "$SECRET_VALUE" | ansible-vault encrypt_string --vault-id prod@prompt --stdin-name 'db_password' > inventories/prod/group_vars/all/vault.yml
unset SECRET_VALUE
chmod 0600 inventories/prod/group_vars/all/vault.yml
Uitvoeren met Vault ID
ansible-playbook -i inventories/prod/hosts.yml playbooks/web.yml --vault-id prod@prompt --check --limit prod-web-01
# YAML-variabelen met !vault worden ontsleuteld wanneer het playbook met --vault-id wordt uitgevoerd.
Gevoelige Task-output blokkeren
- name: Render application secret configuration
ansible.builtin.template:
src: app-secret.conf.j2
dest: /etc/myapp/secret.conf
owner: root
group: root
mode: '0600'
no_log: true
diff: false
no_log beperkt de output van de betreffende Task, maar vormt geen beveiligingsgrens die bescherming biedt tegen kwaadaardige code, afzonderlijke debug-taken of logs van het doelsysteem. Gebruik indien mogelijk externe secret managers en credentials met een korte levensduur, en sla Vault-wachtwoordbestanden niet op in Git.
Ansible Playbook rolling deployment
Voer na een nieuwe implementatie van de service eerst de herstart uit die via meta: flush_handlers is gemeld en voer daarna een healthcheck uit. Om een bestaande versie te upgraden, specificeert u de goedgekeurde versie in de pakketnaam of geeft u myapp_package_state op als latest in het wijzigingsvenster. present voert geen automatische upgrades uit voor reeds geïnstalleerde pakketten.
Wijzig niet de gehele productieomgeving tegelijk, maar beperk de batchgrootte met serial. max_fail_percentage stopt het proces wanneer het percentage mislukkingen in de huidige batch de ingestelde waarde overschrijdt. Om te stoppen bij 1 mislukking van de 2, moet u rekening houden met de overschrijdingsvoorwaarde, bijvoorbeeld door 49 in plaats van 50 te gebruiken.
---
- name: Roll out application safely
hosts: web
become: true
serial: 2
max_fail_percentage: 49
pre_tasks:
- name: Confirm target batch
ansible.builtin.debug:
msg: "Deploying to {{ ansible_play_batch }}"
tasks:
- name: Deploy application package
ansible.builtin.package:
name: myapp
state: "{{ myapp_package_state | default('present') }}"
notify: Restart MyApp
- name: Restart changed services before checking health
ansible.builtin.meta: flush_handlers
- name: Verify local health endpoint
ansible.builtin.uri:
url: http://127.0.0.1:8080/healthz
status_code: 200
return_content: false
register: health
retries: 10
delay: 3
until: health.status == 200
handlers:
- name: Restart MyApp
ansible.builtin.service:
name: myapp
state: restarted
Dit voorbeeld is minimaal en dient enkel om de structuur te verduidelijken. In een echte load balancer-omgeving moet elke host in de batch uit het verkeer worden gehaald, moet worden gewacht tot de verbindingen zijn verbroken, en moet daarna de implementatie, healthcheck en herregistratie plaatsvinden. Controleer bij het gebruik van delegate_to en API-modules ook de certificaatvalidatie, foutafhandeling en de veiligheid van heruitvoering.
Ansible Playbook foutafhandeling en herstel
block past algemene become, when, enz. toe op gerelateerde taken en drukt de foutstroom uit met rescue en always. Als rescue slaagt, wordt de oorspronkelijke fout als hersteld beschouwd en kan de Play doorgaan. Syntaxfouten en onbereikbare hosts worden niet door rescue afgehandeld, dus zijn een beleid voor verbindingsfouten en monitoring afzonderlijk vereist.
- name: Back up current configuration
ansible.builtin.copy:
src: /etc/myapp/myapp.conf
dest: /var/backups/myapp.conf.pre-ansible
remote_src: true
owner: root
group: root
mode: '0600'
- name: Update service configuration with recovery
block:
- name: Render candidate configuration
ansible.builtin.template:
src: myapp.conf.j2
dest: /etc/myapp/myapp.conf
owner: root
group: root
mode: '0640'
validate: '/usr/local/bin/myapp --check-config %s'
notify: Restart MyApp
rescue:
- name: Restore previous configuration
ansible.builtin.copy:
src: /var/backups/myapp.conf.pre-ansible
dest: /etc/myapp/myapp.conf
remote_src: true
owner: root
group: root
mode: '0640'
- name: Stop this host after recovery
ansible.builtin.fail:
msg: Configuration deployment failed and was restored
always:
- name: Record completion state
ansible.builtin.debug:
msg: "Configuration block finished for {{ inventory_hostname }}"
Ga er niet vanuit dat u met slechts één herstelbestand zowel de applicatie als het databaseschema kunt terugdraaien. Maak een apart runbook dat verificatie voor en na de implementatie, de mogelijkheid tot pakket-rollback, gegevenswijzigingen en het uitvoeringsmoment van de Handler bevat.
Ansible Playbook kwaliteitscontrole en uitvoeringsvolgorde
- Leg de versies van ansible-core, Python, collecties en de toe te passen Git-commit vast.
- Controleer doelen, variabelen en groepen met inventory –graph en –list.
- Laat ansible-lint en –syntax-check slagen.
- Voer –check –diff uit op een enkele host in de ontwikkelomgeving.
- Controleer de reikwijdte van gevoelige diffs en no_log.
- Voer na uitvoering op een enkele host een healthcheck uit en controleer of changed=0 bij heruitvoering.
- Test de procedures voor het stoppen bij fouten en herstel met een kleine serial-batch in de stage-omgeving.
- Implementeer in productie (prod) tijdens het goedgekeurde wijzigingsvenster en bewaar recap, applicatiestatistieken en logs.
ansible-config dump --only-changed
ansible-inventory -i inventories/prod/hosts.yml --graph
ansible-lint playbooks roles
ansible-playbook -i inventories/prod/hosts.yml playbooks/web.yml --syntax-check
ansible-playbook -i inventories/prod/hosts.yml playbooks/web.yml --check --diff --limit prod-web-01 --vault-id prod@prompt
Checklist voor het beheer van Ansible-playbooks
- De bronnen voor dev-, stage- en prod-inventory en de schrijfrechten zijn gescheiden.
- SSH-hostkeyverificatie is behouden en de rechten voor het automatiseringsaccount en sudo zijn geminimaliseerd.
- Elke taak gebruikt een naam en FQCN, en command- en shell-modules bevatten voorwaarden voor voltooiing en wijziging.
- Configuratiewijzigingen worden gevalideerd met validate en handlers, waarbij bij heruitvoering wordt gecontroleerd of changed=0 is.
- Vault, no_log, diff-beperkingen en toegangscontrole voor logbestanden zijn gezamenlijk toegepast.
- De scope wordt stapsgewijs uitgebreid: van syntax, lint, check, diff en een enkele host naar kleine serial-batches.
- Er zijn procedures voor onbereikbaarheid, syntaxfouten die niet door block/rescue kunnen worden afgehandeld, en het terugdraaien van gegevens.
- De uitgevoerde commit, inventory, limit, uitvoerder, recap en post-validatie worden vastgelegd in het wijzigingslogboek.
Officiële Ansible-playbookdocumentatie en gerelateerde artikelen
- Officiële Ansible-inventorygids
- Officiële documentatie voor check mode en diff mode
- Officiële Ansible Handler-documentatie
- Officiële documentatie voor block, rescue en always
- Officiële Ansible Vault-documentatie
- Officiële ansible-lint-documentatie
- Gids voor het maken en beheren van Python venv
Conclusie
Ansible-playbooks: Veilige automatisering draait niet om het verzamelen van zoveel mogelijk commando’s, maar om het in code uitdrukken van de gewenste status, wijzigingsvoorwaarden, foutgrenzen en validatievolgordes. Scheid de inventory per omgeving, creëer idempotentie met FQCN-specifieke modules en handlers, en begrijp de beschermingsomvang van Vault nauwkeurig. Alleen automatisering die de tests voor syntax, lint, check, diff, enkele host, serial-batches en herstelprocedures heeft doorstaan, mag worden uitgerold naar productie.