10 KiB
Playbook
Un playbook Ansible è un file testuale, scritto in formato YAML, che definisce una sequenza di operazioni (task) da eseguire su uno o più nodi.
Un playbook può contenere uno o più Play. Ogni Play è composto da una serie di task, che a loro volta possono richiamare uno o più moduli.
Struttura di un playbook
Di seguito è riportato un esempio di playbook:
---
- name: install and start httpd
hosts: databases
tasks:
- name: install httpd
apt:
name: httpd
state: latest
become: true
- name: start httpd
service:
name: httpd
state: started
become: true
name: specifica il nome del play, che descrive l'azione da eseguirehosts: indica i nodi sui quali il play sarà eseguitotasks: contiene un elenco di operazioni da eseguire
In questo esempio:
- il playbook contiene un unico play
- il play ha il compito di installare e avviare il servizio httpd su un gruppo di host denominato databases
- sono definiti due task: il primo installa il pacchetto httpd tramite il modulo apt, mentre il secondo avvia il servizio httpd utilizzando il modulo service
- l’opzione
become: trueindica che i task devono essere eseguite con privilegi elevati, tipicamente utilizzando sudo
Un esempio di playbook con due play:
---
- name: install and start apache
hosts: webservers
tasks:
- name: install apache
apt:
name: apache2
state: latest
become: true
- name: start apache
service:
name: apache2
state: started
become: true
- name: install and start mysql
hosts: databases
tasks:
- name: install mysql
apt:
name: mysql-server
state: latest
become: true
- name: start mysql
service:
name: mysql
state: started
become: true
Esecuzione di un playbook
Per eseguire un playbook, è necessario utilizzare il comando ansible-playbook, specificando:
- l’inventory file, se custom, con l'opzione
-i - il percorso del playbook
- eventuali opzioni aggiuntive, come
-ask-vault-pass, che richiede la password per decifrare i file crittografati conansible-vault
ansible-playbook -i inventory playbook/my-playbook.yml -K --ask-vault-pass
Conditionals
Le istruzioni condizionali consentono di modificare il comportamento di un playbook in base a specifiche condizioni.
L'istruzione condizionale più semplice si applica a un singolo task, utilizzando la parola chiave when. In questo caso, il task verrà eseguito solo sui nodi in cui la condizione specificata è soddisfatta.
Tipologie di condizioni
Le condizioni possono basarsi su diversi tipi di dati:
ansible_facts: attributi specifici di ogni host, messi a disposizione da Ansible. Questi fanno riferimento a caratteristiche del nodo, come il tipo sistema operativo, le caratteristiche hardware e altre proprietà rilevanti. Sono utili per adattare il comportamento del playbook in base alle caratteristiche del nodo targetregistered variables: variabili che contengono il risultato di task precedenti. È possibile condizionare in questo modo l’esecuzione di un task in base all’esito di un task già eseguitovariabilidefinite nel playbook o nell'inventory
Un semplice esempio di condizione when:
---
- name: playbooks with conditions
hosts: db
become: true
tasks:
- name: install postgres
apt:
name: postgresql
state: latest
when: ansible_distribution == 'Ubuntu'
Un esempio di registered variables:
---
- name: Install and Start HTTPD Service
hosts: webservers
become: true
tasks:
- name: Install the httpd package
apt:
name: httpd
state: present
register: httpd_installation
- name: Start the httpd service
service:
name: httpd
state: started
when: httpd_installation.changed == true
Questo task utilizza il modulo apt per installare il pacchetto httpd. Durante l'esecuzione, il risultato dell'installazione viene registrato nella variabile httpd_installation. Avvia infine il servizio httpd, ma solo se l'installazione del pacchetto è stata completata con successo.
Loops
I loop in Ansible consentono di ripetere un task più volte all'interno di un playbook, evitando la necessità di riscrivere blocchi di codice che eseguono la stessa operazione.
I tre tipi principali di loop sono:
ListeListe di hashDizionari
Liste
Per i loop di liste, si utilizza la parola chiave loop, seguita da una lista di stringhe. Il task verrà eseguito tante volte quante sono le stringhe nella lista, e {{ item }}, nel task, assumerà il valore dell'elemento iesimo.
---
- name: playbook with loop
hosts: db
become: true
tasks:
- name: add users
user:
name: "{{ item }}"
loop:
- userOne
- userTwo
Liste di hash
Per i loop di liste di hash, si utilizza la medesima parola chiave loop, ma la lista contiene elementi chiavi: valore. In questo caso, si può accedere ai valori usando la sintassi {{ item.key }}.
---
- name: Playbook con loop su lista di hash
hosts: db
become: true
tasks:
- name: add users
user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
shell: "{{ item.shell }}"
loop:
- { name: 'userOne', uid: 1001, shell: '/bin/bash' }
- { name: 'userTwo', uid: 1002, shell: '/bin/zsh' }
Blocks
I blocchi in Ansible vengono impiegati per due finalità principali:
- raggruppare task correlati tra loro, in modo da applicare direttive comuni a un insieme di operazioni
- gestire gli errori che possono verificarsi durante l’esecuzione dei task, consentendo di definire azioni specifiche in caso di fallimento o di successo
Tutte le direttive associate a un blocco vengono automaticamente ereditate da tutti i task contenuti al suo interno.
I blocchi offrono due sezioni dedicate alla gestione degli errori:
rescue: contiene i task che vengono eseguiti immediatamente nel caso in cui almeno uno dei task all'interno del blocco generi un errorealways: contiene i task che vengono eseguiti indipendentemente dall’esito dei task nel blocco, sia in caso di successo che di fallimento
Un esempio di raggruppamento:
---
- name: block
hosts: db
tasks:
- block:
- name: list user
command: ls -l /usr/
- name: list root
command: ls -l /root/
- name: list bin
command: ls -l /bin/
- name: list home
command: ls -l ~/
become: yes
- name: list home
command: "ls -l ~/"
La direttiva become: yes è associata al blocco e viene applicata a tutti i task al suo interno, semplificando la gestione delle operazioni correlate.
Un esempio di gestione di errori:
---
- name: Error handling example
hosts: db
tasks:
- block:
- name: Execute a command that fail
command: /bin/false
rescue:
- name: Handle the error
debug:
msg: "The command failed, executing an alternative action."
always:
- name: Always execute this command
debug:
msg: "This action is executed regardless of the block's result."
In questo caso, il task nella sezione rescue viene eseguito solo se il comando /bin/false fallisce, mentre il task nella sezione always viene eseguito in ogni circostanza.
Handlers
Gli handler in Ansible consentono l'esecuzione condizionale di specifiche operazioni, attivate solo quando un task determina modifiche su un nodo target.
---
- name: playbook with handlers
hosts: db
become: true
tasks:
- name: install httpd
apt:
name: httpd
state: present
notify:
- Start httpd
handlers:
- name: Start httpd
service:
name: httpd
state: started
La parola chiave notify serve a richiamare l’handler specificato. Durante la prima esecuzione, una volta installato il software httpd, l’handler verrà attivato e avvierà il servizio. Nelle esecuzioni successive, qualora il pacchetto sia già presente e non subisca modifiche, il task non verrà eseguito e, di conseguenza, neppure l’handler associato verrà richiamato.
Per impostazione predefinita, gli handlers vengono eseguiti solo dopo che tutti i task del playbook sono stati completati. Questo significa che, anche se più task notificano lo stesso handler, quest’ultimo verrà eseguito una sola volta.
Tags
I tag consentono di contrassegnare specifici task, offrendo la possibilità di selezionare quali parti eseguire di un playbook.
Per aggiungere un tag a un task, è sufficiente utilizzare la direttiva tags seguita da un elenco di etichette. Ogni task può essere associato a uno o più tag, come illustrato nell’esempio seguente:
---
- name: playbook with tags
hosts: db
become: true
tasks:
- name: install httpd
apt:
name: httpd
state: present
tags:
- http
- name: install postgres
apt:
name: postgresql
state: present
tags:
- db
In questo esempio, ogni task è associato a un tag specifico, rispettivamente http e db. In questo modo, è possibile eseguire solo i task contrassegnati da un determinato tag.
Tag speciali
Ansible offre due tag speciali, always e never: un task contrassegnato con il tag always verrà sempre eseguito, indipendentemente dai tag specificati nella riga di comando. Al contrario, un task contrassegnato con il tag never non verrà mai eseguito, a meno che non venga esplicitamente richiesto tramite l’opzione --tags.
Esecuzione tramite riga di comando
Utilizzando l'opzione --tags, è possibile specificare i task da eseguire:
ansible-playbook playbook.yml --tags "http"
Questo comando eseguirà solo i task contrassegnati con il tag http.
Al contrario, per escludere task specifici dall'esecuzione, si utilizza l'opzione --skip-tags:
ansible-playbook playbook.yml --skip-tags "db"
Questo comando salterà l'esecuzione di tutti i task contrassegnati con il tag db.