Reputation: 386
Finally, I found a solution on how to create nested directory structure which is an equivalent of the Bash command
mkdir -p jenkins/cache/{war,tmp,workspace}
My playbook
---
- name: Create directories
hosts: localhost
vars:
dirs: [
jenkins, # for one elemnt it can be string
[ cache ],
[ war, tmp, workspace ]
]
base_directory: ~/tmp
tasks:
- debug:
msg="{{base_directory}}/{{item.0}}/{{item.1}}/{{item.2}}"
with_nested: "{{ dirs | list }}"
It generates:
PLAY [Create directories] **********************************************************************************************************************************
TASK [debug] ***********************************************************************************************************************************************
ok: [localhost] => (item=['jenkins', 'cache', 'war']) => {
"msg": "~/tmp/jenkins/cache/war"
}
ok: [localhost] => (item=['jenkins', 'cache', 'tmp']) => {
"msg": "~/tmp/jenkins/cache/tmp"
}
ok: [localhost] => (item=['jenkins', 'cache', 'workspace']) => {
"msg": "~/tmp/jenkins/cache/workspace"
}
PLAY RECAP *************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
But there is an issue if I want to use more (or less) levels of nesting. I need more (or less) item.X
.
How to do it dynamically in Ansible?
I know there is community module filetree
, which can be helpfully but I don't want or need to use it.
Upvotes: 3
Views: 1606
Reputation: 39294
You can definitely use a with_nested
and join
the second level list with a /
.
So, a task like this would do:
- debug:
msg: >-
{{ base_directory }}/
{{- item | join('/') }}
with_nested: "{{ dirs }}"
Given the task:
- debug:
msg: >-
{{ base_directory }}/
{{- item | join('/') }}
with_nested: "{{ dirs }}"
vars:
dirs:
- jenkins
- - cache
- - war
- tmp
- workspace
base_directory: ~/tmp
This yields:
ok: [localhost] => (item=['jenkins', 'cache', 'war']) =>
msg: ~/tmp/jenkins/cache/war
ok: [localhost] => (item=['jenkins', 'cache', 'tmp']) =>
msg: ~/tmp/jenkins/cache/tmp
ok: [localhost] => (item=['jenkins', 'cache', 'workspace']) =>
msg: ~/tmp/jenkins/cache/workspace
Upvotes: 3
Reputation: 68189
The filter community.general.path_join takes the items of a list and creates a path. For example, the simplified task below
- debug:
msg: "{{ base_directory }}/{{ item|community.general.path_join }}"
with_nested: "{{ dirs }}"
vars:
dirs:
- jenkins
- cache
- [war, tmp, workspace]
base_directory: /tmp
gives
msg: /tmp/jenkins/cache/war
msg: /tmp/jenkins/cache/tmp
msg: /tmp/jenkins/cache/workspace
Upvotes: 2