ansibleを使用して2つのノード間でファイルをコピーする方法


97

マシンAからマシンBにファイルをコピーする必要がありますが、すべてのansibleタスクを実行する場所からの制御マシンはマシンC(ローカルマシン)です。

私は以下を試しました:

ansibleのシェルモジュールでscpコマンドを使用する

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

このアプローチは続くだけで終わりません。

フェッチ&コピーモジュールを使用する

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

このアプローチでは、次のようなエラーが発生します。

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>'

どんな提案も参考になります。


1.これは、制御マシンが遠く離れている可能性がある場合に、ネットワークアクセスを節約するための便利な機能です。あたりに今固定さ2.Should github.com/ansible/ansible/pull/16756の jctanner ansibleに0d94d39をコミット合併:2016年9月23日にdevelの
AnneTheAgile

回答:


101

リモートからリモートのファイルをコピーするには、同期モジュールを ' delegate_to: source-server'キーワードで使用できます。

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

このプレイブックは、お使いのmachineCから実行できます。


いい答えだ!残念ながら、マルチVMを備えたVagrant環境では動作しませんでした。ヴァグラントはそこで何か特別なことをしているようです。
therealmarv 2015年

rsyncを使用していますが、vmにインストールされていますか?
ant31 2015年

1
Vagrant 1.7.x以降、マシンに応じて異なる秘密鍵を使用します。問題github.com/mitchellh/vagrant/issues/4967を参照してくださいVagrantfileに次の行を挿入して、config.ssh.insert_key = falseVagrantがすべてのマシンにアクセスするために1つのinsecure_keyを使用するように強制します。しかし今、私はエラーメッセージを受け取りません(それは永遠に待ちます)。また、バグgithub.com/ansible/ansible/issues/7250は、リモートからリモートにコピーすることはできないと述べています。
therealmarv 2015年

9
これは実際にファイルをserverBからserverAにコピーします。それらをserverAからserverBにコピーする場合は、を使用しますmode=push(またはdelegate_to: serverB、両方ではなく)。
Marius Gedminas

2
あなたが正しい@MariusGedminasをmode=push使用する必要がありますが、この状況ではソースと宛先delegate_to: serverBが作成されるため、使用できませんserverB
Strahinja Kustudic

95

ant31がすでに指摘したように、synchronizeこのモジュールを使用できます。デフォルトでは、モジュールは制御マシンと現在のリモートホスト(inventory_host)の間でファイルを転送しますが、タスクのdelegate_toパラメーターを使用して変更できます(これはモジュールではなく、タスクのパラメーターであることに注意してください)。

タスクはServerAまたはServerBに配置できますが、それに応じて転送の方向を調整する必要がありmodeます(のパラメーターを使用synchronize)。

タスクを配置する 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

これはデフォルトを使用するmode: pushので、ファイルはデリゲート(ServerA)から現在のリモート(ServerB)に転送されます。

タスクがServerB(を介してhosts: ServerB)配置されているため、これは奇妙に聞こえるかもしれません。ただし、タスクは委任されたホスト(この場合は)で実際に実行されることに注意してServerAください。(からプッシュようServerAServerB)確かに正しい方向です。また、制御マシンとの間で転送が行われることになるため、委任しないことを選択することはできませんServerB

タスクを配置する 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

これはmode: pull、転送方向を反転するために使用します。繰り返しますが、タスクは実際にで実行されるServerBため、プルが正しい選択です。


8
これは、Ansibleのドキュメントの一部であるはずです。そこでの例はどれも、これをそのような明確な方法で説明していません。ありがとう!
ssc 2016年

2
私はこれをさまざまな方法で試しましたが、失敗しましたWarning: Identity file /Users/myuser/.ssh/id_servers not accessible
orotemo 2016年

@orotemo:それ以上の情報がなければ推測できますが、それはSSH設定の問題のようです。エラーメッセージで指定されたIDファイルを使用するようにSSHまたはAnsibleを設定しているかどうか、およびそのファイルが存在し、適切な権限があるかどうかを確認してください。
Florian Brucker

2
@WilliamTurrell私は転送方向をより詳細に説明するために私の答えを更新しました。モジュールは確かに少し混乱しています。
Florian Brucker

1
ありがとう。@orotemoの問題を抱えている他の人にとっては、おそらくサーバーAとBの間で公開鍵にアクセスできないか、または私が見つけたように、一方向にしか機能しないように設定している-間違った方向です。サーバーAの.sshディレクトリにキーペアがない場合、ansibleはローカルマシンのホームディレクトリを使用しようとします(Macなどの場合は存在せず、アカウント名が異なる場合があります)
ウィリアムタレル2016年

2

local_actionを使用してmachineAからmachineCにファイルをscpし、ファイルをmachineBにコピーすることで、これを解決できました。


2

ansibleを介して2つのリモートノード間でファイルを同期する必要がある場合は、これを使用できます。

- 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 }}"

オンのremote_server場合、デーモンモードでrsyncを起動する必要があります。簡単な例:

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

1

コピーモジュールを使用してサーバー間でファイルを転送する簡単な方法

こちらがプレイブックです

---
- 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}

これは今日のセッション中に浮上しましたが、どちらもansible 2.6.4を使用してこれを再現することはできませんでした。最初にmachine1にファイルを作成し、その後ディレクトリをリストすることで、このタスクをプレイブックに入れると、「Ansible Controllerで「/ tmp / source-49731914」が見つからないか、アクセスできませんでした」というエラーが発生しました。ホストマシンで空のファイルを作成すると解決しましたが、host> machine2のコピーが行われました。たぶんいくつかのバージョンでバグのある動作がありましたか?
ステファンB

0

rsyncを実行し、カスタムユーザーとカスタムsshキーを使用する場合は、このキーを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

0

あなたは使用することができますdeletgatescp、あまりにも:

- 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

delegateコマンドが他のサーバーで実行されているため、scpそれ自体がファイルです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.