Quando si tratta di gestire infrastrutture IT complesse, l’automazione è la chiave per mantenere l’efficienza, ridurre gli errori umani e garantire la coerenza tra i sistemi. In un ambiente con centinaia di server, come quello che gestisco per un cliente enterprise con 2.000 workstation e oltre 300 VM, la scelta dello strumento di automazione non è mai banale. La decisione tra adottare un framework consolidato come Ansible o affidarsi a script bash/Python custom può avere un impatto significativo sulla produttività del team, sulla stabilità dell’infrastruttura e, in ultima analisi, sui costi operativi. La mia esperienza mi ha portato a testare entrambi gli approcci su larga scala, valutando non solo la velocità di esecuzione, ma anche la manutenibilità, la scalabilità e la resilienza.
Testato su: Ubuntu 22.04 LTS · Ansible 2.15 · Python 3.10 · Agosto 2026
Contesto del Test
Il test è stato condotto su un ambiente di 200 server virtuali, replicando un setup tipico di un’infrastruttura di medie-grandi dimensioni. Tutti i server erano basati su Ubuntu Server 22.04 LTS. Gli obiettivi principali erano: aggiornare i pacchetti di sistema, distribuire un file di configurazione Nginx e riavviare il servizio, e infine verificare lo stato di un servizio critico. Per ogni task, ho misurato il tempo di esecuzione medio, la percentuale di successo e la facilità di debugging in caso di fallimento. I risultati, come vedremo, hanno evidenziato punti di forza e debolezza di entrambi gli approcci, fornendo spunti preziosi per la definizione di una strategia di automazione efficace.
Prerequisiti / Ambiente di test
Per replicare il test, è necessario avere accesso a un ambiente con almeno 200 host Linux. Nel mio caso, ho utilizzato Proxmox per creare rapidamente le VM, ma qualsiasi hypervisor o provider cloud sarebbe adatto. È fondamentale che tutti gli host siano raggiungibili via SSH e che sia configurato l’accesso senza password tramite chiavi SSH. Leggi anche: SSH Senza Password Linux: Configurare le Chiavi in 5 Minuti (2026)
Per Ansible, è necessario installare il pacchetto ansible sul controller e configurare un file di inventario. Per gli script, è sufficiente che Python 3 e Bash siano presenti sugli host (generalmente preinstallati su Linux).
# Installazione Ansible sul controller
sudo apt update
sudo apt install ansible -y
# Esempio di inventario Ansible (hosts.ini)
[webservers]
web[001:200] ansible_host=192.168.1.{{ (ansible_loop.index | int) + 100 }}
1. Ansible: l’approccio dichiarativo e idempotente
Ansible si basa su playbook scritti in YAML, che descrivono lo stato desiderato dei sistemi. La sua forza risiede nell’idempotenza: puoi eseguire un playbook più volte e il sistema raggiungerà lo stesso stato finale senza effetti collaterali indesiderati. Questo semplifica enormemente la gestione delle configurazioni e la risoluzione dei problemi.
Ecco un esempio del playbook utilizzato per i test:
---
- name: Gestione server con Ansible
hosts: webservers
become: yes
gather_facts: no
tasks:
- name: Aggiorna pacchetti di sistema
ansible.builtin.apt:
update_cache: yes
upgrade: dist
register: apt_update_result
- name: Debug apt update result
ansible.builtin.debug:
var: apt_update_result
when: apt_update_result.changed or apt_update_result.failed
- name: Distribuisci configurazione Nginx
ansible.builtin.copy:
src: files/nginx.conf
dest: /etc/nginx/nginx.conf
mode: '0644'
notify: Riavvia Nginx
- name: Verifica stato servizio Nginx
ansible.builtin.service_facts:
- name: Assicurati che Nginx sia in esecuzione e abilitato
ansible.builtin.service:
name: nginx
state: started
enabled: yes
handlers:
- name: Riavvia Nginx
ansible.builtin.service:
name: nginx
state: restarted
L’esecuzione di questo playbook è semplice:
ansible-playbook -i hosts.ini playbook.yml
Durante i test, Ansible ha gestito l’aggiornamento dei 200 server in circa 15-20 minuti, a seconda del carico di rete e del numero di pacchetti da aggiornare. La distribuzione del file di configurazione e il riavvio di Nginx sono stati quasi istantanei. Il vantaggio principale è stata la chiarezza del log di output e la facilità di identificare eventuali host problematici. Leggi anche: Kubernetes Produzione: Il Primo Deploy, Errori e Soluzioni (2026)
2. Script Custom: flessibilità e controllo granulare
Gli script Bash o Python offrono un controllo granulare su ogni singola operazione. Sono ideali per task molto specifici o per logiche complesse che non si adattano facilmente ai moduli Ansible esistenti. Tuttavia, la creazione di script robusti che gestiscano errori, idempotenza e logging richiede uno sforzo di sviluppo e test significativamente maggiore. Per il nostro test, ho creato uno script Python che si connette via SSH a ciascun server e esegue i comandi necessari.
# script_custom.py
import subprocess
import paramiko
import concurrent.futures
import time
hosts = [f'192.168.1.{i}' for i in range(101, 301)] # Esempio di 200 IP
SSH_USER = 'your_ssh_user'
def run_command_on_host(host, command):
try:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect(host, username=SSH_USER, timeout=10)
stdin, stdout, stderr = client.exec_command(command, get_pty=True)
output = stdout.read().decode().strip()
error = stderr.read().decode().strip()
client.close()
return host, 'SUCCESS', output, error
except Exception as e:
return host, 'FAILED', '', str(e)
def main():
print("Avvio script custom per 200 server...")
start_time = time.time()
commands_to_run = [
"sudo apt update && sudo apt upgrade -y",
"echo 'server { listen 80; root /var/www/html; index index.html; }' | sudo tee /etc/nginx/nginx.conf > /dev/null",
"sudo systemctl restart nginx",
"sudo systemctl is-active nginx"
]
with concurrent.futures.ThreadPoolExecutor(max_workers=50) as executor:
future_to_host = {
executor.submit(run_command_on_host, host, cmd): (host, cmd)
for host in hosts for cmd in commands_to_run
}
for future in concurrent.futures.as_completed(future_to_host):
host, cmd = future_to_host[future]
try:
result_host, status, output, error = future.result()
if status == 'SUCCESS':
print(f"[{result_host}] {cmd} -> {status}")
else:
print(f"[{result_host}] {cmd} -> {status}: {error}")
except Exception as exc:
print(f"[{host}] Generato un'eccezione: {exc}")
end_time = time.time()
print(f"Script completato in {end_time - start_time:.2f} secondi.")
if __name__ == '__main__':
main()
L’esecuzione di questo script, anche con ThreadPoolExecutor per la parallelizzazione, ha richiesto un tempo simile o leggermente superiore ad Ansible per l’aggiornamento dei pacchetti (circa 20-25 minuti). La gestione della configurazione e del riavvio di Nginx è stata rapida, ma il logging e la gestione degli errori erano molto più rudimentali rispetto ad Ansible. Qualsiasi errore su un singolo host richiedeva un’analisi manuale del log dello script, senza il contesto ricco fornito da Ansible.
Errori comuni e troubleshooting
Ansible:
- Problemi di connessione SSH: Spesso dovuti a chiavi SSH non configurate correttamente o a firewall che bloccano la porta 22. Verificare la connettività manuale
ssh user@hoste i log di Ansible per messaggi specifici (unreachable). - Idempotenza non rispettata: Se un modulo non è idempotente (o se un comando
shell/commandviene usato in modo improprio), si possono avere effetti collaterali. Assicurarsi di usare moduli specifici quando disponibili. - Performance lente:
gather_facts: noè essenziale su grandi inventari. Utilizzareforksadeguati nel fileansible.cfgper parallelizzare le operazioni.
Script Custom:
- Gestione degli errori: Ignorare i codici di uscita dei comandi (
$?in Bash) può portare a errori non rilevati. Ogni comando deve essere controllato. - Idempotenza: Deve essere implementata manualmente, ad esempio verificando l’esistenza di un file prima di copiarlo, o controllando lo stato di un servizio prima di riavviarlo.
- Parallelizzazione: Senza una corretta gestione dei thread/processi, gli script possono essere molto lenti su molti host. Paramiko, se non gestito con un pool di connessioni, può essere inefficiente. Leggi anche: Ansible Windows: Gestire Server Windows con WinRM e Moduli Core (2026)
FAQ — Domande Frequenti
Qual è l’impatto delle performance di rete?
Le performance di rete sono un fattore critico per entrambi gli approcci. Un collo di bottiglia sulla rete può rallentare significativamente l’esecuzione, specialmente durante l’aggiornamento di pacchetti o la distribuzione di file di grandi dimensioni. È essenziale che il controller Ansible o il server che esegue lo script abbia una connettività adeguata a tutti i 200 host.
Ansible è sempre più lento degli script Python?
Non necessariamente. Sebbene ci sia un overhead iniziale per l’interpretazione dei playbook e la gestione dell’inventario, Ansible è altamente ottimizzato per la parallelizzazione e l’uso efficiente dei moduli. Per task complessi e ben definiti, Ansible può essere più veloce perché i suoi moduli sono spesso scritti in Python ottimizzato o richiamano binari efficienti. Gli script custom, se non scritti con attenzione alla parallelizzazione e all’efficienza, possono essere più lenti.
Posso combinare i due approcci?
Assolutamente sì. Un approccio ibrido è spesso il più efficace. Puoi usare Ansible per la gestione generale delle configurazioni e l’orchestrazione, e richiamare script custom (Bash o Python) tramite il modulo ansible.builtin.script o ansible.builtin.command per task molto specifici o complessi che richiedono una logica particolare non facilmente esprimibile in YAML. Questo ti permette di sfruttare i punti di forza di entrambi gli strumenti. Leggi anche: Ansible: Eseguire Script Remoti con il Modulo Command
Come gestisco le credenziali in modo sicuro con entrambi?
Per Ansible, si consiglia vivamente di usare Ansible Vault per cifrare i dati sensibili come password o chiavi API. Per gli script Python, è buona pratica utilizzare variabili d’ambiente, un gestore di segreti come HashiCorp Vault, o un sistema di gestione delle configurazioni che inietti le credenziali in modo sicuro all’avvio dello script, evitando di hardcodarle nel codice.
Conclusioni con takeaway operativi
Il confronto tra Ansible e script custom su 200 server ha chiarito che entrambi hanno il loro posto in una strategia di automazione. Ansible eccelle nella manutenibilità, nell’idempotenza e nella gestione di configurazioni complesse su larga scala, offrendo un’esperienza di debugging superiore. Gli script custom, d’altra parte, forniscono la massima flessibilità e sono insostituibili per logiche altamente specifiche o per l’integrazione con sistemi non standardizzati. La mia raccomandazione operativa è di adottare un approccio ibrido: utilizzare Ansible come framework principale per la maggior parte delle operazioni di gestione e deploy, e riservare gli script Python per i casi eccezionali che richiedono un controllo più granulare o logiche di business complesse. L’importante è investire tempo nell’ottimizzazione e nel testing, indipendentemente dallo strumento scelto, per garantire che l’automazione sia un asset e non una fonte di nuovi problemi.
Fonti
Aggiornato: Agosto 2026