#ansible
Вопрос:
Я пытаюсь рекурсивно импортировать переменные из папок со следующей структурой:
containers
|_ deluge
|_ defaults
|_ main.yml
|_ tasks
|_ main.yml
|_ jellyfin
|_ defaults
|_ main.yml
|_ tasks
|_ main.yml
В каждой папке есть default/main.yml
файл, который выглядит следующим образом:
---
container_name: deluge
port: 8112
homer_url: "http://{{ ansible_host }}:{{ port }}"
Эти переменные имеют одинаковые имена во всех папках.
Я хотел бы импортировать homer_url
переменные в учебник в следующей форме, чтобы я мог обращаться к ним с помощью homer_containers.deluge
, homer_containers.jellyfin
, и так далее:
homer_containers {
deluge: "http://myhost.com:8112"
plex: "http://myhost.com:32400"
jellyfin: "http://myhost.com:8096"
}
Вот как я пытаюсь это сделать:
---
- name: Get a list of containers
delegate_to: localhost
become: no
find:
paths:
- "roles/containers"
file_type: directory
excludes: "homer"
recurse: no
register: containers
- name: Include all .json and .jsn files in vars/all and all nested directories (2.3)
include_vars:
dir: "{{ playbook_dir }}/{{ item.path }}/defaults"
files_matching: main.yml
name: "{{ item.path.split('/')[-1] }}"
with_items: "{{ containers.files }}"
no_log: true
- name: print out
debug:
var: deconz.homer_url
- name: Populate the dictionary
set_fact:
homer_containers: "{{ homer_containers | default({}) | combine ( { item.path.split('/')[-1] : vars[item.path.split('/')[-1] '.homer_url'] } ) }}"
cacheable: true
with_items: "{{ containers.files }}"
- name: print out
debug:
var: homer_containers
Однако Ansible не удается преобразовать имя переменной в фактическую переменную:
TASK [containers/homer : print out]
ok: [myhost] => {
"deconz.homer_url": "http://myhost.com:8085"
}
TASK [containers/homer : Populate the dictionary]
fatal: [myhost]: FAILED! => {"msg": "The task includes an option with an undefined variable.
The error was: 'dict object' has no attribute 'deconz.homer_url'}
Ответ №1:
Вместо того , чтобы обращаться к переменной как foo['bar.baz']
, так и должно быть foo['bar']['baz']
.
Так что просто изменитесь:
vars[item.path.split('/')[-1] '.homer_url']
Для
vars[item.path.split('/')[-1]]['homer_url']
Комментарии:
1. Это, казалось, сработало, однако переменные усов, похоже, не разрешаются внутри диктанта, например
"bitwarden": "https://bitwarden.{{ host }}"
Ответ №2:
Ответ @Rickkwa сработал после небольшой корректировки. Я также изменил структуру, включив в нее другую переменную ( homer_category
)
- name: Populate the dictionary
set_fact:
homer_urls: "{{ homer_urls | default([]) [{ 'name': item.path.split('/')[-1], 'url' : lookup('vars', item.path.split('/')[-1])['homer_url'] | default(''), 'category': lookup('vars', item.path.split('/')[-1])['homer_category'] | default ('') }] }}"
with_items: "{{ containers.files }}"