ANSIBL с переменными по умолчанию на основе словаря

У меня есть некоторые переменные по умолчанию в моей роли Ansible

sysproperties:
 java_awt_headless:
   key: "java.awt.headless"
   value: "true"
   enabled: "true"
 java_iccprofile_path:
   key: "java.iccprofile.path"
   value: "image/iccprofiles"
   enabled: "true"
...
...

И они должны в конечном итоге в XML-файл, основанный на шаблоне jinja2

{% for key, value in sysproperties.items() %}
<sysproperty key="{{ value.key }}" value="{{ value.value }}" enabled="{{ value.enabled }}"/>
{% endfor %}

Чтобы изменить одно из значений по умолчанию, я бы хотел, чтобы это было так просто:

---
- name: run this
  hosts: myTestHost
  vars:
     sysproperties.java_iccprofile_path.value: "somewhere/else"
  roles:
    - role: myRole

Но пока я только что обнаружил, что мне понадобится дополнительная задача, просто чтобы изменить этот параметр

  pre_tasks:
    - set_fact:
        sysproperties: "{{ sysproperties | combine(new_item, recursive=true) }}"
      vars:
        new_item: "{ 'java_iccprofile_path': { 'value': 'somewhere/else' } }"
      with_dict: "{{ sysproperties }}"

Итак, мои вопросы: есть ли более простой способ для этого? Должен ли я настроить свои значения по умолчанию немного по-другому, чтобы их было легче изменить?

[РЕДАКТИРОВАТЬ] Чтобы сделать более ясным, что мой фактический вопрос:

Я храню настройки в списке / словаре, чтобы записать их через шаблонный модуль в файл XML. Мне нравятся все, кто использует мою роль, чтобы иметь возможность легко изменять или добавлять настройки. Каков наилучший способ сделать это? Является ли способ сделать это сейчас, выполнив pre_task правильно или есть лучшие способы сделать это?

1 ответ

Одна из вещей, которую вы можете сделать, это переопределить переменную при вызове роли. Вы можете сделать это в своей пьесе:

---
- hosts: localhost
  roles:
    - {role: "myRole", sysproperties.java_iccprofile_path.value: "somwhere/else"}
...

Надеюсь это поможет.

ОБНОВЛЕНИЕ Хм. Интересно. Вот моя тестовая установка:

myRole
+ tasks
| + main.yml
+ vars
| + main.yml
+ testrole.yml

Вот содержимое myRole / tasks / main.yml

---
- name: Debugging
  debug: var=foo
...

Вот содержимое myRole / vars / main.yml

---
foo: "blah"
...

Вот содержание testrole.yml

---
- hosts: localhost
  roles:
    - myRole
...

Если я бегу

ansible-playbook ./testrole.yml

я получил

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [defaults : Debugging] ****************************************************
ok: [localhost] => {
    "foo": "blah"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

Если я обновлю testrole.yml следующим образом:

---
- hosts: localhost
  roles:
    - {role: "myRole", foo: "yuck"}
...

я получил

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [defaults : Debugging] ****************************************************
ok: [localhost] => {
    "foo": "yuck"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

Итак, я попробовал со словарем.

myRole / вары / main.yml:

---
sysproperties:
  java_something_else:
    key: "path"
  java_iccprofile_path:
    value: "i/am/here"
...

Если я помещу sysproperties.java_iccprofile_path.value: "some/where/else" в testrole.yml, это не удастся. Если у меня есть следующее в testrole.yml, это вроде работает:

---
- hosts: localhost
  roles:
    - {role: "myRole", sysproperties: {java_iccprofile_path: {value: "yuck"}}}
...

Результатом вышесказанного является

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [defaults : Debugging] ****************************************************
ok: [localhost] => {
    "sysproperties": {
        "java_iccprofile_path": {
            "value": "yuck"
        }
    }
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

Как видите, он заменил значение, но также удалил и другие значения.

Я обнаружил здесь, что изменение значения hash_behavior для слияния в файле ansible.cfg сохранит старые данные и перезапишет только то, что вы сказали перезаписать.

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [defaults : Debugging] ****************************************************
ok: [localhost] => {
    "sysproperties": {
        "java_iccprofile_path": {
            "value": "yuck"
        }, 
        "java_something_else": {
            "key": "path"
        }
    }
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   
Другие вопросы по тегам