Рейтинг:3

Перекрестные ссылки на переменные Ansible в пределах одного сопоставления

флаг co

Как я могу определить переменную Ansible, чья value — это другая переменная в той же структуре сопоставления.?

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

акме:
  каталог:
    имя хоста: "acme-staging-v02.api.letsencrypt.org"
пустьшифрует:
  config_dir: "/etc/letsencrypt"
  keys_dir: "{{ letsencrypt.config_dir }}/ключи"
  csrs_dir: "{{ letsencrypt.config_dir }}/csr"
  certs_dir: "{{ letsencrypt.config_dir }}/certs"
  account_dir: "{{ letsencrypt.config_dir }}/accounts"
  csr_file: "{{ letsencrypt.csrs_dir }}/{{ site_domain }}.csr"
  account_key_file: "{{ letsencrypt.csrs_dir }}/{{ acme.directory.hostname }}"
  email_address: "сертификат-напоминания@{{site_domain}}"

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

в строке шаблона обнаружен рекурсивный цикл: {{ letsencrypt.config_dir }}/keys

Так что я подумал the lookup вары позволит отложить это решение:

акме:
  каталог:
    имя хоста: "acme-staging-v02.api.letsencrypt.org"
пустьшифрует:
  config_dir: "/etc/letsencrypt"
  keys_dir: "{{ lookup('vars', 'letsencrypt.config_dir') }}/keys"
  csrs_dir: "{{ lookup('vars', 'letsencrypt.config_dir') }}/csr"
  certs_dir: "{{ lookup('vars', 'letsencrypt.config_dir') }}/certs"
  account_dir: "{{ lookup('vars', 'letsencrypt.config_dir') }}/accounts"
  csr_file: "{{ lookup('vars', 'letsencrypt.csrs_dir') }}/{{ site_domain }}.csr"
  account_key_file: >-
    {{ lookup('vars', 'letsencrypt.csrs_dir') }}/{{ acme.directory.hostname }}
  email_address: "сертификат-напоминания@{{site_domain}}"

Это не удается, потому что Ansible пытается немедленно разрешить этот поиск:

Переменная с таким именем не найдена: letsencrypt.config_dir


Конечно, я мог бы разделить их, чтобы они были отдельными переменными. Тем не менее, это противоречит моей цели, состоящей в том, чтобы сгруппировать сильно связанные переменные в одном пространстве имен.

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

Michael Hampton avatar
флаг cz
Это давняя проблема в Ansible, см. [issue #8603](https://github.com/ansible/ansible/issues/8603) для расширенного обсуждения.
Рейтинг:0
флаг co

(Спасибо @michael-hampton за этот ответ.)

Как описано в Проблема #8603, анализатор конфигурации считывает значения переменных и немедленно пытается отобразить шаблоны, с которыми сталкивается при определении переменных. Это приводит к сбою синтаксического анализа, когда шаблон ссылается на еще не полностью определенную переменную.

А комментарий от ârquelibariâ дает хороший анализ:

Эта функция на самом деле четко определена с точки зрения значения ровно одной вещи. Синтаксис и семантика (с точки зрения логики) хорошо определены для такого рода «обратной ссылки». [ ¦ ]

и подробно объясняет, как это происходит.

Последующий комментарий пользователя «cmpunches» прямо указывает необходимое решение:

Эта проблема является прямым результатом использования ansibles парсера yaml. функция интерполяции вместо загрузки объекта yaml и выполнения второго проход для интерполяции. Это не просто ошибка jinja, это ошибка реализации в ansible. Пожалуйста, осмотрите. Загрузка как необработанная строка и затем обработка инициализированных членов объекта во втором проходе должна исправить это.

Таким образом, до тех пор, пока синтаксический анализатор YAML в Ansible не будет исправлен для чтения значений переменных в виде простого текста без попытки немедленного рендеринга шаблонов (и, таким образом, отложить рендеринг до тех пор, пока не будут определены все переменные), эта перекрестная ссылка в значениях еще не может быть сделана в переменных Ansible. .

flowerysong avatar
флаг th
Это вводящее в заблуждение объяснение происходящего, потому что все вычисления переменных происходят лениво (при использовании), а не во время синтаксического анализа. Переменные не могут ссылаться сами на себя, потому что переменная должна быть полностью визуализирована, прежде чем можно будет получить доступ к какой-либо ее части. Изменение этого повлекло бы за собой трудно обосновываемые изменения в обработке переменных и имело бы сомнительную ценность. Лучшим решением является использование переменных пространства имен с префиксами (`letsencrypt_config_dir` и т. д.), вместо того, чтобы пытаться передать все как одну переменную.

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

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