Рейтинг:0

Шаблон Ansible jinja2 из формата JSON предоставляется в виде дополнительных переменных

флаг us

У меня есть этот шаблон jinja2:

# {{ ansible_managed }}

{% для виртуального хоста в nginx_vhosts %}
{%- если vhost.name == item.name -%}

# перенаправление с www на без www
сервер {
    слушать {{ nginx_port }};
    слушать [::]:{{ nginx_port }};
    port_in_redirect выключен;

    имя_сервера www.{{ vhost.name }};
    вернуть 301 http://{{ vhost.name }}$request_uri;
}
{%-конец-%}
{%- конец для -%}

Независимая роль с файлом yaml vhosts.yml, содержащий такие определения:

nginx_vhosts:
      - название: "test1.com"
        репо: "git1"
        ветка: мастер
        состояние: присутствует
      - название: "test2.com"
        репо: "git2"
        ветка: мастер
        состояние: присутствует
...
      - название: "test101.com"
        репо: "git101"
        ветка: мастер
        состояние: присутствует

Задача внутри playbook.yml:

- name: "Создать файл конфигурации nginx vhost"
  шаблон:
    источник: шаблоны/nginx-vhost-template.j2
    dest: "{{ nginx_vhosts_dir }}/{{ item.name }}.conf"
    владелец: "{{ nginx_user }}"
    группа: "{{nginx_group}}"
    режим: 0640
  with_items:
    - "{{nginx_vhosts}}"
  когда:
    - item.state == 'присутствует'
  уведомлять:
    - nginx-перезагрузка

Я запустил такие задачи, как:

ansible-playbook -l web1 playbook.yml --tags=nginx-vhost-config

который работает нормально, он создаст из шаблона файл конфигурации nginx vhost на удаленном сервере как domain1.com.conf и так далее для всех найденных определений.

Предполагая, что в файле vhosts.yml у меня есть test1.com до test100.com, я добавлю, скажем, test101.com и хочу запускать задачи строго для этого test101.com, а не для всех предыдущих хостов. Итак, я попробовал что-то вроде этого:

ansible-playbook -l web1 playbook.yml --tags=nginx-vhost-config -e "{ 'nginx_vhosts': { 'имя': 'test101.com', 'состояние': 'присутствует', 'репозиторий': ' git101", "ветка": "мастер" }}"

Проблема в том, что это приводит к ошибке при попытке заменить значения из шаблона jinja2.

Исключение произошло во время выполнения задачи. Чтобы увидеть полную трассировку, используйте -vvv. Ошибка: ansible.errors.AnsibleUndefinedVariable: 'ansible.parsing.yaml.objects.AnsibleUnicode object' не имеет атрибута 'name'

Я также пытался использовать петля вместо with_items но не повезло.

Я понимаю, что при использовании дополнительных переменных предоставляемый контент находится в формате JSON, но я не смог найти другого способа передать содержимое из vhosts.yml в виде дополнительных переменных для одной записи. Есть ли способ сделать это функциональным?

Может быть, есть лучший подход?

flowerysong avatar
флаг th
Одно небольшое замечание: вы передаете YAML, а не JSON. Он очень похож на JSON, потому что это YAML в потоковом стиле, но его легко отличить, потому что JSON не позволяет использовать одинарные кавычки так, как здесь.
Рейтинг:1
флаг th

Вы передаете объект/словарь, но ваш код ожидает список. Вам нужно либо обернуть его в список, когда вы его передаете, либо учитывать различные возможные структуры при его использовании.

Сначала следует уменьшить количество мест, которые ссылаются nginx_vhosts используя текущий элемент цикла непосредственно в вашем шаблоне:

# {{ ansible_managed }}

# перенаправление с www на без www
сервер {
    слушать {{ nginx_port }};
    слушать [::]:{{ nginx_port }};
    port_in_redirect выключен;

    server_name www.{{ item.name }};
    вернуть 301 http://{{ item.name }}$request_uri;
}

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

"{ 'nginx_vhosts': [{ 'name': 'test101.com', 'state': 'присутствует', 'repo': 'git101', 'ветка': 'master' }]}"

Или немного измените свой цикл:

- name: "Создать файл конфигурации nginx vhost"
  шаблон:
    источник: шаблоны/nginx-vhost-template.j2
    dest: "{{ nginx_vhosts_dir }}/{{ item.name }}.conf"
    владелец: "{{ nginx_user }}"
    группа: "{{nginx_group}}"
    режим: "0640"
  цикл: "{{ [nginx_vhosts] | сгладить}}"
  когда:
    - item.state == 'присутствует'
  уведомлять:
    - nginx-перезагрузка
Bogdan Stoica avatar
флаг us
Теперь это имеет смысл. Отлично работает! Спасибо!

Ответить или комментировать

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