Ansible-在单个播放中迭代多个哈希

Ansible-在单个播放中迭代多个哈希,ansible,ansible-playbook,Ansible,Ansible Playbook,我在一个json文件中有一个数据结构,作为一个额外的变量文件提供给ansible,它看起来像这样: "files_from_ftp": { "file1": { "full_name":"very-long-file-name-1" "url":"ftp://.....very-long-file-name-1.zip" }, "file2": { "full_name":"very-long-file-name-2"

我在一个json文件中有一个数据结构,作为一个额外的变量文件提供给ansible,它看起来像这样:

"files_from_ftp":
{
   "file1":
   {
      "full_name":"very-long-file-name-1"
      "url":"ftp://.....very-long-file-name-1.zip"
   },
   "file2":
   {
      "full_name":"very-long-file-name-2"
      "url":"ftp://.....very-long-file-name-2.zip"
   }
},
"files_from_network":
{
  "file3":
  {
     "full_name":"very-long-file-name-3"
     "network_path":"file:///SOMEWHERE/ON/THE/NETWORK/very-long-file-name.zip"
  }
},
"files_from_s3":
{
  "file4":
  {
     "full_name":"very-long-file-name-4"
     "url":"s3://some.s3.bucket/very-long-file-name-4.tar"
  }
}
- name: process files from ftp
  shell: some_command -f /home/ubuntu/downloaded_files/{{ item.value.full_name }}
  with_dict: files_from_ftp | default({})

- name: process files from network
  shell: some_command -f /home/ubuntu/downloaded_files/{{ item.value.full_name }}
  with_dict: files_from_network | default({})

- name: process files from s3
  shell: some_command -f /home/ubuntu/downloaded_files/{{ item.value.full_name }}
  with_dict: files_from_s3 | default({})
这三个部分指定从不同来源下载的文件

它们来自不同的来源,而且我们知道其中一些是不同类型的(tar文件来自s3,zip来自本地网络和ftp服务器),所以我有三个不同的剧本来处理每次下载。但是在每个剧本的结尾,在目录
/home/ubuntu/downloaded\u files
中有一个文件名为
full\u name
(这些散列中的所有条目都将有一个名为
full\u name
)的元素

下载后,它们都以相同的方式进行处理。现在,我有三个不同的重头戏做同样的事情,但在不同的散列上迭代,如下所示:

"files_from_ftp":
{
   "file1":
   {
      "full_name":"very-long-file-name-1"
      "url":"ftp://.....very-long-file-name-1.zip"
   },
   "file2":
   {
      "full_name":"very-long-file-name-2"
      "url":"ftp://.....very-long-file-name-2.zip"
   }
},
"files_from_network":
{
  "file3":
  {
     "full_name":"very-long-file-name-3"
     "network_path":"file:///SOMEWHERE/ON/THE/NETWORK/very-long-file-name.zip"
  }
},
"files_from_s3":
{
  "file4":
  {
     "full_name":"very-long-file-name-4"
     "url":"s3://some.s3.bucket/very-long-file-name-4.tar"
  }
}
- name: process files from ftp
  shell: some_command -f /home/ubuntu/downloaded_files/{{ item.value.full_name }}
  with_dict: files_from_ftp | default({})

- name: process files from network
  shell: some_command -f /home/ubuntu/downloaded_files/{{ item.value.full_name }}
  with_dict: files_from_network | default({})

- name: process files from s3
  shell: some_command -f /home/ubuntu/downloaded_files/{{ item.value.full_name }}
  with_dict: files_from_s3 | default({})
我希望能够有一个单一的发挥,处理所有这些散列,但我不知道这是否是可能的。我似乎搞不懂语法。我在假设(可能在语法上无效)代码中的想法:

在这个代码示例中,我想象
with_dict
将迭代其他三个哈希的并集


这有意义吗?我想做的事情可能吗?更改播放比更改数据结构更容易,因为在这种情况下,数据结构是可用的。

我个人认为您应该从使用文件哈希改为使用哈希列表。然而:

在Ansible 2.0中,您可以执行如下操作:

- shell: echo "{{ item.value.full_name }}"
  with_dict: files_from_s3|hash_merge(files_from_ftp)|hash_merge(files_from_network)

您可以通过添加此项来配置它

Nice!关于更多信息,这里是PR的链接:这些文件被分成不同的散列,因为有些是使用
get\u url
模块下载的,有些是使用s3的,有些是通过本地网络复制的。在下载并预处理完所有步骤后,有一些相同的通用步骤可应用于所有步骤。如果它们都在一个散列中,后面的步骤将很容易,但我不确定如何编写一个可以从S3、本地网络或ftp服务器下载的剧本,然后执行其他几个预处理步骤中的一个。好吧,这种情况下的复杂性似乎达到了您想要编写一个模块来管理它的程度,它将能够更好地处理诸如文件覆盖其他文件、过时文件等极端情况,以及幂等的真正特殊情况