Ansible: отдельные переменные group_vars перезаписываются при развертывании на том же хосте

Созданный на 19 сент. 2014  ·  71Комментарии  ·  Источник: ansible/ansible

Тип проблемы:

Сообщение об ошибке

Версия Ansible:

доступный 1.6.1

Окружающая обстановка:

Mac OS X

Резюме:

Если у нас есть файл hosts:

[service1]
www.host1.com

[service2]
www.host1.com

и у нас есть эти group_vars:

group_vars/service1:
    database_host: "www.database.com"
    database_port:  3306

group_vars/service2:
    database_host: "www.differentdatabase.com"
    database_port:  3306

и мы запускаем этот сценарий:

- hosts: service1
  remote_user: root

переменные из group_vars / service1 и group_vars / service2 перезаписывают друг друга, если мы выполняем развертывание на одном сервере. Это означает, что service1 получит переменные группы service2 и получит неверный хост и порт базы данных.

чтобы их обойти, мы добавили записи DNS (псевдонимы для www.host1-service.com), чтобы наш хост выглядел так:

[service1]
www.host1-service1.com

[service2]
www.host1-service2.com

но это очень подвержено ошибкам и не идеально. Какими способами можно обойти эту проблему? (или неправильное понимание group_vars)

Я выполняю развертывание в нескольких средах следующим образом:

inventory/stage/hosts
inventory/stage/group_vars/
inventory/stage/group_vars/service1
inventory/stage/group_vars/service2

inventory/live/hosts
inventory/live/group_vars/
inventory/live/group_vars/service1
inventory/live/group_vars/service2
Действия по воспроизведению:

Резюме описывает, как это воспроизвести.

Ожидаемые результаты:

group_vars не должны перезаписываться другой группой при совместном использовании одного и того же хоста

Фактические результаты:

group_vars перезаписываются другой группой при совместном использовании одного и того же хоста

Самый полезный комментарий

Это так глупо. Я просто потратил много часов, пытаясь отладить проблему с переменной, только чтобы обнаружить, что это было из-за какой-то глупой философии дизайна (это). По крайней мере, должно быть предупреждение, когда несколько файлов group_var загружаются для одного и того же хоста.

Все 71 Комментарий

У меня также есть эта проблема, похоже, что vars анализируются и прикрепляются к хосту, а не остаются с группой.

Действия по воспроизведению:

Файл Hosts:

[aaa]
host1
host2

[bbb]
host2
host3

[aaa:vars]
foo=aaa

[bbb:vars]
foo=bbb

Выполните команду для каждой группы:

$ ansible -i hosts aaa -m shell -a "echo {{ foo }}"
host1 | success | rc=0 >>
aaa

host2 | success | rc=0 >>
bbb

$ ansible -i hosts bbb -m shell -a "echo {{ foo }}"
host2 | success | rc=0 >>
bbb

host3 | success | rc=0 >>
bbb

Ожидаемые результаты:

Переменная foo=aaa назначается группе aaa и должна выводиться при выполнении команд для группы aaa

Фактические результаты:

host2 выводит переменную из группы bbb

Есть такая же проблема.

Пример:

./group_vars/group1:

---
name: group1

./group_vars/group2

---
name: group2-default

файл hosts:

[group1]
host1

[group2]
host1

Итак, когда я пытаюсь запустить playbook только для group1 , я получаю такой результат:
Переменная name имеет значение group2-default, но ожидается, что она будет иметь значение group1 .

Есть ли обходной путь для этого?

Вары инвентаря объединяются, даже если вы не используете эту группу, последняя группа
объединенные победы

Брайан Кока

@bcoca Почему это так работает? Это ожидаемое поведение или реальная ошибка?

У вас могут быть файлы vars / service (1,2,3, ...)

И передайте service = 1 как дополнительные vars

Затем для хостов, на которые вы нацелены в playbook, используйте служебную переменную,
а также какой файл vars вы импортируете

Мы делаем то же самое для импорта варов на основе дополнительных переменных среды.
26 ноября 2014 г. в 15:12 «arianitu» [email protected] написал:

@bcoca https://github.com/bcoca Почему это так работает? Это
ожидаемое поведение или фактическая ошибка?

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/ansible/ansible/issues/9065#issuecomment -64718173.

У меня такая же проблема с 1.8.4 сегодня.
В конце концов, это правильное поведение или нет?
Кто-нибудь знает прогресс?

Хм. Похоже, теги bug_report здесь неправильные. Это не ошибка, а .. особенность :-)
Так что да, это правильное поведение.

Как сказал @hashnz , «вары разбираются и привязываются к хосту, а не остаются с группой», что совершенно правильно.

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

При нацеливании на группу во время playbook на самом деле только определяет, какие хосты находятся в прогоне, это ничего не меняет на уровне переменных.

Доступным способом здесь было бы установить хост и порт базы данных в списке и перебрать его в задачах.

@bcoca @

@srvg Большое спасибо! Я понял. Попробую без group_vars.

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

У кого-нибудь есть обходной путь для этого?

мы не можем использовать статические переменные в playbook, поскольку нам нужно различать разные среды (обрабатываются разными файлами инвентаризации) и нужно запускать с разными переменными, в зависимости от запуска группы, даже если они выполняются на том же хосте, что и другая группа

Используйте CNAME для того же имени хоста или IP-адреса. Это единственный
я нашел обходной путь. Проблема возникает, когда вы используете Ansible Tower,
потому что вы тратите впустую лицензию с такими CNAME. Ансибл не хочу
исправьте эту ошибку, назвав ее "функцией", но на самом деле это настоящая ошибка, которая должна
быть исправленным.
28 Апр 2015 г. 17:16 пользователь "SkaveRat" [email protected]
написал:

У кого-нибудь есть обходной путь для этого?

мы не можем использовать статические вары в playbook, так как нам нужно различать
между разными средами (обрабатывается разными файлами инвентаризации) и
нужно запускать с разными переменными, в зависимости от группового запуска, даже
они работают на том же хосте, что и другая группа

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/ansible/ansible/issues/9065#issuecomment -97077453.

Он был исправлен, но отклонен. https://github.com/ansible/ansible/pull/6666

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

http://docs.ansible.com/playbooks_best_practices.html

Рекомендуется определять группы в зависимости от назначения хоста (ролей), а также географии или расположения центра обработки данных (если применимо).

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

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

Мы уже следим за http://docs.ansible.com/ansible/playbooks_best_practices.html#staging -vs-production, выполняя разные инвентаризации для разных сред.

Почему с Ansible это кажется таким сложным? Ansible плохо справляется с развертыванием на основе среды?

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

Например, у меня есть служба аутентификации с переменной authentication_db_host: 127.0.0.1 для стадии и authentication_db_host: 192.168.2.4 для live. Вы хотите, чтобы у меня было 2 переменных?

authentication_db_host_stage: 127.0.0.1
authentication_db_host_live: 192.168.2.4

Теперь мне сложно передать это в общий файл шаблона. Мне нужно добавить проверки if else во всем моем файле j2 (и мы пошли по этому пути, но это было слишком много дублирования, и мы избавились от него).

Я не нашел никакой документации, касающейся этого случая, и похоже, что это не должно быть сложно.

Вот как мы это делаем:

Экземпляр AWS с тегом:

someapi: prod

playbook someapi.yml

  • хосты: tag_someapi _ {{env}}
    gather_facts: правда
    пользователь: ec2-user
    vars_files:

    • vars / aws _ {{env}}

    задания:

    • fail: msg = "Env должен быть определен"
      когда: env не определен
      роли:
    • Someapi
      ...

Выполнение с дополнительными варами

ansible-playbook -vv someapi.yml -e "env = prod"

роли / someapi / задачи / main.yml

  • name: включить переменные, относящиеся только к someapi.
    include_vars: someapi _ {{env}}. yml
  • имя: Разместите конфигурацию
    шаблон: src = config.j2
    dest = {{someapi_install_directory}} / configuration.properties
    ...

роли / someapi / vars / someapi_prod.yml

host_db_ аутентификации: 192.168.2.4

роли / someapi / vars / someapi_stag.yml

authentication_db_host: 127.0.0.1
...

роли / someapi / шаблоны / config.j2

authentication_db_host = {{authentication_db_host}}
...

HTH,

Иэн Райт

Это электронное письмо является конфиденциальным и предназначено только для получателей.
названный выше и может содержать информацию, которая является привилегированной, освобожденной от
раскрытие информации в соответствии с действующим законодательством. Если вы не являетесь предполагаемым получателем, сделайте
не разглашать и не распространять сообщение никому, кроме предполагаемых
получатель. Если вы получили это сообщение по ошибке или не являетесь
получатель (-ы), пожалуйста, немедленно уведомите отправителя по электронной почте, и
удалить все копии этого сообщения.

Пт, 16 октября 2015 г., в 12:42, arianitu [email protected] написал:

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

Мы уже следим
http://docs.ansible.com/ansible/playbooks_best_practices.html#staging -vs-production,
путем проведения различных инвентаризаций для разных сред

Почему с Ansible это кажется таким сложным? Ansible плохо справляется
развертывания на основе среды?

Пожалуйста, предоставьте полный пример, потому что "Возможный способ здесь -
установить хост базы данных и порт в списке, и перебрать его в задачах ".
для меня не имеет никакого смысла. Где здесь указано окружение?

Например, у меня есть служба аутентификации с переменной с именем authentication_db_host:
127.0.0.1 для Stage и authentication_db_host: 192.168.2.4 для live. Делать
вы хотите, чтобы у меня было 2 переменных?

authentication_db_host_stage: 127.0.0.1
authentication_db_host_live: 192.168.2.4

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

Я не нашел никакой документации, касающейся этого случая, и кажется
как то, что не должно быть трудным.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/ansible/ansible/issues/9065#issuecomment -148816278.

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

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

Если я правильно понимаю, как это работает - для будущих читателей вроде меня, которым трудно понять:

  1. Группы хостов в файлах инвентаризации определяют группы хостов. Групповые переменные определяют, какие переменные должны быть установлены для хостов в этой группе.
  2. Когда я указываю группу, которая будет использоваться для воспроизведения playbook, это означает взять все хосты, принадлежащие этой группе.
  3. Каждая игра проводится отдельно для каждого хоста - нет контекста, какая группа развертывается. Группы используются для группировки хостов и групповых переменных - для установки общих переменных для этих хостов.
  4. Таким образом, если хост упоминается в нескольких группах, и эти группы имеют одну и ту же переменную с разными значениями, хосту сообщается, что, поскольку он принадлежит к первой группе - переменной для него присваивается значение группы; тогда, поскольку хост принадлежит другой группе, та же самая переменная с другим значением устанавливается как тень предыдущего значения.

Основная проблема заключается в том, что доступные переменные слияния даже из групп, которые я не
хочу поиграть прямо сейчас. Мне не нужно проверять переменные из группы, я не
играет в это время. Возможно, полу-решение - проверить переменные
только те группы, в которых был запланирован запуск playbook.

вс, 17 Янв 2016, 20:00, Виктор Варварюк [email protected] :

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

  1. Группы хостов в файлах инвентаризации определяют группы хостов. Группа
    переменные определяют, какие переменные должны быть установлены для хостов в этом
    группа.
  2. Когда я указываю группу, которая будет использоваться для воспроизведения playbook, это означает, что
    взять все хосты, принадлежащие этой группе.
  3. Каждая игра разыгрывается отдельно для каждого хоста - контекста нет.
    какая группа развертывается. Группы используются для группировки хостов и группировки
    vars - чтобы установить общие переменные для этих хостов.
  4. Итак, если хост упоминается в нескольких группах, и эти группы имеют
    одна и та же переменная с разными значениями, хосту сообщается, что, поскольку он
    принадлежит к первой группе - переменная для него установлена ​​в группу
    значение; тогда, поскольку хост принадлежит другой группе, та же переменная
    с другим значением устанавливается затенение предыдущего значения.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/ansible/ansible/issues/9065#issuecomment -172353019.

Это кажется очень нелогичным.

У меня есть инвентарь, в котором есть только мой бродячий ящик в каждой группе для тестирования.

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

28 апреля 2016 г. в 17:55 Филип Вигг [email protected] написал:

Это кажется очень нелогичным.

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

У меня есть инвентарь, в каждой группе которого есть только ящики Vagrant для
в целях тестирования.

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

Не смотрите на инвентарь как на тесно связанный с пьесами. Инвентарь
это в значительной степени отдельная вещь, где

  • хосты могут быть членами нескольких групп и, как таковые, нацелены на
    ansible (ad-hoc) или ansible-playbook (playbooks), указав на один из
    группы, в которые входит хост.
  • разрешение переменных выполняется для всего инвентаря, независимо от того, нацеливаете ли вы
    конкретная группа или всемогущая встроенная группа "все" не меняет этого
    переменные наследуются, разрешаются и вычисляются, глядя на все
    определения групп и все групповые переменные, которые существуют в инвентаре.

HTH,

Serge

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

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

Может ли кто-нибудь указать мне, как лучше сделать это или как обойти это? Я чувствую, что могу злоупотреблять концепцией ролей или инвентаря, заставляя мою роль "vhosts" принимать массив vhosts (vhost не совсем "роль" в том смысле, что вы не говорите серверу "вы являетесь вид "). Может ли кто-нибудь предложить лучший способ сделать это или поделиться своими мыслями?

Между прочим, нашли время ответить мне - это было очень оценено и прояснило мое понимание.

Мое решение.

[service1]
host1 ansible_ssh_user = host1.com

[service2]
host2 ansible_ssh_user = host1.com

Это так глупо. Я просто потратил много часов, пытаясь отладить проблему с переменной, только чтобы обнаружить, что это было из-за какой-то глупой философии дизайна (это). По крайней мере, должно быть предупреждение, когда несколько файлов group_var загружаются для одного и того же хоста.

Меня очень раздражает случайная загрузка group_vars. Это делает невозможным наследование в таком случае все> центр обработки данных> среда (интег, разработка, продукт)> приложение> хост

Это очень легко сделать с марионеточной хиерой, но с недоступностью это боль, и, когда у вас есть> 100 пьес / ролей для поддержки, загрузка переменных явно не обязательна, потому что вы должны поддерживать файл vars_file + файл group_vars для той же функции .
Возможно, наличие тега в файле (vars_priority) или использование имени файла для исправления порядка загрузки может быть хорошим (например, apache), например

  • all.yml
  • 10_datacenter_a.yml
  • 10_datacenter_b.yml
  • 20_env_production.yml
  • 40_app_gitlab.yml

затем gitlab загружает переменные группы для каждого имени, здесь - центры обработки данных, после env и, наконец, приложение.

Я очень рад видеть, что я не одинок в этой чуши! Группы vars должны применяться к HIS группе узлов. Как в мире должна быть объяснена директива --limit, чем? Естественный образ мышления таков: хорошо, я "ограничиваю" эту пьесу размещением в ЭТОЙ группе, так что ЭТА группа варов получит поддержку !!!! Не определение переменных в других группах для того же самого хоста, это не имеет никакого смысла!

Я надеюсь, что это будет исправлено, а пока я откажусь от использования нескольких записей DNS для одного и того же хоста.

Просто потратил несколько часов на то, чтобы биться головой об стол, пытаясь обойти эту проблему. Учитывая то количество разговоров, которые вызывают эту проблему, я очень удивлен, что Ansible (или Red Hat) позволяет этому продолжаться.

Зачем полагаться на абстракцию group_vars для слияния переменных и определения того, что
нужно в первую очередь?

Я не могу придумать вескую причину, чтобы явно не определять и не включать вары
(простейший пример включен в ветку выше)

Иэн Райт

Это электронное письмо является конфиденциальным и предназначено только для получателей.
названный выше и может содержать информацию, которая является привилегированной, освобожденной от
раскрытие информации в соответствии с действующим законодательством. Если вы не являетесь предполагаемым получателем, сделайте
не разглашать и не распространять сообщение никому, кроме предполагаемых
получатель. Если вы получили это сообщение по ошибке или не являетесь
получатель (-ы), пожалуйста, немедленно уведомите отправителя по электронной почте, и
удалить все копии этого сообщения.

Во вторник, 27 сентября 2016 г., в 11:53, Джейсон Хейн [email protected]
написал:

Просто провел несколько часов, бился головой об стол, пытаясь обойти
Эта проблема. Из-за количества болтовни, эта проблема становится все больше.
удивленный Ansible (или Red Hat) позволяет этому продолжаться.

-
Вы получили это, потому что оставили комментарий.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/ansible/ansible/issues/9065#issuecomment -249961581,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AATjccSt7D7FJfzdA8r86kb1GQvxLBnaks5quWY4gaJpZM4Cjyd4
.

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

Запуск всех хостов - это другая история, но, по крайней мере, тогда должно быть четкое предположение, что Ansible будет захватывать все переменные для всех групп, в которых находится хост. Ansible должен либо лучше справляться с этими предположениями, либо предоставлять флаг, который позволяет такое поведение .

Зачем полагаться на абстракцию group_vars для слияния переменных и определения того, что
нужно в первую очередь?

В этом ТОЧНО суть абстракции! Если этот инструмент позволяет мне абстрагировать мою среду в разных группах, а затем, применяя четкие правила вывода, сделать вывод, какие переменные следует использовать, почему бы не использовать его?!? Итак, здесь есть 2 проблемы: правила не ясны или абстракция не работает. В противном случае объясните мне назначение groups_vars, если мне нужно явно определить и включить vars?

Я должен сказать, что в документации не упоминается этот конкретный случай, когда один и тот же хост был включен в несколько group_vars. Но этот случай очень реален для хоста, где существует несколько экземпляров службы (например, apache). Я очень надеюсь, что эта проблема скоро решится.

Мы нашли способ решить нашу проблему app / env с наследованием переменных путем перекрестного определения переменных между группами с использованием префикса.
например

app_collectd.yml
collectd_host: "{{env_collectd_host}}"

env_production.yml
env_collectd_host: 1.1.1.1

то теперь это не проблема, у нас есть четкие переменные приложения + переменные env с использованием переменных перекрестного вызова

Я приехал из страны марионеток, где абстракция и повторное использование кода просты и понятны. Возможно, я неправильно понимаю, как Ansible подходит к этому, поэтому, если есть лучший способ, не связанный с group_vars, я все уши. Чего я не хочу делать, так это поддерживать другой набор переменных для каждого хоста или группы, чтобы указать, где он должен получать свои переменные. Для меня это должно быть ответственностью фреймворка. В этом прелесть иеры в Марионетке.

@hyojinbae

Мое решение.

[service1]
host1 ansible_ssh_user = host1.com

[service2]
host2 ansible_ssh_user = host1.com

можешь подробно объяснить?

Я тестирую его вот так, не такой, как ваш, но он работает!

[service1]
host1 ansible_host=192.168.0.10

[service2]
host2 ansible_host=192.168.0.10

Здесь еще одна жертва.

Кто-нибудь придумал хорошее решение для следующего сценария?

Допустим, у меня есть список веб-приложений (app-a, app-b, app-c). И есть 4 хоста в 2 DC для DR / балансировки нагрузки. Я хочу использовать ansible для упрощения развертывания.

Мой первый инстинкт - использовать групповые вары, очевидно, я потерпел неудачу, но какую альтернативу предлагает Ansible?

инвентарь

[dc1]
host1
host2

[dc2]
host3
host4

[cluster:children]
dc1
dc2

[app-a:children]
cluster

[app-b:children]
cluster

[app-c:children]
cluster

groups_vars
приложение-а

http_port: 8081

приложение-б

http_port: 8082

приложение-c

http_port: 8083

playbook в основном ожидает, что хосты переданы через командную строку:

- host: {{app-name}}
- tasks: 
  # deploy application with given {{http_port}}....

Это то, что я делаю, чтобы обойти это

- hosts: "{{ app-name }}"

vars_files:
    - "vars/{{ app-name }}.yml"

@hanej Спасибо, это определенно указывает на направление, о котором я не знал.
Однако теперь я больше склоняюсь к использованию ролей для повторного использования кода и объявляю переменные непосредственно в playbook. Несмотря на то, что это означает, что у меня будет один playbook для каждого приложения, но, объявив переменную рядом с ролью, которая будет ее использовать, значительно упростит понимание всей конфигурации.

@hanej Спасибо, это замечательное решение. Вы спасли меня.

@hanej Genius!

Я так удивлен, что это вообще проблема. Я сталкиваюсь с этим, потому что у меня есть одна роль, которую я использую с несколькими группами инвентаризации, которые имеют связанные файлы group_var. В QA / Prod это не проблема, потому что каждая группа инвентаризации имеет разные серверы. Но для сред уровня интеграции мы склонны разбивать все на отдельные серверы (вот почему я вижу эту проблему).

Следуя совету Ханеджа, я изменил свой playbook yml, чтобы просто явно загрузить файл group_var:

hosts: publish
vars_files:
  - group_vars/publish.yml

"Это так глупо. Я просто потратил много часов, пытаясь отладить проблему с переменной, только чтобы обнаружить, что это было из-за какой-то глупой философии дизайна (это). По крайней мере, должно быть предупреждение при загрузке нескольких файлов group_var для одного и того же хоста. "

Просто чтобы обновить эту "ПРОБЛЕМУ" / "ОГРАНИЧЕНИЕ"
Хорошо, мы можем использовать обходной путь для устранения конфликта (с доступным хостом или другим способом)
но лучше всего использовать переменную в файле ansible.cfg для определения:
"вложить group_vars" или "merge group_vars"

Я не могу использовать group_vars только по этой причине. У нас есть хосты в нескольких группах (DC, среда, приложение и т. Д.), И мы не можем контролировать, как считываются переменные. Переход с Puppet с использованием Hiera - это большое дело. На мой взгляд, Ansible должен принять что-то вроде Hiera, используя шаблон «роли и профили», где вы можете указать порядок использования переменных на основе фактов или групп. Я как бы делаю это сейчас, используя подход, описанный выше.

Например, если у вас есть хост с ролью «/ Linux Hosts / Applications / Java / Website», вы должны иметь возможность наследовать переменные от хостов Linux (переменные глобального уровня, такие как sysctl, DNS, NTP и т. Д.), Applications (global переменные уровня приложения), Java (переменные, специфичные для Java, такие как версия JDK, JAVA_HOME и т. д.) и Website (переменные, относящиеся конкретно к приложению веб-сайта). Чем дальше вы спускаетесь по дереву, тем более конкретными становятся переменные, которые могут переопределить переменные, расположенные выше.

Использование Ansible для запусков, управляемых событиями или adhoc, - это здорово и работает очень хорошо, однако я считаю, что использование Ansible для управления конфигурацией не так просто и не так просто, как Puppet и Hiera, в основном по этой причине.

Спустя 2 года я все еще получаю постоянный поток электронных писем по этой проблеме (это также одна из самых комментируемых проблем в этом github). По-прежнему ли разработчики Ansible считают, что текущее поведение правильное, хотя неинтуитивно?

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

Мы решили полностью отказаться от использования Ansible. Это отстой при управлении конфигурацией, и точка.

Удачи с проектом.

Да, просто столкнулся с той же проблемой при настройке процесса развертывания файлов конфигурации для разных сред при тестировании на одном хосте. Я собираюсь принять весь метод {{app-name}} - {{env}}. Yml , предложенный

Счастлив, что я обнаружил эту проблему после того, как бился головой об стену в течение бесчисленных часов ... И я крайне удивлен пренебрежительным отношением сопровождающих к этой ошибке, назвав ее «особенностью», это глупо до неузнаваемости.

Я пытаюсь настроить общий сценарий развертывания / роль, используя динамический инвентарь. Вывод инвентаризации выглядит так:

{
  "resource-service_ci": {
    "vars": {
      "nginxpool": "resource_pool",
      "httpport": "8800"
    },
    "hosts": ["host1.example.com", "host2.example.com"]
  },
  "example-service_ci": {
    "vars": {
      "nginxpool": "example_pool",
      "httpport": "8100"
    },
    "hosts": ["host1.example.com","host3.example.com"
    ]
  }
}

К сожалению, на одном хосте может быть несколько приложений. Вся суть в использовании динамического инвентаря испаряется, если групповые вары «случайным образом» перемешиваются и возвращаются вместо наследования переменных только для той группы, которую я использую --limit с

Я попробовал обходной путь

_ "hosts": ["host1 ansible_host = host1.example.com", "host2 ansible_host = host2.example.com"] _

но Ansible явно не понимает, что пытается ssh на host1 ansible_host = host1.example.com

Кто-нибудь еще сталкивается с той же проблемой, и если да, есть ли способ ее решения?

Я мог бы передать переменные порта и пула в командной строке, поскольку они имеют приоритет, но тогда мне придется выполнить некрасивый поиск раньше.

Отлично проводил время с Ansible, пока не обнаружил эту ошибку.

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

То, что казалось одной из самых мощных функций Ansible, не работает так, как все ожидают.

Пожалуйста, давайте исправим это.

Я часами бился головой о стол, пытаясь обойти эту проблему. Пожалуйста, исправьте эту проблему.

Эта "функция" потратила зря большую часть моего дня. Не смешно.

@hanej Спасибо за довольно элегантный обходной путь. Теперь мы устанавливаем переменную env в наших файлах environment/group_vars/all на имя среды.

Затем в наших сценариях мы делаем следующее:

- hosts: group
  vars_files:
    - "{{ env }}/group_vars/group.yml
  roles:
    - ...

Я знаю, что прошло 2,5 года и что Ansible, вероятно, никогда не обратит на это внимания, но я просто добавлю свое разочарование по этому поводу. Зачем разрешать пользователям размещать хост в нескольких группах, если вы не можете использовать группы по отдельности?

Зачем разрешать пользователям размещать хост в нескольких группах

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

Мы отфильтровываем закрытые проблемы и не видим комментариев к ним, но кто-то попросил меня ответить на некоторые из этих вопросов. Если вы хотите, чтобы разработчики обратили внимание на рассылку или IRC, лучше использовать закрытые тикеты.

Ansible смотрит на группы как на свойства хоста. Например, у вас может быть хост, входящий в группу веб-серверов (для установки требований веб-сервера) и часть группы northeast_datacenter (чтобы вы знали сетевой шлюз, серверы ntp и dns для установки), а также часть группы dev_group для установки инструментов разработчика. и укажите на непроизводственную базу данных и т. д. и т. д.

Вы МОЖЕТЕ использовать группы как способ нацеливания на хосты, но это не означает, что другие «свойства хоста» исчезнут. Я принадлежу к группе «мужчин» и «программистов», потому что я не перестаю быть мужчиной только потому, что вы «выбираете меня» как программиста.

В конце концов, это дизайнерское решение (а не ошибка) о том, как работать с группами, способ классификации и добавления свойств к хостам. Я знаю, что другие инструменты используют их по-разному, но это не причина менять то, как они работают в Ansible, поскольку нет единого способа, которым ВСЕ другие инструменты используют группы, многие другие смотрят на них так же, как и многие.

Это имеет ограничение, заключающееся в невозможности повторно использовать имена переменных и использовать только «текущую группу», но оно имеет то преимущество, что всегда видит более широкую картину того, как определен хост, и упрощает обнаружение или разрешение конфликтов. В большинстве приведенных выше случаев использование vars_files или include_vars кажется более подходящим, чем настройка в виде групп, когда речь идет о переменных, специфичных для приложения.

Выполнение include_vars для group_vars ... ну, это не то, как мы его спроектировали, но если это работает для вас ... предостережение в том, что вы выполняете "двойную загрузку", поскольку group_vars автоматически втягиваются, это может привести к проблемам с производительностью в больших запасы. Мы рекомендуем более конкретные, vars_files: vars/app1.vars.yml или аналогичные с include_vars.

Я надеюсь, что это проясняет, почему группы работают так, как они работают в Ansible, и почему это отличается от «другого конкретного инструмента», дайте мне знать, если есть что-нибудь, что я могу добавить в наши документы http://docs.ansible.com/ansible/ intro_inventory.html, чтобы прояснить

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

@bcoca можно ли обнаружить случаи, когда групповые переменные используются странным образом (извините, не могу сформулировать это лучше - не использовал это в течение длительного времени) и делать предупреждения, чтобы помочь пользователям сэкономить свое время?

@bcoca Что для меня непонятно, и я думаю, что большинство остальных комментаторов по этому вопросу, так это то, какую ценность команда Ansible стремится сохранить, сохраняя приоритет / разрешение group_var таким, каким он является.

Можете ли вы привести пример кейса, который хорошо удовлетворяется текущим решением, но перестанет быть таковым, если, скажем, group_vars загружаются / учитываются только для групп, выбранных для данной игры, а не для всего инвентаря?

Кажется, довольно легко придумать примеры, которые сломаны тем, что есть сейчас.

Я понимаю точку зрения @bcoca , поскольку мы тоже ее используем. Мое самое большое разочарование в Ansible заключается в том, что он в основном хорошо работает как для управления конфигурацией, так и для специальных рабочих процессов. Он не очень хорошо справляется с этим, но становится лучше, и у него есть поддержка плагинов, которые, я думаю, я буду использовать, чтобы улучшить еще одну проблему, которая у меня есть. В большинстве случаев я все еще скучаю по Puppet исключительно из-за управления конфигурацией ...

Вероятно, лучший вариант использования group_vars - это несколько центров обработки данных. Допустим, ваш файл инвентаря выглядит так:

[dc1]
host1
host2

[dc2]
host3
host4

[app1]
host1
host3

[app2]
host2
host4

Вы можете использовать group_vars для установки переменных, специфичных для центра обработки данных, которые будут унаследованы всеми хостами в этом центре обработки данных.

group_vars/
    dc1.yml
    dc2.yml
    app1.yml
    app2.yml

dc1.yml

---
ntp_servers:
  - 10.10.10.10
  - 10.10.10.11

dc2.yml

---
ntp_servers:
  - 10.11.10.10
  - 10.11.10.11

Подобное использование group_vars подходит до тех пор, пока вам не понадобится объединить или переопределить переменную в другом файле group_var. Это еще один случай, когда group_vars выходит из строя. Невозможно установить порядок, в котором переменные читаются в group_vars. Здесь на ум приходит иерархическая структура (например, Hiera), которая может быть определена фактами, а не группами для таких вещей, как переменные среды, но я отвлекся.

С моей точки зрения, этот вариант использования в основном хорош для прямого управления конфигурацией, но не так хорош для развертываний или специальных сценариев. Вот почему я хотел бы увидеть переключатель, чтобы отключить эту функцию для определенных playbooks, где вы не хотите этого делать.

@hanej Я не уверен, как этот пример ломается из-за изменения дизайна, которое я предложил в моем предыдущем комментарии?

С учетом перечисленного вами инвентаря, если я ansible-playbook -i /my-inventory -v some_playbook.yml -l dc1:&app2 Any some_playbook.yml вы напишете против этого инвентаря, должен быть достаточно надуманным, чтобы он сломался, когда переменные из dc1.yml Были загружены только app1.yml .

Я согласен с тем, что развертывание - это проблема. В частности, многопользовательские развертывания.

Меня беспокоит то, как все работает сейчас:

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

Во-вторых, дело, о котором здесь все говорят. Я ожидал, что с приведенным ниже списком я никогда не получу файлы, записанные в /data/prod когда я запустил ansible-playbook -i inventory -v data_deploy.yml -l app1_staging , и эти файлы никогда не будут записаны в /data/staging когда я бегу ansible-playbook -i inventory -v data_deploy.yml -l app1_prod

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

Пример инвентаря.

[dc1]
host1
host2

[dc2]
host3
host4

[app1_staging]
host1
host2
host3
host4

[app1_prod]
host1
host2
host3
host4

app1_staging.yml:

---
  data_path: /data/staging

app1_prod.yml:

---
  data_path: /data/prod

Не знаю, сработало ли изменение для настройки уведомления, мой последний комментарий должен был быть направлен на @hanej.

@benjamincburns Вы просили привести пример использования group_vars, который удовлетворяет текущему методу загрузки, но не работает, если используются только непосредственные группы. Я представил это на примере центра обработки данных. Если Ansible не загружает переменные для всех групп, вы не можете устанавливать переменные, например, на уровне центра обработки данных.

Я считаю, что это должен быть переключатель в ansible.cfg или в командной строке, чтобы вы могли указать, как загружать group_vars, чтобы это не нарушало существующие варианты использования. У нас есть мультитенантные среды, и мы привыкли к этому, пока я не перестал использовать group_vars.

Я не уверен, слышали ли вы о шаблоне ролей и профилей, но это действительно хорошее чтение, и я настоятельно рекомендую этот подход, если вы используете какой-либо инструмент управления конфигурацией. Он был написан для Puppet, но применим ко всем инструментам. Вы, вероятно, не стали бы использовать это для развертывания или специального решения, но для прямого управления конфигурацией это здорово.

http://www.craigdunn.org/2012/05/239/

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

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

Мой обходной путь - определить игру следующим образом:

- hosts: "{{ group }}"
  vars_files:
    - "vars/{{ group }}.yml" 
  roles:
    - role1 etc

Поместите каталог vars в каталог playbook с помощью group1.yml, group2.yml.

Было бы ужасно, если бы ваши конфигурации изменились просто потому, что к ним _ другой доступ_. Подумайте только, какое влияние это окажет на попытки конвергентной архитектуры. +1 к команде Ansible за то, чтобы переменные были как можно более согласованными.

Более интересный вопрос заключается в том, как вы можете применять одну и ту же роль несколько раз, разделяя одни конфигурации между хостами и _ расширяя_ (но не заменяя) другие. Я думаю, что ролевые зависимости позволяют это, а именно:

  • Создайте «роли-оболочки», которые включают роли, которые вы хотите расширить в качестве зависимостей.
  • Укажите allow_duplicates: true в meta/main.yml вашей оболочки.
  • Передайте свои расширения конфигурации в объявление роли (см. Ниже).
  • Установите общие стабильные конфигурации в group/host_vars .

По сути, ваша роль-оболочка должна включать meta.yml вроде:

---
# roles/my-app/meta.yml
allow_duplicates: true
dependencies:
  - role: nginx
    nginx_servers:
      - name: server-myapp
        contents: |
          ...

Когда вы применяете роль оболочки, фактически изменяются только «расширяемые» конфигурации. На разработчиков лежит обязанность разрабатывать свои роли таким образом, чтобы поддерживать этот шаблон.

Команда Ansible: было ли это вашим намерением относительно того, как будут использоваться роли? Честно говоря, я не видел лучшего варианта использования зависимостей; все остальное, кажется, приводит к суперу кода.

Я только что присоединился к списку жертв сегодня после часа отладки, и мне повезло, что я нашел этот пост.
Я думаю, это всего лишь проблема с документацией, никто не будет жаловаться, если это четко указано здесь:
http://docs.ansible.com/ansible/intro_inventory.html#group -variables
тот факт, что переменные связаны с хостами, а группы - просто удобный способ установить переменные для всех хостов, принадлежащих ему. Переменные будут отменены, если один и тот же хост используется в нескольких группах.

+1 Эта проблема затрагивает нашу команду разработчиков программного обеспечения.

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

Однако этот подход, похоже, не работает. Я пока не знаю, как это сделать. Я не могу создавать роли-оболочки, в которых есть переменные, потому что некоторые из переменных фактически относятся к инвентарю. Подумайте, например, о пароле базы данных oid.

Недавно я нашел это, что облегчило мою боль с этой проблемой:
https://github.com/leapfrogonline/ansible-merge-vars

Это позволяет объединять переменные независимо от того, где они были определены, поэтому вы можете объединить два словаря / списка в двух разных группах, например, в отличие от одной группы, выигравшей и перезаписав переменную, определенную в других группах, как текущее поведение. Плагин работает только с Ansible 2+.

Хорошая статья объясняет концепцию и случай использования можно найти здесь .

Мы недавно тоже занялись этим вопросом. У нас есть несколько приложений, работающих на одном хосте под разными пользователями . Например:

[group_a]
host1

[group_b]
host1

У нас нет возможности правильно указать ansible_user с vars, ни с host_vars ни с group_vars . Последнее определение всегда выигрывает в обоих случаях.

Наш текущий обходной путь - определить несколько воспроизведений с разными ansible_user в playbook:

- hosts: group_a
  ansible_user: user_a
  roles:
    - my-role

- hosts: group_b
  ansible_user: user_b
  roles:
    - my-role

@hyojinbae предложил умный способ обойти это выше:

[group_a]
user_a<strong i="8">@host1</strong> ansible_user=user_a ansible_host=host1

[group_b]
user_b<strong i="9">@host1</strong> ansible_user=user_b ansible_host=host1

Итак, теперь у каждого хоста в инвентаре есть уникальное имя. Не большой поклонник помещать хост-вары в инвентарь, но это лучший обходной путь, который я когда-либо видел.

@hyojinbae Я думаю, вам не хватает пунктов hostvars и директив:

- hosts: group_a
  remote_user: user_a
  roles:
    - my-role

- hosts: group_b
  remote_user: user_b
  roles:
    - my-role

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

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

Идем на +1, чтобы подвергнуть сомнению доступный дизайн здесь.
В реальном мире на одном хосте может работать множество различных приложений.
Определение group_vars на уровне хоста просто не покрывает этот вариант использования.

Просто как мысленный эксперимент:

  • Предположим, что поведение по умолчанию было изменено таким образом, что запуск ansible-playbook с параметром «-l» использует дочерний файл group_vars (если он существует).
  • Вы по-прежнему можете обрабатывать вариант использования «центр обработки данных», упомянутый в родительских группах.
  • Все, что изменится, - это то, что «именованная» дочерняя группа для совпадения хоста выиграет битву за наследование, а не «последняя» дочерняя группа для совпадения хоста.

Внесение этого небольшого изменения осчастливит сотни специалистов DevOps и никому не повредит.

Из моего предыдущего комментария см. Https://github.com/ansible/proposals/issues/41 , чтобы узнать о потенциальном пути, позволяющем более гибкое поведение здесь.

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

Я тоже с этим столкнулся. Один из подходов заключался в использовании вложенных переменных. Возьмем, к примеру, группу инвентаризации my_app_servers, которая совпадает с файлом my_app_servers.yml внутри вашего group_vars, и у вас есть более одного приложения для управления на общем хосте. Я вложил их вот так

Пример: my_app_servers.yml

application_env:
  - application1
  - application2

application_environments:
  application1: 
    app_port: 8080
    app_conf_dir: "/somedirectory/conf"
    app_logs_dir: "/somedirectory/logs"
    app_install_name: app1prd

   application2: 
     app_port: 8081
     app_conf_dir: "/somedirectory/conf"
     app_logs_dir: "/somedirectory/logs"
     app_install_name: app2prd

В вашем main.yml определите цикл и перебирайте список вложенных переменных следующим образом:

with_items: "{{application_env}}"
loop_control:
loop_var: application_env_item

Затем в своих задачах вы можете захватить вложенную переменную, которую хотите, чтобы что-то выполнить.
{{application_environments [application_env_item] ['app_install_name']}}
(если вы можете вытащить одну переменную из этого списка, вы можете получить остальные.) Надеюсь, это поможет.

Этот выпуск (№9065) был закрыт еще в 2015 году. Тот же №6538. Тот же № 6666. И многое другое.
Вот 2018 год, через 4 года после того, как многие проблемы были открыты, и, по-видимому, он более горячий, чем был в начале, и все потеряли часы из-за нелогичного дизайна.
ИМХО, это похоже на необходимость проверки командой дизайнеров.

Если все будут продолжать использовать предложенные хаки, это сделает код доступной информации некрасивым:

ИМХО, эти хаки делают его менее привлекательным, не полностью согласованный с девизом ansible " Простая ИТ-автоматизация";)

@bcoca -> Пожалуйста,

Я думаю, что сами group_vars должны иметь приоритет. Hiera для Puppet все поняла. Вы можете указать, как выполняется поиск на основе фактов или групп. Пусть конечный пользователь сможет настроить, как следует обрабатывать group_vars, и предоставить механизм, позволяющий легко увидеть порядок, в котором Ansible применяет эти переменные.

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

@hanej, я думаю, вам нужна конфигурация ansible_group_priority и [defaults]precedence , что касается интроспекции, прямо сейчас у вас есть ansible-inventory который показывает вам окончательный результат, мы все еще работаем над тем, чтобы дать людям лучшее посмотреть, где / что установить окончательное значение переменной.

@ReSearchITEng открывает предложение (http://github.com/ansible/proposals), но это

Поскольку доступные «группы» - это просто свойство хоста, а не основной объект, другие инструменты фокусируются на группах как на «основном контексте», и все остальное добавляется к этому.

Я не считаю оба подхода «неправильными», просто разные. Попытка заставить Ansible работать таким образом нарушит парадигму простоты, сфокусируется на хосте и задаче для того, что является просто организационным фокусом, и перенесет то, что я считаю `` привычным образом мышления '', которое люди приносят из других инструментов.

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

Была ли эта страница полезной?
0 / 5 - 0 рейтинги