Как уничтожить/удалить/сбросить значение переменной в Ansible?

Вопрос или проблема

Существует ли способ уничтожить переменную в Ansible?

На самом деле, у меня есть переменная {{version}}, которая используется во всех моих ролях для соответствующих пакетов. Когда я запускаю несколько ролей, значение версии одной роли передается другой — это происходит из-за того, что для одной из ролей я не указываю значение версии, чтобы она могла установить стандартную версию этого пакета, доступного для соответствующей машины, такой как ubuntu/redhat и т. д.

Вот шаблон моей роли. Значение {{version}} из mysql передается в rabbitmq.

    roles:
- { role: mysql }
- { role: rabbitmq}

Если я смогу уничтожить/удалить значение версии в каждой роли, это должно решить проблему, я верю.

Как уже упоминалось, нельзя убрать переменную в Ansible.

Избегайте этой ситуации, добавляя префикс к именам ваших переменных, например rabbitmq_version и так далее. На мой взгляд, это лучшая практика.

Кроме того, избегая ситуации, с которой вы столкнулись, это добавит ясность в ваши host_vars и group_vars.

Нет, нет способа убрать переменную (на верхнем уровне) в Ansible.

Единственное, что вы можете сделать, это создать словарь и хранить переменную в качестве ключа в этом словаре. Очистка “родительского” словаря фактически заставит условное выражение dictionary.key is defined работать.

Чтобы убрать переменную, попробуйте запустить задачу set_fact, устанавливающую переменную в null, например:

- name: Удалить переменные
  set_fact:
    version:
    other_var:

Если у вас есть полный словарь, вы можете просто переопределить его с null, например:

- name: Установить словарь
  set_fact:
    dict:
      rabbitmq_version: 1
      other_version: 2

- name: переопределить словарь на null
  set_fact:
    dict:

Что-то вроде other_var: просто является "other_var": null в JSON. Так вы можете убрать переменные в Ansible. Хорошего дня.

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

  roles:
    - role: mysql
      version: mysql_version
    - role: rabbitmq
      version: rabbitmq_version

или

  roles:
    - { role: mysql, version: mysql_version }
    - { role: rabbitmq, version: rabbitmq_version }

В Ansible 2.12 используйте функцию undef() вот так:

airflow_pip_version: "{{ undef() }}"  # убирает значение по умолчанию: 20.2.4

После этого следующая задача будет пропущена:

- name: Airflow | Установить pip "{{ airflow_pip_version }}" версию
  pip:
    name: pip
    version: "{{ airflow_pip_version }}"
  when: airflow_pip_version is defined

Это было желаемое поведение для меня. Документация:

https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_templating_undef.html

В Ansible 2.12 и более поздних версиях используйте функцию undef(). Вот пример:

- hosts: all
  vars:
    version: 1.0
  tasks:
    - assert:
        that: version is defined
    - assert:
        that: version is not defined
      vars:
        version: "{{ undef() }}"

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

variable_name: ''

Ответ или решение

Вопрос о том, как «уничтожить» или «удалить» значение переменной в Ansible, является довольно распространенным, особенно при работе с несколькими ролями, которые могут переопределять значения переменных и вызывать путаницу.

К сожалению, в Ansible не существует прямого способа удалить переменную. Однако есть несколько подходов, которые помогут избежать конфликтов и достигнуть желаемого поведения.

1. Используйте переменные, специфичные для роли

Один из наиболее рекомендуемых способов избежать подобных конфликтов — это использовать разные переменные для каждой роли. Например, вместо одного общего имени переменной version, используйте специфичные переменные для каждой роли:

roles:
  - role: mysql
    version: mysql_version
  - role: rabbitmq
    version: rabbitmq_version

Такой подход не только улучшит читаемость, но и поможет избежать случайной передачи значений между ролями.

2. Использование set_fact

Если вам необходимо «очистить» значение переменной, вы можете использовать модуль set_fact, чтобы установить переменную в null или в пустое значение:

- name: Установить переменную в null
  set_fact:
    version: null
    other_var: null

Или же, если у вас есть словарь:

- name: Установить словарь
  set_fact:
    versions_dict:
      rabbitmq_version: 1
      other_version: 2

- name: Очистить словарь
  set_fact:
    versions_dict: {}

Это позволит некоторым условиям, использующим when, не выполняться, если переменные не заданы.

3. Использование функции undef() (Ansible 2.12 и позже)

В Ansible версии 2.12 и новее вы можете использовать функцию undef(), чтобы сбросить переменную. Пример использования:

- hosts: all
  vars:
    version: 1.0
  tasks:
    - assert:
        that: version is defined
    - assert:
        that: version is not defined
      vars:
        version: "{{ undef() }}"

Этот подход позволяет вам явно установить переменную в состояние не определено, что может быть полезно в сценариях, где необходимо предотвратить дальнейшее использование переменной.

4. Использование пустых строк

Иногда вместо использования null, вы можете установить переменную в пустую строку:

variable_name: ''

Этот способ тоже может быть полезен, если необходимо очистить значение, но важно помнить, что пустая строка будет считаться определенной переменной.

Заключение

Рекомендуется следовать принципу именования переменных, специфичных для роли, поскольку это не только решит вашу текущую проблему, но и улучшит масштабируемость и поддерживаемость вашего кода Ansible. С помощью предложенных методов, таких как использование set_fact, функции undef() или простое использование специфичных имен переменных, вы сможете избежать путаницы и конфликтов.

Оцените материал
Добавить комментарий

Капча загружается...