Вопрос или проблема
У меня несколько ролей, а именно: haproxy, java, nginx, tomcat
├── ansible-test-host.yml
├── hapoxy
├── java
├── myplaybook.yml
├── nginx
└── tomcat
Базовая книга игр: myplaybook.yml
выглядит следующим образом:
---
- hosts: test-local
connection: local
vars:
java_version: "1.8.0"
roles:
- java
Итак, моя задача состоит в том, чтобы, в зависимости от указанных ролей java/tomcat/nginx и т.д., у меня есть файл шаблона, который нужно заполнить. Предположим, что моя логика такова:
if
role == java then in template.j2 I have to set `JAVA_TOOL_OPTIONS= -Xmx10g -Xms5g`
elif
role == tomcat then in template.j2 I have to set `JAVA_OPTS= -Xmx10g -Xms5g`
else
NOTHING
endif
У меня есть другие сценарии, которые нужно решить, но если я пойму основы, остальное я смогу сделать.
Что я пытался сделать в main.yml роли java, здесь
---
# tasks file for java
- name: выводить 'ansible_' магические переменные
debug:
msg: [
"ansible_role_names = {{ ansible_role_names | default({}) }}",
"ansible_dependent_role_names = {{ ansible_dependent_role_names }}",
"ansible_play_role_names = {{ ansible_play_role_names | default([]) | join(',') }}"
]
- name: установить факты
set_fact:
DEFAULT_VAR: >
{% if "{{ ansible_play_role_names | default([]) | join(',') }}" == "java" %}
JAVA_TOOL_OPTIONS
{% elif "{{ ansible_play_role_names | default([]) | join(',') }}" == 'tomcat' %}
CATALINA_OPTS
{% else %}
NOTHING
{% endif %}
- name: вывод моей пользовательской переменной - проба1
debug:
msg: >
{% if "{{ ansible_play_role_names | default([]) | join(',') }}" == "java" %}
JAVA_TOOL_OPTIONS
{% else %}
NOTHING
{% endif %}
- name: вывод моей пользовательской переменной - эхо
debug:
msg: "{{ DEFAULT_VAR }}"
Мой вывод таков
TASK [java : выводить 'ansible_' магические переменные] ****************************************************
ok: [127.0.0.1] => {
"msg": [
"ansible_role_names = ['java']",
"ansible_dependent_role_names = []",
"ansible_play_role_names = java"
]
}
TASK [java : установить факты] ********************************************************************************
ok: [127.0.0.1]
TASK [java : вывод моей пользовательской переменной - проба1] ***************************************************************
ok: [127.0.0.1] => {
"msg": " NOTHING \n"
}
TASK [java : вывод моей пользовательской переменной - эхо] **************************************************************
ok: [127.0.0.1] => {
"msg": " NOTHING \n"
}
PLAY RECAP *********************************************************************************************
127.0.0.1 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Пожалуйста, помогите с указаниями для достижения этого.
Я знаю, что это старый вопрос, но я пытался разобраться сам и, похоже, нашел ответ. (Так что, если это поможет кому-то в будущем…)
Я думаю, проблема в ваших кавычках в условных операторах. Вот мой тестовый пример. Обратите внимание на отсутствие/сокращение кавычек в операторах if/elif:
- name: выполнения тестового набора
hosts: "{{ host_list }}"
remote_user: root
vars:
list_one: [ "lead", "up", "to", "one" ]
list_two: [ "one", "two" ]
list_three: ["one", "two", "three" ]
tasks:
- name: установить булевы значения на основе фактов
ansible.builtin.set_fact:
my_list: >-
{%- if ansible_facts["distribution_major_version"] == '6' -%}
{{ list_one }}
{%- elif ansible_facts["distribution_major_version"] == '7' -%}
{{ list_two }}
{%- elif ansible_facts["distribution_major_version"] == '8' -%}
{{ list_three }}
{%- else -%}
["nothing", "else"]
{% endif %}
- name: вывод моей пользовательской переменной - эхо
debug:
msg: "{{ ansible_facts['distribution_major_version'] }} results in {{ my_list }}"
Ответ или решение
Определение переменных Ansible на основе условий: использование if
, elif
, else
Введение
Ansible является мощным инструментом для автоматизации управления конфигурацией и развертыванием приложений. В Ansible вы можете использовать условные конструкции внутри ваших плейбуков и роли для динамического определения переменных. В данном руководстве мы рассмотрим, как правильно определить переменные в зависимости от заданной роли, используя конструкции if
, elif
, и else
.
Структура проекта
В вашем проекте вы имеете следующую структуру:
├── ansible-test-host.yml
├── haproxy
├── java
├── myplaybook.yml
├── nginx
└── tomcat
Ваш основной плейбук (myplaybook.yml
) выглядит следующим образом:
---
- hosts: test-local
connection: local
vars:
java_version: "1.8.0"
roles:
- java
Цель
В зависимости от роли (java
, tomcat
, nginx
и т.д.), вам нужно установить определенные переменные, которые будут использоваться в шаблоне. Логика для определения переменной такова:
- Если роль
java
, установитьJAVA_TOOL_OPTIONS= -Xmx10g -Xms5g
- Если роль
tomcat
, установитьJAVA_OPTS= -Xmx10g -Xms5g
- В противном случае ничего не делать.
Правильная реализация
Для решения вашей задачи нужно сделать следующие шаги:
- Уберите ненужные кавычки из условий.
- Примените
set_fact
для определения нужных переменных.
Вот как это может выглядеть в вашем main.yml
для роли java
:
---
# tasks file for java
- name: Устанавливаем опции Java на основе роли
set_fact:
java_options: >
{%- if 'java' in ansible_play_role_names -%}
JAVA_TOOL_OPTIONS=-Xmx10g -Xms5g
{%- elif 'tomcat' in ansible_play_role_names -%}
JAVA_OPTS=-Xmx10g -Xms5g
{%- else -%}
""
{% endif %}
- name: Вывод установленной переменной
debug:
msg: "Установленные опции: {{ java_options }}"
Пояснения к коду:
ansible_play_role_names
возвращает список всех ролей, определенных для выполнения в плейбуке.- Мы проверяем, содержится ли
'java'
или'tomcat'
в этом списке, без использования избыточных кавычек. set_fact
позволяет вам создавать или изменять переменные, которые могут использоваться в других задачах или шаблонах.debug
используется для вывода значения переменной и проверки корректности выполнения.
Применение в шаблоне
Теперь, когда у вас есть переменная java_options
, вы можете использовать ее в своих шаблонах (template.j2
) следующим образом:
# template.j2
{% if java_options %}
export {{ java_options }}
{% else %}
# Нет специфичных опций для заданной роли
{% endif %}
Заключение
Правильное использование условных конструкций в Ansible позволяет динамически адаптировать поведение ваших плейбуков в зависимости от контекста их выполнения. Убедитесь, что вы избегаете ненужных кавычек и используете правильный синтаксис при проверке условий. Теперь вы можете легко добавлять другие роли и соответствующие им переменные, следуя приведенному примеру.