I have three local directories with the following structure:
$ tree .
|_ inventory
|_ deploy.yml
|_ key
|_ node1
| |_ ... # several files, like id_rsa.pub etc
|_ node2
| |_ ... # several files, like id_rsa.pub etc
|_ node3
|_ ... # several files, like id_rsa.pub etc
My inventory file is down bellow:
[remote_cluster]
node1 ansible_host=192.168.100.100
node2 ansible_host=192.168.100.101
node3 ansible_host=192.168.100.102
What I want to do is to copy the directory from my local machine to remote machine whose hostname is same with the directory name, for example, copy node1
to the remote machine named node1
. I don't really want to hard-code this feature in that the amount of remote_cluster nodes is not always three. It may increase or decrease in the future.
I have googled some examples, but nove of them fit my goal. And I have made some attempts,but also without success:
- hosts: remote_cluster
name: copy local directories to related nodes
gather_facts: False
tasks:
- name: copy task
ansible.builtin.copy:
src: '{{ item.src }}'
dest: '{{ item.dest }}'
with_items:
- { src: 'key/{{hostvar}}/', dest: '~/.ssh/'}
tags:
- copy
It seems to me that ansible might be able to identify which remote host is currently executing a task by some variable or something. But I didn't figure out what the name of this magic variable is. To make things clear, I'm temporarily replacing that variable name with hostvar
.
Can anyone help? Thanks in advance!
You are taking this the wrong way. Your play already loops on each machine in your group. You don't need a loop here (unless you only want a subset of files inside your source dir).
The copy
module is able to copy an entire tree but will have very poor performance if you have a lot of files. If that's the case, have a look at the syncrhonize
module which is better suited for that.
My feeling is that you are missing a bit of knowledge on internal ansible variables you can use during your play. As a first introduction, I suggest you read the documentation section on magic variables. The one I will use below (as already reported in @JBone comment) is inventory_hostname
Here is your fixed playbook (from what I understood and untested). Please note the ending /
in the src:
value and read the corresponding description in the documentation
If path is a directory, it is copied recursively. In this case, if path ends with "/", only inside contents of that directory are copied to destination. Otherwise, if it does not end with "/", the directory itself with all contents is copied.
---
- hosts: remote_cluster
name: copy local directories to related nodes
gather_facts: false
tasks:
- name: copy task
ansible.builtin.copy:
src: 'key/{{ inventory_hostname }}/'
dest: '~/.ssh/'
tags:
- copy