Перебор списка в словаре в ansible
У меня есть переменная, структурированная так. Я успешно использовал это с with_dict
с одним ключом в accessible_from
vars:
mysql_dbs:
db1:
user: db1_user
pass: "password"
accessible_from: localhost
db2:
user: db2_user
pass: "password2"
accessible_from: '%'
Это применяется с использованием mysql_db
ANSIBLE модуль, как это:
- name: Configure mysql users
mysql_user: name={{ item.value.user }} password={{ item.value.pass }} host={{ item.value.accessible_from | default('localhost')}} priv={{ item.key }}.*:ALL state=present
with_dict: "{{ mysql_dbs }}"
мне бы хотелось accessible_from
иметь возможность быть списком. Неважно, должен ли это быть список, но одной пары ключ / значение недостаточно:) Так, например:
vars:
mysql_dbs:
db1:
user: db1_user
pass: "password"
accessible_from:
- server1
- server2
- localhost
db2:
user: db2_user
pass: "password"
accessible_from:
- '%'
Итак, цель - создать все базы данных и пользователей в одной игре. Я пытался поиграть с with_subelements
, безуспешно. Возможно ли это сделать? Или необходимо реструктурировать данные или переписать игру? Я сделаю это, если придется, но мне было интересно, есть ли другой способ обойти это.
2 ответа
Во-первых: вы можете изменить свой mysql_dbs
в список (потому что в with_subelements
Вы не можете ссылаться на ключи предметов), например:
mysql_dbs:
- name: db1
user: db1_user
pass: "password"
accessible_from:
- server1
- server2
- localhost
- name: db2
user: db2_user
pass: "password2"
accessible_from:
- '%'
И пользователь with_subelements
:
- mysql_user: name={{ item[0].user }} password={{ item[0].pass }} host={{ item[1] }} priv={{ item[0].name }}.*:ALL state=present
with_subelements:
- "{{ mysql_dbs }}"
- accessible_from
Но это не удастся, если accessible_from
не определено для любой базы данных. Вы можете использовать skip_missing
, но это пропустит всю БД. Таким образом, вы не можете опустить accessible_from
в этом случае.
Второе: вы можете использовать помощника set_fact
сформировать список с ключом и значением, также по умолчанию accessible_from
в localhost
, Это будет работать без рефакторинга ваших данных:
- set_fact:
db_name: "{{ item.key }}"
db_params: "{{ dict(accessible_from=['localhost']) | combine(item.value) }}"
with_dict: "{{ mysql_dbs }}"
register: mysql_dbs_fact
loop_control:
label: "{{ item.key }}"
- debug:
msg: "mysql_user: name={{ item[0].db_params.user }} password={{ item[0].db_params.pass }} host={{ item[1] }} priv={{ item[0].db_name }}.*:ALL state=present"
with_subelements:
- "{{ mysql_dbs_fact.results | map(attribute='ansible_facts') | list }}"
- db_params.accessible_from
loop_control:
label: "{{ item[0].db_name }}->{{ item[1] }}"
Попробуй это:
vars:
mysql_dbs:
db1:
user: db1_user
pass: "password"
accessible_from:
- acc_from: server1
- acc_from: server2
- acc_from: localhost
db2:
user: db2_user
pass: "password"
accessible_from:
- acc_from: '%'
tasks:
- name: Configure mysql users
debug: msg="{{ item.0.user }} password={{ item.0.pass }} host={{ item.1.acc_from }} priv={{ item.0 }}.*:ALL state=present"
with_subelements:
- "{{ mysql_dbs }}"
- accessible_from