Fullmoon System

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.

Ansible-playbookautomatisering: Inventory, control node, SSH, servergroepen, validatie en herstelstromen
Een workflow waarbij de inventory en declaratieve taken op de control node worden gevalideerd, waarna ze via SSH sequentieel op servers per omgeving worden toegepast en de resultaten worden gecontroleerd.

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

  1. Leg de versies van ansible-core, Python, collecties en de toe te passen Git-commit vast.
  2. Controleer doelen, variabelen en groepen met inventory –graph en –list.
  3. Laat ansible-lint en –syntax-check slagen.
  4. Voer –check –diff uit op een enkele host in de ontwikkelomgeving.
  5. Controleer de reikwijdte van gevoelige diffs en no_log.
  6. Voer na uitvoering op een enkele host een healthcheck uit en controleer of changed=0 bij heruitvoering.
  7. Test de procedures voor het stoppen bij fouten en herstel met een kleine serial-batch in de stage-omgeving.
  8. 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

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.