In Ansible come forse ben saprete è possibile effettuare una escalation di privilegi specificando anche l’utente privilegiato.
Tutti i moduli di Ansible rispettano, o almeno dovrebbero, queste direttive effettuando l’escalation di privilegi una volta stabilita la connessione (SSH o altra che sia) con l’utente definito dalla variabile ansible_user.
Dal momento che il progetto è open source ed i moduli mantenuti grazie alla community i comportamenti imprevisti sono ancor più possibili.
Nel nostro caso il modulo synchronize è un wrapper di rsync che ci permette quindi di mantenere sincronizzata una struttura di file e directory da locale a remoto o viceversa (dipende dal parametro ‘mode’).
Se volessimo mantenere inalterato anche l’owner e il gruppo della nostra struttura sarebbe sufficiente settare i parametri:
group: yes owner: yes
Altrimenti di default se attivassimo il flag archive (stessa di rsync) l’owner ed il gruppo verrebbero comunque mantenuti.
Se volessimo impostare un nuovo owner e/o gruppo al momento non è disponibile come una funzionalità dedicata, ma è possibile far creare la struttura da un utente privilegiato a livello di task o di play o di inventario. Per esempio a livello di task:
- synchronize: [...] become: yes become_user: my_privileged_user
Ed ora ci aspetteremmo che i file vengano creati da “my_privileged_user” ed invece no. Verrebbero creati dall’utente root, che è l’utente privilegiato di default.
E’ stato risolto?
No. Al momento non è stata risolta la issue, ma è comunque aperta una pull request non ancora merged nel repository di Ansible.
Esiste un workaround?
Sì. Uno dei parametri di synchronize è ‘rsync_path’ che permette di specificare il path del comando rsync; possiamo sfruttarlo insieme a sudo per far sì che il comando venga effettivamente eseguito dal nostro utente privilegiato:
- synchronize: [...] rsync_path: ‘sudo -u my_privileged_user rsync’ [...] become: yes
Per esempio se volessimo gestire le configurazioni di Nagios facendo sì che esse rimangano di proprietà dell’utente ‘nagios’, questo potrebbe essere un esempio di task di sincronizzazione:
- name: Configure Nagios synchronize: src: “{{ nagios_local_conf }}” dest: “{{ nagios_remote_conf }}” archive: yes compress: yes owner: no group: no rsync_path: “sudo -u nagios rsync” become: yes notify: reload nagios
(ammettendo che sia definito un handler per il reload delle configurazioni che stia in ascolto su ‘reload nagios’).
In alternativa, se si volesse evitare di specificare l’’rsync_path’ dovremmo specificare ‘owner: yes’ e ‘group: yes’ e mantenere i nostri file in locale con owner e group che combacino con uid gid dell’utente target, che nel nostro caso è nagios.
Per verificarlo, sull’host remoto:
$ id -u nagios # nagios_uid $ id -g nagios # nagios_gid
Ed in locale impostare quegli uid e gid come owner e gruppo dei nostri file di configurazione:
$ chown -R [nagios_local_conf] [nagios_uid]:[nagios_gid]
Task di esempio:
- name: Configure Nagios synchronize: src: “{{ nagios_local_conf }}” dest: “{{ nagios_remote_conf }}” archive: yes compress: yes owner: yes group: yes become: yes notify: reload nagios
Sconsigliamo ad ogni modo questa alternativa.
In conclusione chiariamo che queste non vogliono essere presentate come soluzioni ma come hack in attesa del merge della PR 21531 verso Ansible.
Buon hacking!
* Rimandiamo qui (https://docs.ansible.com/ansible/2.6/modules/synchronize_module.html) per la documentazione relativa al modulo per la versione 2.6 di Ansible.