Ответ 1
В Ansible 2.0 есть фильтр Jinja, combine
, для этого:
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: "{{ my_default_values | combine(my_values) }}"
В настоящее время я занимаюсь созданием роли для установки PHP с помощью незаменимого, и мне сложно слить словари. Я пробовал несколько способов сделать это, но я не могу заставить его работать, как я хочу:
# A vars file:
my_default_values:
key = value
my_values:
my_key = my_value
# In a playbook, I create a task to attempt merging the
# two dictionaries (which doesn't work):
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: my_default_values + my_values
# I have also tried:
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: my_default_values|union(my_values)
# I have /some/ success with using j2 update,
# but you can't use j2 syntax in "with_dict", it appears.
# This works:
- debug: msg="{{ my_default_values.update(my_values) }}"
# But this doesn't:
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: my_default_values.update(my_values)
Есть ли способ слить два словаря, поэтому я могу использовать его с "with_dict"?
В Ansible 2.0 есть фильтр Jinja, combine
, для этого:
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: "{{ my_default_values | combine(my_values) }}"
Если вы хотите слить хэш, я бы включил функцию слияния хэшей в недоступном. В вашем конфигурационном файле включить хеш слияния.
С hash_behaviour = merge вы можете иметь два файла var с тем же именем переменной:
defaults.yml:
values:
key: value
overrides.yml:
values:
my_key: my_value
Чтобы объединить два vars, вам нужно будет включить оба файла var:
ansible-playbook some-play.yml ... [email protected] [email protected]
И вы закончите с этим:
TASK: [debug var=values] ********************************************************
ok: [localhost] => {
"values": {
"key": value,
"my_key": my_value
}
}
Вызов обновления для переменной может быть выполнен в Jinja, но в целом это будет грязно, я бы не сделал это за пределами ваших шаблонов и даже тогда попытаюсь избежать его вообще.
Теперь можно использовать привязку и расширить возможности YAML:
---
- hosts: localhost
vars:
my_default_values: &def
key: value
my_values:
<<: *def
my_key: my_value
tasks:
- debug: var=my_default_values
- debug: var=my_values
Результат:
TASK [debug]
ok: [localhost] => {
"my_default_values": {
"key": "value"
}
}
TASK [debug]
ok: [localhost] => {
"my_values": {
"key": "value",
"my_key": "my_value"
}
}
Я понятия не имею, почему это не упоминалось раньше.
Если вам нужен объединенный словарь несколько раз, вы можете установить его в новую "переменную":
- set_fact: _my_values="{{ my_default_values|combine(my_values) }}"
- debug: msg="{{ item.key }} = {{ item.value }}"
with_dict: _my_values
Попробуйте эту роль из Ansible Galaxy.
Я сделал это некоторое время назад по той же причине. Он может сглаживать словари из нескольких файлов vars и устанавливать пользовательский приоритет слияния.
Эта роль может работать под Ansible 2.0 +
>>> key = 'default key'
>>> value = 'default value'
>>> my_key = 'my key'
>>> my_value = 'my value'
>>>
>>> my_default_values = {key: value}
>>> print my_default_values
{'default key': 'default value'}
>>>
>>> my_values = {my_key: my_value}
>>> print my_values
{'my key': 'my value'}
>>>
>>> with_dict = my_default_value.copy()
>>> print with_dict
{'default key': 'default value'}
>>> with_dict.update(my_values)
>>> print with_dict
{'default key': 'default value', 'my key': 'my value'}