1 26/10/2026 12 min

Su Ubuntu 20.04 LTS Ansible si installa in pochi minuti, ma il punto vero non è “avere il pacchetto”: è impostare subito un flusso che resti leggibile, ripetibile e facile da verificare. In pratica, conviene separare tre cose: il controller da cui lanci Ansible, gli host gestiti, e la struttura dei file con cui descrivi inventario, variabili e playbook.

In questa guida parto da un’installazione pulita su Ubuntu 20.04 LTS e arrivo a un primo playbook utile, con controllo della connessione, inventario statico, variabili essenziali e un esempio concreto di configurazione. L’obiettivo non è solo “farlo partire”, ma evitare i classici errori che poi fanno perdere tempo: SSH non coerente, chiavi non distribuite, host key che bloccano il primo accesso, privilege escalation impostata male e playbook scritti senza una struttura minima.

Prerequisiti reali prima di installare Ansible

Ansible non richiede un demone sul server remoto, ed è questo uno dei suoi vantaggi principali. Sul nodo di controllo ti serve però un ambiente pulito: Ubuntu 20.04 LTS aggiornato, accesso SSH verso gli host da gestire, e un utente con privilegi adeguati per eseguire le operazioni previste. Se devi amministrare più macchine, conviene anche avere una chiave SSH dedicata e non usare account condivisi.

Prima di installare, verifica che il sistema sia aggiornato e che Python 3 sia presente, perché Ansible su Ubuntu 20.04 si appoggia a Python per molte operazioni lato target. Il controllo minimo è questo:

sudo apt update
sudo apt -y upgrade
python3 --version
ssh -V

Se python3 --version restituisce una versione valida e ssh -V mostra il client OpenSSH, sei già nella condizione giusta per procedere.

Installazione di Ansible su Ubuntu 20.04 LTS

Su Ubuntu 20.04 hai due strade sensate: il pacchetto dei repository ufficiali e, se ti serve una versione più aggiornata, il PPA dedicato. Per la maggior parte dei casi operativi il pacchetto standard è sufficiente; per ambienti dove vuoi una release più recente, il PPA di Ansible è una scelta comune. Il criterio pratico è semplice: se non hai un’esigenza specifica, parti dal repository ufficiale; meno variabili, meno attrito.

Installazione dai repository Ubuntu

Questa è la via più lineare:

sudo apt update
sudo apt install -y ansible

Controlla subito la versione installata:

ansible --version

Nel risultato dovresti vedere la versione di Ansible, il percorso dell’eseguibile e la directory di configurazione. Se il comando non viene trovato, il problema è quasi sempre legato a un’installazione incompleta o a un PATH non aggiornato, anche se in un caso normale non dovrebbe succedere.

Installazione con PPA per una versione più recente

Se ti serve una release più aggiornata rispetto a quella presente nei repository standard, puoi usare il PPA ufficiale. È una scelta utile quando lavori con moduli o comportamenti introdotti in versioni più nuove, ma va fatta con cognizione perché aggiungi una sorgente software esterna al sistema.

sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install -y ansible

Dopo l’installazione, verifica di nuovo con ansible --version. Se vuoi evitare sorprese in ambienti condivisi, annota anche da quale repository proviene il pacchetto con apt policy ansible.

Struttura minima di lavoro: inventario, configurazione e directory

Puoi usare Ansible in modo “al volo” con un inventario passato da riga di comando, ma appena superi una manciata di host conviene organizzare il progetto. La struttura minima che funziona bene è questa: una directory per il progetto, un file ansible.cfg, un inventario, una cartella per i playbook e una per le variabili. Ti evita di spargere file casuali nella home e rende più semplice passare il lavoro a un collega.

mkdir -p ~/ansible-lab/{inventory,playbooks,group_vars,host_vars}
cd ~/ansible-lab

Un file ansible.cfg essenziale può essere questo:

[defaults]
inventory = ./inventory/hosts.ini
host_key_checking = True
stdout_callback = yaml
retry_files_enabled = False
interpreter_python = auto_silent

Con host_key_checking = True mantieni un comportamento più sicuro, soprattutto se gestisci server reali e non un laboratorio temporaneo. Se invece stai facendo test iniziali su macchine effimere, potresti temporaneamente disabilitarlo, ma in produzione è meglio lasciarlo attivo.

Inventario statico: il primo punto da fare bene

L’inventario dice ad Ansible quali host gestire e con quali parametri. Per iniziare, un inventario statico in formato INI è semplice e trasparente. Ecco un esempio con due server e un gruppo dedicato ai web server:

[web]
web01 ansible_host=192.0.2.10 ansible_user=deploy
web02 ansible_host=192.0.2.11 ansible_user=deploy [db]
db01 ansible_host=192.0.2.20 ansible_user=deploy

La variabile ansible_host serve quando il nome logico dell’host non coincide con l’indirizzo raggiungibile via SSH. ansible_user ti permette di fissare l’utente remoto senza doverlo ripetere ogni volta. Se usi una chiave privata specifica, puoi aggiungere anche ansible_ssh_private_key_file, ma è meglio farlo solo se serve davvero.

Per controllare che l’inventario sia leggibile, usa:

ansible-inventory -i inventory/hosts.ini --graph

Se il comando restituisce la gerarchia dei gruppi, l’inventario è valido. Se invece hai errori di parsing, il problema è quasi sempre un errore di sintassi, un carattere fuori posto o una sezione scritta male.

Connessione SSH e accesso senza password

Ansible non vuole password salvate nel codice. Il flusso corretto è usare una chiave SSH e, se serve, sudo sul target con una configurazione controllata. Il primo passo è copiare la chiave pubblica sul server remoto con un account autorizzato:

ssh-keygen -t ed25519 -C "ansible@lab"
ssh-copy-id deploy@192.0.2.10

Se la porta SSH non è quella standard, specifica -p nel comando o imposta il parametro nel file inventario. Dopo la distribuzione della chiave, verifica che il login sia davvero senza password:

ssh deploy@192.0.2.10

Se qui ti viene ancora chiesta la password, non ha senso andare avanti con Ansible: prima risolvi il livello SSH. Il problema può essere un permesso errato sulla home dell’utente remoto, una chiave non accettata o una configurazione server che limita l’accesso.

Test di connettività con ansible ad-hoc

Prima di scrivere playbook, fai un test ad-hoc. È il modo più rapido per capire se Ansible vede davvero gli host e se l’esecuzione remota funziona. Il modulo ping non testa ICMP: verifica solo che Ansible riesca a connettersi e a eseguire Python sul target.

ansible all -i inventory/hosts.ini -m ping

Se tutto è corretto, l’output atteso è qualcosa del tipo SUCCESS con un risultato pong. Se ricevi UNREACHABLE, il problema è quasi sempre SSH, DNS, routing o credenziali. Se ricevi un errore Python, può mancare l’interprete o esserci un problema di compatibilità lato host.

Puoi anche verificare un comando semplice, ad esempio il nome dell’host remoto:

ansible web -i inventory/hosts.ini -m command -a "hostname"

In una fase iniziale questo è più utile di una playbook complesso, perché separa i problemi di trasporto da quelli di logica applicativa.

Primo playbook: aggiornare i pacchetti in modo controllato

Un primo playbook sensato deve fare una cosa concreta e sicura. Aggiornare la cache APT e portare il sistema allo stato desiderato è un buon esercizio, purché tu sappia che in produzione può avere impatti indiretti se i pacchetti cambiano versione. Per questo, meglio eseguire prima in un gruppo limitato di host o in finestra di manutenzione.

---
- name: Aggiorna i pacchetti su Ubuntu hosts: web become: true tasks: - name: Aggiorna cache APT ansible.builtin.apt: update_cache: true cache_valid_time: 3600 - name: Installa aggiornamenti disponibili ansible.builtin.apt: upgrade: dist

Salva il file come playbooks/update.yml e lancialo con:

ansible-playbook -i inventory/hosts.ini playbooks/update.yml

Il parametro become: true indica che Ansible deve elevare i privilegi, tipicamente via sudo. Se l’utente remoto non è autorizzato, il playbook fallirà con errore di escalation. In quel caso la correzione non è “forzare Ansible”, ma sistemare i privilegi sul target in modo controllato.

Gestire i privilegi con sudo senza aprire troppo

Per usare become in modo pulito, l’utente remoto dovrebbe avere i permessi minimi necessari. Evita account troppo potenti se non servono. Se il playbook deve installare pacchetti o modificare servizi, basta spesso una regola sudo mirata e non un accesso amministrativo totale.

Un controllo utile è verificare se il comando sudo funziona senza interventi interattivi, almeno per le operazioni previste. In molti ambienti si usa ansible_become_password, ma è meglio non inserirla in chiaro nel repository. Se devi gestire segreti, usa un vault Ansible oppure un sistema di secret management esterno.

Per un test rapido, puoi chiedere ad Ansible di eseguire whoami con escalation:

ansible web -i inventory/hosts.ini -b -m command -a "whoami"

Se tutto è corretto, il risultato deve essere root. Se ottieni un errore di sudo, controlla la configurazione dell’utente remoto prima di cambiare il playbook.

Variabili di gruppo e separazione per ambiente

Appena il progetto cresce, le variabili diventano il vero punto di ordine. Ansible legge variabili da group_vars e host_vars, permettendoti di differenziare comportamento e valori senza duplicare i playbook. È qui che conviene tenere parametri come nomi di pacchetti, directory, porte, endpoint e flag di configurazione.

Per esempio, puoi creare group_vars/web.yml con un valore comune ai web server:

nginx_worker_processes: auto
app_port: 8080

In un file host-specifico come host_vars/web01.yml puoi sovrascrivere solo ciò che cambia davvero. Questa separazione riduce gli errori e rende più facile capire perché due host si comportano in modo diverso.

Template Jinja2 per configurazioni ripetitive

Uno degli usi migliori di Ansible è generare file di configurazione a partire da template. Il vantaggio non è solo evitare copia e incolla: è mantenere una singola fonte di verità per i parametri. Un template Jinja2 ti consente di inserire variabili in un file di configurazione in modo pulito.

Ad esempio, per un file di configurazione Nginx puoi creare templates/site.conf.j2:

server { listen {{ app_port }}; server_name {{ server_name }}; location / { proxy_pass http://127.0.0.1:{{ app_port }}; }
}

Nel playbook, il template si distribuisce con il modulo template e poi, se necessario, si riavvia il servizio solo quando il file cambia. È una logica importante: non riavviare sempre, riavviare solo quando serve.

---
- name: Distribuisce la configurazione hosts: web become: true tasks: - name: Copia il template Nginx ansible.builtin.template: src: templates/site.conf.j2 dest: /etc/nginx/sites-available/site.conf mode: '0644' notify: Riavvia Nginx handlers: - name: Riavvia Nginx ansible.builtin.service: name: nginx state: restarted

Qui il comportamento è corretto perché il riavvio è condizionato da una modifica reale. Se il file non cambia, il handler non parte.

Controllo sintattico e modalità di prova

Prima di lanciare un playbook su host reali, usa il check mode quando possibile. Non copre tutto, ma aiuta a intercettare errori grossolani di sintassi e di logica. In parallelo, puoi fare un diff per vedere quali file cambierebbero.

ansible-playbook -i inventory/hosts.ini playbooks/update.yml --check --diff

Se un modulo non supporta pienamente il check mode, lo segnala. È un limite normale: non bisogna scambiarlo per un’esecuzione reale. Però, come filtro iniziale, è molto utile. In ambienti delicati, conviene affiancarlo a un inventario ristretto o a un gruppo di test.

Vault per segreti e dati sensibili

Credenziali, token e password non vanno lasciati in chiaro nei file del progetto. Ansible Vault è la soluzione nativa per cifrare dati sensibili, soprattutto quando devi versionare playbook e variabili in un repository condiviso. Non è il sistema perfetto per ogni caso, ma è molto meglio del testo in chiaro.

Un file cifrato si crea con:

ansible-vault create group_vars/all/vault.yml

Per modificarlo:

ansible-vault edit group_vars/all/vault.yml

E per eseguire un playbook che usa quel file:

ansible-playbook -i inventory/hosts.ini playbooks/update.yml --ask-vault-pass

Se lavori in team, valuta un vault password file gestito con attenzione, ma solo se hai davvero un controllo adeguato sul suo ciclo di vita. Il punto è non lasciare mai segreti leggibili da chiunque abbia accesso al repository.

Problemi comuni e come leggerli senza perdere tempo

Quando Ansible fallisce, conviene leggere il messaggio dal basso verso l’alto, partendo dall’errore finale e risalendo alla causa. Alcuni casi tipici ricorrono spesso:

  • Host unreachable: quasi sempre SSH, rete, DNS o chiave non accettata.
  • Permission denied: utente remoto errato, chiave sbagliata, o sudo non configurato.
  • Python interpreter not found: host minimale, interprete mancante o path non previsto.
  • Template o file non trovati: path relativi errati nel progetto.

Un buon controllo operativo è eseguire sempre un test ad-hoc prima di un playbook importante. Se ansible all -m ping non funziona, il playbook non è il problema: il problema è il trasporto o la base d’esecuzione.

Quando conviene usare Ansible e quando no

Ansible è molto adatto a configurazione, provisioning leggero, distribuzione di file, orchestration semplice e attività ripetitive su più host. È meno adatto, invece, a processi molto stateful o a trasformazioni che richiedono un motore di convergenza continuo e sofisticato. In altre parole: se devi descrivere lo stato desiderato di server e servizi, è un buon strumento; se devi fare automazione interattiva o logiche molto complesse, va valutato con attenzione.

Il suo punto forte resta la leggibilità operativa: un playbook ben scritto si legge quasi come una procedura. Il suo punto debole, se lo si usa male, è l’accumulo di eccezioni e variabili sparpagliate. Per questo la disciplina iniziale conta più della quantità di moduli usati.

Setup consigliato per iniziare senza complicarsi la vita

Se vuoi una base solida, il setup minimo che consiglio è questo: Ansible installato dai repository o da PPA solo se serve, chiave SSH dedicata, inventario statico pulito, ansible.cfg nel progetto, variabili separate per gruppo, e un primo playbook che faccia una sola cosa. Da lì puoi crescere senza dover rifare tutto.

In pratica: prima fai parlare il controller con gli host, poi standardizzi le variabili, poi introduci template e handler, infine aggiungi vault e struttura per ambienti diversi. Questo ordine riduce gli errori e ti evita di costruire automazione sopra fondamenta fragili.

Assunzioni: Ubuntu 20.04 LTS sul nodo di controllo, accesso SSH funzionante verso gli host target, e privilegi sudo disponibili solo dove necessari.