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:
- Nodo di Controllo Ansible: Una macchina con Ansible installato.
- File di Inventario: Un file di inventario funzionante (es.
/etc/ansible/hosts) che definisce i tuoi nodi gestiti. - 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. | Sì | /tmp/config.conf |
dest |
Il percorso in cui verrà posizionato il file sul nodo gestito remoto. | Sì | /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. | Sì | /var/log/nginx/error.log |
dest |
Il percorso assoluto della directory sulla macchina di controllo in cui verranno salvati i file. | Sì | /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=yessolo 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.