Ansible: group_vars игнорируется скриптом инвентаризации в ansible 2.1.1.0

Созданный на 29 июл. 2016  ·  31Комментарии  ·  Источник: ansible/ansible

ТИП ПРОБЛЕМЫ
  • Отчет об ошибке
    АНСИБЛ ВЕРСИЯ
ansible 2.1.1.0
КОНФИГУРАЦИЯ
ОС / ОКРУЖАЮЩАЯ СРЕДА

Убунту 16.04

РЕЗЮМЕ

group_vars игнорируются, если инвентаризация является результатом сценария, хранящегося в подкаталоге. Сюда входит популярный скрипт инвентаризации ec2. Эта ошибка появилась в версии 2.1.1.0 (2.1.0.0 работает нормально).

ДЕЙСТВИЯ ПО ВОСПРОИЗВЕДЕНИЮ
inventory/script.sh
#!/bin/sh

echo '{"webservers": ["paperberry"]}'
group_vars/all.yml :
frontend_path: /var/www/html
playbooks/webservers.yml :
- hosts: all
  connection: local
  tasks:
  - debug: var=frontend_path

Запустите следующий код:

ansible-playbook -i inventory/script.sh playbooks/webservers.yml 
ОЖИДАЕМЫЕ РЕЗУЛЬТАТЫ

ansible 2.1.0.0 показывает

ok: [paperberry] => {
    "frontend_path": "/var/www/html"
}
ФАКТИЧЕСКИЕ РЕЗУЛЬТАТЫ

ansible 2.1.1.0 показывает

ok: [paperberry] => {
    "frontend_path": "VARIABLE IS NOT DEFINED!"
}

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

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

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

Возможное недоразумение

Привет!

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

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

Всегда считалось, что переменные group_var находятся рядом с инвентарем или игрой, а не с каталогом, в котором они находятся.

Вы могли столкнуться с ошибкой в ​​версии 2.1, из-за которой переменные group_var также загружались из «текущего рабочего каталога», которая была исправлена ​​в версии 2.1.1.

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

Еще раз спасибо за это и ваш интерес к Ansible!

Спасибо за указание на это. Документы также ясно об этом.

Можно ли вернуть это поведение, может быть, отключено по умолчанию?

Странно, у меня (tm) это всегда работало, даже до 2.1.0 и вплоть до 1.9.x.
Я что-то упустил или теперь довольно сложно организовать плейбуки, не выполняя кучу «ln -s» для group_vars / host_vars из всех папок плейбуков?

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

Я должен согласиться с @emanuelis в этом.
Включение этого обратно несовместимого «исправления» в следующую версию патча — исключительно плохое решение.

что? мои playbooks сломаны из-за этого "обновления"!

Невероятно, что это рассматривается как исправление ошибки, когда оно эффективно ломает тысячи инфраструктур. Полностью согласен с @emanuelis

Это смешно, ребята. Вы представили ошибку, которая сломала так много людей, и называете ее «исправлением». Невероятный.

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

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

https://docs.ansible.com/ansible/playbooks_best_practices.html#directory -layout

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

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

В документации по переменным упоминается _playbook group_vars_.

Я не вижу упоминаний playbook group_vars где-либо еще на сайте?

https://github.com/ansible/ansible/commit/6dd07de10b7ec7f2aa865deb23f2f19e1656c217 приводит к сбою макета каталога с несколькими инвентарями.

https://github.com/ansible/ansible/pull/17354

group_vars/host_vars из текущего рабочего каталога было ошибкой, появившейся в версии 2.1 по ошибке. Это никогда не должно было быть там. group_vars/host_vars следует читать только каталог файла инвентаря и каталог playbook. Причиной этого является безопасность, поскольку, если вы запустите ansible-playbook из каталога, в котором есть какие-то вредоносные group_vars/host_vars , вы можете сломать управляемые хосты.

@Vivicus это не нарушает документацию по передовым практикам, поскольку в документации по передовым практикам group_vars/host_vars находятся в том же каталоге, где находятся файлы инвентаря (а также где находятся сборники игр), поэтому все работает.

Извините, это не имеет большого смысла. Чтобы на самом деле работать, ansible нужно больше, чем _group_var/host_vars_, поэтому потенциальному злоумышленнику придется создать и их. И если он может их создавать, то он может легко создавать записи в каждой инвентаризации _group_vars/host_vars_. Так что для меня любая потенциальная атака очень маловероятна.

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

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

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

- authorized_key:
    user: root
    key: '{{ root_public_key }}'
    exclusive: yes

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

mkdir /tmp/group_vars
echo 'root_public_key: "ssh-rsa AAKfslfs....."' >/tmp/group_vars/all

Теперь пользователь-администратор, который хочет запустить плейбук с указанной выше задачей, может запустить ansible-playbook из /tmp , например:

admin<strong i="16">@bastion</strong>:/tmp$ ansible-playbook -i /path/to/inventory /path/to/playbook/set_root_key.yml

Это перезапишет то, что пользователь-администратор настроил в своем инвентаре/книге group_vars/all , с тем, что находится в /tmp, и злоумышленник сможет получить контроль над этими хостами. Также подумайте об инструментах непрерывной доставки, запускающих playbooks из некоторых случайных каталогов, в которых также могут быть некоторые плохо установленные переменные.

Я добавлю, что я, вероятно, видел больше производственных реализаций Ansible с точки зрения как количества, так и разнообразия, чем, вероятно, большинство людей во всей отрасли, учитывая мое пребывание в Ansible. При этом любой, кто правильно использует Ansible, не должен / не будет использовать произвольные каталоги групп / хостов vars таким образом, чтобы использовать ошибку CWD-vars-pickup. Это не тот шаблон, который я когда-либо рекомендовал, предоставляя профессиональные услуги нашим клиентам.

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

Итак, как изменится структура наилучшей практики (особенно для group_vars) при использовании динамического инвентаря в башне? Вот где я борюсь. У меня есть одна папка group_vars на верхнем уровне (как определено в документах с лучшими практиками), и после обновления до 2.1.1 они больше не распознаются. Я не определяю отдельные инвентари внутри общего каталога, так как башня делает это за меня.

чтобы добавить, это работало правильно для всех версий за последние 18 месяцев и сломалось только в 2.1.1.

@cmebert Главное не то, где находится group_vars , а то, где он находится _по отношению к вашим сборникам игр_. Папка верхнего уровня group_vars будет работать только в том случае, если рядом с ней находятся все ваши плейбуки. Это переменные группы _play_. Они будут работать последовательно между Ansible Tower и Ansible в командной строке. Поскольку Ansible Tower управляет своим собственным инвентарем (даже динамическим), он не обращает внимания на переменные группы _inventory_.

Если ваши плейбуки находятся во вложенной папке, поместите туда же свои group_vars . Это даст вам желаемое поведение.

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

@cmebert , нет, в лучших практиках у вас есть ОБА инвентарь и воспроизведение в каталоге верхнего уровня.

Если вы посмотрите на «альтернативный» макет, станет ясно, что group_vars установлены рядом с инвентарем.

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

@cmebert Я только что сделал простой проект, надеюсь, проясню.

.
├── group_vars
│   └── all.yml
├── inventory
│   ├── group_vars
│   │   └── all.yml
│   └── hosts
├── playbooks
│   ├── group_vars
│   │   └── all.yml
│   └── nested-playbook.yml
└── toplevel-playbook.yml

При запуске toplevel-playbook.yml :

.
├── group_vars
│   └── all.yml         <-- These are applied, others ignored.
 ...
└── toplevel-playbook.yml

При запуске nested-playbook.yml :

.
...
├── playbooks
│   ├── group_vars
│   │   └── all.yml      <-- These are applied, others ignored. group_vars at the root of a project is the same as any arbitrary directory from the perspective of nested-playbook.yml.
│   └── nested-playbook.yml
...

Во всех случаях Tower игнорирует инвентарь group_vars .

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

Ansible Tower Variables

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

@samdoran В этом первом примере именно так устроена наша структура каталогов, и до версии 2.1.1 башня без проблем распознавала и использовала файлы group_vars .yml, расположенные внутри папки group_vars верхнего уровня. Это ломается при обновлении до 2.1.1 без каких-либо других изменений. (башня 3.0.2).

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

Требования не изменились, исправлена ​​ошибка в Ansible, которая некорректно позволяла работать вашей настройке.
В данном случае Tower — это именно то, что выполняет Ansible.

@bcoca Если требования не изменились, но ошибка была исправлена, и это исправление нарушило пример передовой практики из документации, можем ли мы просто получить обновленный набор документов. Я платный клиент башни, который не может обновить версию ansible, которую я использую, из-за этого «исправления ошибки».

пожалуйста, прочитайте выше, это НЕ нарушило пример лучших практик

@cmebert ты это исправил? У меня точно такая же проблема при попытке обновить нас до 2.2.0. Только динамическая инвентаризация, переменные group_var не распознаются. У меня есть только один файл group_vars, и нет смысла копировать его в несколько мест.

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

Как уже говорили другие, это похоже на странное «исправление ошибки». У нас есть динамическая инвентаризация, а также некоторые вещи, определенные в group_vars и host_vars в корне нашего репозитория. Мы делаем это с 1.7ish. Внезапно group_vars и host_vars вообще не загружаются в 2.2 (обновление с 2.0). Наш текущий обходной путь — символическая ссылка на group_vars и host_vars верхнего уровня в наш подмодуль динамической инвентаризации, добавив эти папки в качестве исключений в .gitignore. Это странный выход!!!

В качестве альтернативы, можем ли мы указать несколько каталогов для поиска инвентаря в файле ansible.cfg?

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

Для меня это проблема, потому что мы используем скрипт ec2.py для получения динамической инвентаризации от AWS.

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

Пример:

.
├── group_vars
│   ├── all
│   │   └── all.yml <--- always loaded
│   ├── tag_env_aws_eu_west_011_production
│   │   └── only_for_this_env.yml <--- I would like to have that file loaded as 
                   it defines MyArray.MyAttribute used for an iteration
├── inventory
│   └── ec2.ini
│   └── ec2.py
├── roles
│   └── pam_limits
│   └── other_role
└── my-playbook.yml

Внутри my-playbook.yml у меня есть:

  - hosts: tag_env_aws_eu_west_011_production
    roles:
      - { role: pam_limits, tags: [ 'pam_limits'] } 
     ...
    tags:
      - common

Перед запуском playbook установите ANSIBLE_HOSTS, чтобы он использовал сценарий инвентаризации:

#Set
cd .
export EC2_INI_PATH=$(pwd)/inventory/ec2.ini
export ANSIBLE_HOSTS=$(pwd)/inventory/ec2.py

В динамической инвентаризации, созданной ec2.py, есть хост, который находится в группе с именем «tag_env_aws_eu_west_011_production» (теги в AWS отображаются как группы)

"tag_env_aws_eu_west_011_production": [
    "123.123.123.123", 
    "123.123.123.124"
]

С ansible <= 2.1.4.0 загружается group_vars/tag_env_aws_eu_west_011_production/only_for_this_env.yml, и мои роли могут использовать переменные, определенные в этом файле.

С ansible > 2.1.4.0 загружается только group_vars/all/all.yml

TASK [pam_limits : a_task] ********************************************************************************************************
fatal: [123.123.123.123]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, 
which appears to include a variable that is undefined. The error was: 
'ansible.vars.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'MyAttribute'\n\nT...}

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

Пока что я вернулся к стабильной версии 2.1.4.0.

Спасибо!

Я сталкиваюсь с той же проблемой, что и @jruizjimenez с v2.2.1.0.

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