#ansible
Вопрос:
Есть ли способ ссылаться на другую переменную в loop1, которая будет использоваться в loop2?
Вот мой фиктивный учебник, который не работает:
---
- name: test
hosts: localhost
vars:
- br:
- dir1
- dir2
- folders:
- /folder1/"{{ item.1 }}"/sub1
- /folder1/"{{ item.1 }}"/sub2
tasks:
- name:
debug:
msg: "{{ item.0 }}"
with_nested:
- "{{ folders }}"
- "{{ br }}"
Результат, которого я пытаюсь достичь, таков:
/folder1/dir1/sub1
/folder1/dir1/sub2
/folder1/dir2/sub1
/folder1/dir2/sub2
Thank you. Appreciate your response.
Комментарии:
1. Я вижу здесь только один цикл (
with_nested
цикл для вашейdebug
задачи).2. @larsks Я на самом деле тоже пробовал
loop
и несколько другихwith_X
, но, похоже, не могу получить нужный мне результат.
Ответ №1:
Я понимаю, что у вас нет требований к используемым переменным, вы просто хотите получить предоставленный список папок эффективным способом (с помощью цикла). Вы можете использовать эти переменные, чтобы получить желаемый результат с помощью with_nested
цикла:
---
- hosts: localhost
gather_facts: false
vars:
- folders:
- dir1
- dir2
- subfolders:
- sub1
- sub2
tasks:
- name:
debug:
msg: "/folder1/{{ item.0 }}/{{ item.1 }}"
with_nested:
- "{{ folders }}"
- "{{ subfolders }}"
овации
Ответ №2:
Вы ищете перекрестный продукт ваших двух списков, чтобы вы могли написать:
- name: test
hosts: localhost
vars:
- br:
- dir1
- dir2
- folders:
- /folder1/%s/sub1
- /folder1/%s/sub2
tasks:
- name:
debug:
msg: "{{ item.1 % item.0 }}"
loop: "{{ br|product(folders) }}"
При этом используется форматирование строк в стиле Python (например "Hello %s" % "world"
) для замены нужного значения в выводе.
Это приводит к выходу:
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => (item=['dir1', '/folder1/%s/sub1']) => {
"msg": "/folder1/dir1/sub1"
}
ok: [localhost] => (item=['dir1', '/folder1/%s/sub2']) => {
"msg": "/folder1/dir1/sub2"
}
ok: [localhost] => (item=['dir2', '/folder1/%s/sub1']) => {
"msg": "/folder1/dir2/sub1"
}
ok: [localhost] => (item=['dir2', '/folder1/%s/sub2']) => {
"msg": "/folder1/dir2/sub2"
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Комментарии:
1. Спасибо @larsks. Ценю ваш ответ.
Ответ №3:
Вы можете использовать Jinja для создания структуры, например
- hosts: localhost
vars:
root:
- folder1
br:
- dir1
- dir2
sub:
- sub1
- sub2
_folders: |-
{% for r in root %}
{% for b in br %}
{% for s in sub %}
- /{{ r }}/{{ b }}/{{ s }}
{% endfor %}
{% endfor %}
{% endfor %}
folders: "{{ _folders|from_yaml }}"
tasks:
- debug:
var: folders
дает то, что ты хочешь
folders:
- /folder1/dir1/sub1
- /folder1/dir1/sub2
- /folder1/dir2/sub1
- /folder1/dir2/sub2
Вы можете скрыть его в файле и отделить динамические данные от кода, например, воспроизведение ниже дает тот же результат
shell> cat my_vars.yml
root:
- folder1
br:
- dir1
- dir2
sub:
- sub1
- sub2
_folders: |-
{% for r in root %}
{% for b in br %}
{% for s in sub %}
- /{{ r }}/{{ b }}/{{ s }}
{% endfor %}
{% endfor %}
{% endfor %}
folders: "{{ _folders|from_yaml }}"
shell> cat playbook.yml
- hosts: localhost
vars_files:
- my_vars.yml
tasks:
- debug:
var: folders