Comment copier des fichiers entre deux nœuds à l'aide d'ansible

97

Je dois copier la machine de formulaire A sur la machine B alors que ma machine de contrôle à partir de laquelle j'exécute toutes mes tâches ansible est la machine C (machine locale)

J'ai essayé ce qui suit:

Utilisez la commande scp dans le module shell d'ansible

hosts: machine2
user: user2
tasks:
  - name: Copy file from machine1 to machine2 
    shell: scp user1@machine1:/path-of-file/file1 /home/user2/file1

Cette approche continue et ne s'arrête jamais.

utiliser des modules d'extraction et de copie

hosts: machine1
user: user1
tasks:
  - name: copy file from machine1 to local
    fetch: src=/path-of-file/file1 dest=/path-of-file/file1

hosts: machine2
user: user2
tasks:
  - name: copy file from local to machine2
    copy: src=/path-of-file/file1 dest=/path-of-file/file1

Cette approche me lance une erreur comme suit:

error while accessing the file /Users/<myusername>/.ansible/cp/ansible-ssh-machine2-22-<myusername>, error was: [Errno 102] Operation not supported on socket: u'/Users/<myusername>/.ansible/cp/ansible-ssh-machine2-22-<myusername>'

Toute suggestion serait utile.

user3228188
la source
1.C'est une fonctionnalité pratique pour enregistrer les accès réseau, lorsque la machine de contrôle peut être plus éloignée; 2.Devrait être corrigé maintenant par github.com/ansible/ansible/pull/16756 jctanner a fusionné le commit 0d94d39 dans ansible: devel le 23 septembre 2016
AnneTheAgile

Réponses:

101

Pour copier des fichiers distants vers distants, vous pouvez utiliser le module de synchronisation avec delegate_to: source-serverle mot-clé ' ':

- hosts: serverB
  tasks:    
   - name: Copy Remote-To-Remote (from serverA to serverB)
     synchronize: src=/copy/from_serverA dest=/copy/to_serverB
     delegate_to: serverA

Ce playbook peut fonctionner à partir de votre machine C.

fourmi31
la source
bonne réponse! Malheureusement, je ne l'ai pas fait fonctionner dans un environnement Vagrant avec plusieurs VM. Il semble que Vagrant y fasse quelque chose de spécial.
therealmarv
Il utilise rsync, l'avez-vous installé sur vm?
ant31
1
À partir de Vagrant 1.7.x, il utilise différentes clés privées en fonction de la machine. Voir le numéro github.com/mitchellh/vagrant/issues/4967 Insérez la ligne suivante dans le fichier config.ssh.insert_key = falseVagrant pour forcer Vagrant à utiliser la clé ONE insecure_key pour accéder à toutes les machines. Mais maintenant, je n'obtiens même pas de message d'erreur (cela attend indéfiniment). Le bogue github.com/ansible/ansible/issues/7250 indique également qu'il n'est pas possible de copier d'une télécommande à une autre.
therealmarv
9
Cela copie en fait les fichiers du serveurB vers le serveurA. Si vous souhaitez les copier du serveurA vers le serveurB, utilisez mode=push(ou delegate_to: serverB, mais pas les deux).
Marius Gedminas
2
@MariusGedminas vous avez raison, mode=pushdevrait être utilisé, mais dans cette situation delegate_to: serverBne peut pas être utilisé, car cela ferait serverBla source et la destination.
Strahinja Kustudic
95

Comme ant31 l'a déjà souligné, vous pouvez utiliser le synchronizemodule pour cela. Par défaut, le module transfère des fichiers entre la machine de contrôle et l'hôte distant actuel ( inventory_host), mais cela peut être modifié en utilisant le delegate_toparamètre de la tâche (il est important de noter qu'il s'agit d'un paramètre de la tâche , pas du module).

Vous pouvez placer la tâche sur l'un ServerAou l' autre ServerB, mais vous devez ajuster la direction du transfert en conséquence (en utilisant le modeparamètre de synchronize).

Placer la tâche sur ServerB

- hosts: ServerB
  tasks:
    - name: Transfer file from ServerA to ServerB
      synchronize:
        src: /path/on/server_a
        dest: /path/on/server_b
      delegate_to: ServerA

Cela utilise la valeur par défaut mode: push, de sorte que le fichier est transféré du délégué ( ServerA) vers le remote ( ServerB) actuel .

Cela peut sembler étrange, car la tâche a été placée sur ServerB(via hosts: ServerB). Cependant, il faut garder à l'esprit que la tâche est réellement exécutée sur l'hôte délégué , ce qui dans ce cas l'est ServerA. Donc pousser (de ServerAvers ServerB) est en effet la bonne direction. Rappelez-vous également que nous ne pouvons pas simplement choisir de ne pas déléguer du tout, car cela signifierait que le transfert se produit entre la machine de contrôle et ServerB.

Placer la tâche sur ServerA

- hosts: ServerA
  tasks:
    - name: Transfer file from ServerA to ServerB
      synchronize:
        src: /path/on/server_a
        dest: /path/on/server_b
        mode: pull
      delegate_to: ServerB

Cela permet mode: pulld'inverser le sens de transfert. Encore une fois, gardez à l'esprit que la tâche est réellement exécutée ServerB, donc tirer est le bon choix.

Florian Brucker
la source
8
C'est une si bonne réponse qu'elle devrait faire partie de la documentation Ansible . Aucun des exemples ne l'explique de manière aussi claire. Merci!
ssc
2
J'ai essayé cela de nombreuses façons, cependant, cela me fait échouer Warning: Identity file /Users/myuser/.ssh/id_servers not accessible.
orotemo
@orotemo: Sans plus d'informations, je ne peux que deviner, mais cela ressemble à un problème dans votre configuration SSH. Veuillez vérifier si vous avez configuré SSH ou Ansible pour utiliser le fichier d'identité indiqué dans le message d'erreur et si ce fichier existe et dispose des autorisations appropriées.
Florian Brucker
2
@WilliamTurrell J'ai mis à jour ma réponse pour expliquer la direction du transfert plus en détail. Le module est en effet un peu déroutant.
Florian Brucker
1
Merci. Pour toute autre personne ayant le problème de @ orotemo, la solution probable est que vous n'avez seulement aucun accès à clé publique entre les serveurs A et B, ou comme je l'ai trouvé, vous l'avez configuré pour ne fonctionner que dans une direction - la mauvaise. En l'absence de paire de clés dans votre répertoire .ssh sur le serveur A, ansible tente d'utiliser le répertoire personnel de votre machine locale (qui n'existera pas s'il s'agit, par exemple, d'un Mac, et peut avoir un nom de compte différent.)
William Turrell
3

Si vous avez besoin de synchroniser des fichiers entre deux nœuds distants via ansible, vous pouvez utiliser ceci:

- name: synchronize between nodes
  environment:
    RSYNC_PASSWORD: "{{ input_user_password_if_needed }}"
  synchronize:
    src: rsync://user@remote_server:/module/
    dest: /destination/directory/
    // if needed
    rsync_opts:
       - "--include=what_needed"
       - "--exclude=**/**"
    mode: pull
    delegate_to: "{{ inventory_hostname }}"

quand remote_servervous devez démarrer rsync avec le mode démon. Exemple simple:

pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsync.log
port = port

[module]
path = /path/to/needed/directory/
uid = nobody
gid = nobody
read only = yes
list = yes
auth users = user
secrets file = /path/to/secret/file
CrusaderX
la source
2

J'ai pu résoudre ce problème en utilisant local_action pour scp vers un fichier de machineA vers machineC, puis en copiant le fichier vers machineB.

user3228188
la source
1

Un moyen simple d'utiliser le module de copie pour transférer le fichier d'un serveur à un autre

Voici le playbook

---
- hosts: machine1 {from here file will be transferred to another remote machine}
  tasks:
  - name: transfer data from machine1 to machine2

    copy:
     src=/path/of/machine1

     dest=/path/of/machine2

    delegate_to: machine2 {file/data receiver machine}
Aliabbas Kothawala
la source
Cela a flotté au cours d'une session aujourd'hui, mais aucun de nous n'a pu le reproduire en utilisant ansible 2.6.4. Mettre cette tâche dans un playbook en créant d'abord un fichier sur machine1 et en listant le répertoire par la suite a échoué avec "Impossible de trouver ou d'accéder à '/ tmp / source-49731914' sur le contrôleur Ansible." La création d'un fichier vide sur la machine hôte l'a résolu, mais a fait une copie hôte> machine2. Peut-être y avait-il un comportement bogué dans certaines versions?
Stephan B
0

Si vous voulez faire rsync et utiliser un utilisateur personnalisé et une clé ssh personnalisée, vous devez écrire cette clé dans les options rsync.

---
 - name: rsync
   hosts: serverA,serverB,serverC,serverD,serverE,serverF
   gather_facts: no
   vars:
     ansible_user: oracle
     ansible_ssh_private_key_file: ./mykey
     src_file: "/path/to/file.txt"
   tasks:
     - name: Copy Remote-To-Remote from serverA to server{B..F}
       synchronize:
           src:  "{{ src_file }}"
           dest: "{{ src_file }}"
           rsync_opts:
              - "-e ssh -i /remote/path/to/mykey"
       delegate_to: serverA
Sasha Golikov
la source
0

Vous pouvez également utiliser deletgateavec scp:

- name: Copy file to another server
  become: true
  shell: "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null admin@{{ inventory_hostname }}:/tmp/file.yml /tmp/file.yml"
  delegate_to: other.example.com

En raison de delegatela commande est exécutée sur l'autre serveur et c'est scple fichier à lui-même.

Kris
la source