I have an Ansible variable specifing a directory, and another which is a list of files. I want to derive a list of paths comprised of each file prefixed by the directory.
vars:
dir: /tmp
files:
- a
- b
- c
paths: .. # some transform expression
The eventual value of paths
should be as though it had been explicitly defined as
paths:
- /tmp/a
- /tmp/b
- /tmp/c
I've tried a solution with regex_replace
, but that's a pretty nuclear option for such a simple transform, and I ran into endless quoting issues. I've also tried various combinations with map
, join
, path_join
, and I don't know what-all else. Some would make perfect sense, if they didn't expect their arguments to be a mix of filter input and actual parameters.
The regex_replace
example I tried seem to imply that variable definitions could 'forward reference' others in the same vars
structure, but a few of my attempts gave me pages of errors suggesting that's not [always?] the case.
This is a heavily over-simplified example, and I'm looking for a more general solution than once just for the data shown.
Q: "I'm looking for a more general solution."
A: Given the data
dir: /tmp
files: [a, b, c]
paths: "{{ [dir]|product(files)|map('join', '/') }}"
gives
paths:
- /tmp/a
- /tmp/b
- /tmp/c
paths: "{{ [dir]|product(files)|map('community.general.path_join') }}"
def string_prefix(s, prefix):
return prefix + str(s)
See string_filters.py. Create directory plugins/filter and get the filters
shell> cd plugins/filter
shell> wget https://raw.githubusercontent.com/vbotka/ansible-plugins/master/filter_plugins/string_filters/string_filters.py
Configure DEFAULT_FILTER_PLUGIN_PATH
shell> pwd
/scratch/tmp7/test-481
shell> ansible-config dump | grep DEFAULT_FILTER_PLUGIN_PATH
DEFAULT_FILTER_PLUGIN_PATH(/export/scratch/tmp7/test-481/ansible.cfg) = ['/scratch/tmp7/test-481/plugins/filter']
shell> tree .
.
├── ansible.cfg
├── hosts
├── pb.yml
└── plugins
└── filter
└── string_filters.py
Then, the below expression gives the same result
paths: "{{ files|map('string_prefix', dir ~ '/') }}"
Example of a complete playbook for testing
shell> cat pb.yml
- hosts: localhost
vars:
dir: /tmp
files: [a, b, c]
paths1: "{{ [dir]|product(files)|map('join', '/') }}"
paths2: "{{ [dir]|product(files)|map('community.general.path_join') }}"
paths3: "{{ files|map('string_prefix', dir ~ '/') }}"
tasks:
- debug:
var: paths1
- debug:
var: paths2
- debug:
var: paths3
See an example of other plugins.