如何从 Ansible 中具有不同路径的主机获取多个文件?

问题描述 投票:0回答:1

我正在尝试编写一个从多个主机获取文件的脚本,每个远程主机的路径以及从每个主机获取的文件数量都不同。

我的问题是,当

with_items
块内的文件长度不固定时,如何循环/迭代每个文件列表?

由于文件和路径的数量各不相同,我已按如下方式声明了我的库存文件,以使我的剧本更加灵活。来自远程主机的每个 fetch_path 对应于本地主机上的 land_path:

[hosts]
host1 fetch_paths='["path/to/file1", "path/to/file2"]' land_paths='["path/to/file1", "path/to/file2"]'

host2 fetch_paths='["path/to/file1"]' land_paths='["path/to/file1"]'

host3 fetch_paths='["path/to/file1", "path/to/file2", "path/to/file3"]' land_paths='["path/to/file1", "path/to/file2", "path/to/file3"]' 

我当前的剧本如下,但我不确定如何在我的

loop
语句中嵌套
with_items
语句,并使其将 fetch_path 与 land_path 相关联。我假设我需要某种基于每个列表的长度的索引迭代器,但我不确定应该如何以及在哪里实现这个逻辑。

---

- name: fetch files from remote host then execute batch scripts on the localhost
  hosts: hosts
  tasks:
    - name: fetch files from remote host to local
    fetch:
      src: "{{ item.fetch_paths }}"
      dest: "{{ item.land_paths }}"
      flat: yes
      fail_on_missing: yes
      validate_certs: no
    with_items: "{{ groups['hosts'] }}"

我对 Ansible 非常陌生(这是我的第一本剧本),因此非常感谢任何正确方向的指导,提前致谢!

ansible nested-loops ansible-2.x ansible-inventory
1个回答
1
投票

zip 列表。比如下面这个剧

shell> cat pb.yml
- hosts: all

  tasks:

    - fetch:
        src: "{{ item.0 }}"
        dest: "{{ item.1 }}"
        flat: true
      loop: "{{ fetch_paths|zip(land_paths) }}"

鉴于库存

shell> cat hosts
host1
host2

host_vars

shell> cat host_vars/host1
fetch_paths: [/etc/passwd, /etc/services]
land_paths: [/tmp/host1/etc/passwd, /tmp/host1/etc/services]
shell> cat host_vars/host2
fetch_paths: [/etc/passwd]
land_paths: [/tmp/host2/etc/passwd]

将按预期获取文件

shell> ansible-playbook pb.yml

PLAY [all] ************************************************************************************

TASK [fetch] **********************************************************************************
changed: [host2] => (item=['/etc/passwd', '/tmp/host2/etc/passwd'])
changed: [host1] => (item=['/etc/passwd', '/tmp/host1/etc/passwd'])
changed: [host1] => (item=['/etc/services', '/tmp/host1/etc/services'])

PLAY RECAP ************************************************************************************
host1: ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host2: ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
shell> tree /tmp/host1
/tmp/host1
└── etc
    ├── passwd
    └── services

1 directory, 2 files
shell> tree /tmp/host2
/tmp/host2
└── etc
    └── passwd

1 directory, 1 file

注1

没有记录参数dest可以是一个文件

dest:保存文件的目录。例如,如果目标目录是

/backup
,则主机
/etc/profile
上名为
host.example.com
的 src 文件将保存到
/backup/host.example.com/etc/profile
中。主机名基于清单名称。

参见:参数 flat


注2

如果不更改所获取文件的路径名,则可以简化工作流程。默认情况下,模块 fetch 将主机名添加到路径中。引用dest

保存文件的目录。例如,如果主机

dest' directory is 
/backup/host.example.com/etc/profile' 上的
src' file named 
/backup' 为
host.example.com', would be saved into 
/etc/profile'。主机名基于清单名称。

以下播放

- hosts: all

  tasks:

    - fetch:
        src: "{{ item }}"
        dest: /tmp/ansible_fetch
      loop: "{{ fetch_paths }}"

将获取的文件放入控制器上的目录 /tmp/ansible_fetch(如果需要,请将其更改为 /tmp

shell> tree /tmp/ansible_fetch/
/tmp/ansible_fetch/
├── host1
│   └── etc
│       ├── passwd
│       └── services
└── host2
    └── etc
        └── passwd

因此,您不再需要列表 land_paths

shell> cat host_vars/host1 fetch_paths: [/etc/passwd, /etc/services]
shell> cat host_vars/host2
fetch_paths: [/etc/passwd]

    
© www.soinside.com 2019 - 2024. All rights reserved.