Reputation: 27516
I have a data structure in a json file that gets fed to ansible as an extra variables file, and it looks something like this:
"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"
}
}
These three sections specify files that are downloaded from different sources.
They come from different sources, and it is know that some of them are different types (tar files come from s3, zip from the local network and ftp server) so I have three different plays to handle each download. But at the end of each play, there is a file whose name is the value of full_name
(all entries in these hashes will have an element named full_name
) in the directory /home/ubuntu/downloaded_files
.
After they are downloaded, they are all processed in the same way. Right now, I have three separate plays that do the same thing, but iterating over a different hash, like this:
- 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({})
I'd like to be able to have a single play that handles all of these hashes, but I am not sure if this is possible. I can't seem to figure out the syntax. What I'm thinking of in hypothetical (and probably syntactically invalid) code:
- name: process all downloaded files
shell: some_command -f /home/ubuntu/downloaded_files/{{ item.value.full_name }}
with_dict: ( files_from_s3 | default({}) )
and ( files_from_ftp | default({}) )
and ( files_from_network | default({}) )
In this code sample, I'm imagining that with_dict
will iterate over a union of the three other hashes.
Does this make sense? Is what I want to do even possible? It would be easier to change the plays than the data structure since the data structure in this situation.
Upvotes: 3
Views: 961
Reputation: 1412
I personally think you should change from using a hash of files to a list of hashes. However:
In Ansible 2.0 you'll be able to do a hash_merge
like so:
- shell: echo "{{ item.value.full_name }}"
with_dict: files_from_s3|hash_merge(files_from_ftp)|hash_merge(files_from_network)
Which you can already configure by adding this hash_merge filter plugin
Upvotes: 2