Trasferimento sicuro dei file: Utilizzo dei moduli Ansible Copy e Fetch

Utilizza i comandi ad-hoc Ansible copy e fetch per inviare file ai nodi gestiti e recuperare log o configurazioni sul nodo di controllo.

Trasferire File in Modo Sicuro: Utilizzare i Moduli Ansible Copy e Fetch

Spostare file è una delle prime attività pratiche di Ansible che devi affrontare: inviare una configurazione ai tuoi server, raccogliere un file di log o eseguire un backup di un file remoto prima di una modifica. I moduli copy e fetch gestiscono queste due direzioni in modo chiaro.

Questa guida utilizza comandi ad-hoc, così puoi eseguire trasferimenti una tantum senza scrivere un playbook completo. Gli stessi argomenti dei moduli funzionano anche nei playbook quando desideri che l'attività sia ripetibile.

Prerequisiti

Prima di eseguire gli esempi seguenti, assicurati di avere quanto segue:

  1. Nodo di Controllo Ansible: Una macchina con Ansible installato.
  2. File di Inventario: Un file di inventario funzionante (es. /etc/ansible/hosts) che definisce i tuoi nodi gestiti.
  3. Connettività: Accesso SSH configurato con chiave per i tuoi host remoti.

Tutti gli esempi presuppongono che il gruppo di destinazione sia denominato webservers nell'inventario.

Comprendere i Comandi Ad-Hoc per il Trasferimento di File

I comandi ad-hoc sono comandi a riga singola eseguiti direttamente dal terminale, ideali per attività rapide che non richiedono un playbook permanente. La struttura di base è:

ansible <gruppo-host> -m <nome-modulo> -a "chiave=valore chiave2=valore2 ..."

Per il trasferimento di file, utilizziamo i nomi dei moduli -m copy o -m fetch, passando gli argomenti richiesti tramite il flag -a.

Il Modulo copy: Inviare File ai Nodi Remoti

Il modulo copy viene utilizzato per trasferire un file situato sulla macchina di controllo Ansible a uno o più nodi gestiti. Questo è il metodo standard per distribuire file di configurazione, script o piccoli asset.

Argomenti Chiave per copy

Il modulo copy richiede due argomenti essenziali e ne accetta diversi opzionali per la gestione della configurazione:

Argomento Descrizione Obbligatorio? Esempio di Valore
src Il percorso del file locale sulla macchina di controllo Ansible. I percorsi assoluti sono più chiari per i comandi ad-hoc. /tmp/config.conf
dest Il percorso in cui verrà posizionato il file sul nodo gestito remoto. /etc/app/config.conf
owner Nome dell'utente che dovrebbe possedere il file sul nodo remoto. No nginx
group Nome del gruppo che dovrebbe possedere il file sul nodo remoto. No www-data
mode Permessi (ottali) da impostare sul file di destinazione. No 0644
backup Se yes, crea un file di backup prima di sovrascrivere l'originale. No yes

Esempio 1: Distribuzione Semplice di un File

Supponiamo di avere un file personalizzato Message of the Day (motd) localmente e di volerlo inviare a tutti i webserver.

# Percorso file locale: /home/utente/ansible/motd_banner
# Destinazione remota: /etc/motd

ansible webservers -m copy -a "src=/home/utente/ansible/motd_banner dest=/etc/motd"

Esempio 2: Impostazione di Permessi e Proprietà

Se stai distribuendo un file di configurazione sicuro, devi specificare il proprietario, il gruppo e i permessi ristretti (es. solo il proprietario può leggere/scrivere).

# Distribuzione di un file di configurazione dell'applicazione, di proprietà di 'app_user', gruppo 'devops',
# con permessi di lettura/scrittura solo per il proprietario (0600).

ansible webservers -m copy -b -a "src=/tmp/app_settings.yaml dest=/etc/app/settings.yaml owner=app_user group=devops mode=0600"

Nota su -b: Il flag -b (o --become) è necessario quando la destinazione remota richiede privilegi elevati (come scrivere in /etc).

Il Modulo fetch: Recuperare File dai Nodi Remoti

Il modulo fetch esegue l'operazione inversa di copy: recupera un file dal nodo gestito e lo riporta alla macchina di controllo Ansible. Questo è utile per eseguire il backup di file di configurazione, recuperare log o raccogliere informazioni diagnostiche.

Argomenti Chiave per fetch

Il modulo fetch richiede il file sorgente sul nodo remoto e una directory di destinazione sulla macchina di controllo.

Argomento Descrizione Obbligatorio? Esempio di Valore
src Il percorso assoluto del file sul nodo gestito remoto. /var/log/nginx/error.log
dest Il percorso assoluto della directory sulla macchina di controllo in cui verranno salvati i file. /tmp/backups/logs
flat Se yes, il nome del file risultante non conterrà la struttura del nome host (non consigliato quando si recuperano file da più host). No no (predefinito)

Differenza Critica: Struttura di Destinazione

A differenza del modulo copy, il modulo fetch crea automaticamente un percorso di sottodirectory strutturato basato sul nome host remoto per evitare collisioni di nomi di file quando si recuperano file da più server.

Il percorso risultante sulla macchina di controllo sarà simile a questo:

<dest>/<nomehost>/<src>

Ad esempio, recuperando /etc/nginx/nginx.conf da host1 a /tmp/backups risulta in:

/tmp/backups/host1/etc/nginx/nginx.conf

Esempio 3: Recuperare Backup di Configurazioni Remote

Per recuperare il file di configurazione in esecuzione da tutti i webserver in una directory di backup locale:

# Recupera nginx.conf da tutti i webserver nella directory locale /tmp/config_backups

ansible webservers -m fetch -a "src=/etc/nginx/nginx.conf dest=/tmp/config_backups"

Dopo aver eseguito questo comando, se hai preso di mira webserver1 e webserver2, la struttura della directory locale sarebbe:

/tmp/config_backups/
├── webserver1
│   └── etc
│       └── nginx
│           └── nginx.conf
└── webserver2
    └── etc
        └── nginx
            └── nginx.conf

Esempio 4: Recuperare un Singolo File Senza Struttura Host (flat=yes)

Se sei assolutamente sicuro di recuperare un file da un singolo host, o se hai bisogno solo del contenuto del file (non della struttura di origine), puoi usare flat=yes. Ciò comporta il posizionamento del file direttamente nella cartella di destinazione, con il nome del file remoto originale.

# Recupera un report sullo stato di salute locale da un singolo host, salvandolo direttamente.

ansible webserver1 -m fetch -a "src=/tmp/health_status.txt dest=/tmp/reports flat=yes"

# Percorso risultante: /tmp/reports/health_status.txt

Avvertenza: Usa flat=yes solo quando prendi di mira un singolo host o se intendi sovrascrivere il file nelle esecuzioni successive, poiché Ansible non impedirà conflitti.

Best Practice e Considerazioni sulla Sicurezza

Piccoli errori nel trasferimento di file possono diventare incidenti di produzione, specialmente quando i file finiscono in /etc o contengono segreti.

Imposta Sempre i Permessi con copy

Non inviare mai un file di configurazione senza definire esplicitamente mode e owner. Se ti affidi all'umask predefinito del sistema remoto, i file sensibili (come chiavi SSH o credenziali del database) potrebbero finire con diritti di accesso eccessivamente permissivi.

# Cattiva Pratica (Modalità derivata da umask)
- name: Distribuisci chiave non sicura
  ansible.builtin.copy:
    src: private.key
    dest: /etc/app/private.key

# Buona Pratica (Limita esplicitamente l'accesso)
- name: Distribuisci chiave sicura
  ansible.builtin.copy:
    src: private.key
    dest: /etc/app/private.key
    mode: '0600'
    owner: root

Usa backup=yes per Modifiche Critiche

Quando usi copy per sovrascrivere un file critico esistente (es. /etc/sudoers), includi backup=yes. Ansible creerà una copia di backup con timestamp sul nodo remoto prima di sovrascrivere il file, fornendo una facile opzione di rollback.

Considera synchronize per Trasferimenti di Grandi Dimensioni

Mentre copy e fetch funzionano bene per operazioni rapide e file piccoli, usa ansible.posix.synchronize per alberi di directory grandi o trasferimenti delta efficienti. Questo modulo avvolge rsync, quindi il nodo di controllo e l'ambiente di destinazione necessitano del giusto accesso rsync e SSH.

Conclusione

Usa copy quando la sorgente è sul tuo nodo di controllo e la destinazione è sul nodo gestito. Usa fetch quando la sorgente è sul nodo gestito e desideri salvare il file localmente.

Modulo Direzione Esempio di Comando Ad-Hoc
copy Nodo di Controllo -> Nodo Gestito ansible all -m copy -a "src=/local/file dest=/remote/path mode=0644"
fetch Nodo Gestito -> Nodo di Controllo ansible all -m fetch -a "src=/remote/file dest=/local/dir"

Per un singolo server, flat=yes può rendere i file recuperati più facili da leggere. Per un gruppo di server, mantieni la struttura di directory predefinita basata sul nome host in modo che il log di un host non sovrascriva quello di un altro.