Вопрос или проблема
Существует ли способ уничтожить переменную в 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()
или простое использование специфичных имен переменных, вы сможете избежать путаницы и конфликтов.