Ansible: как использовать список многозначных данных в качестве инвентаря и передать на целевой хост

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

   servername1  processname1
   servername1  processname2
   servername1  processname3
   servername2  processname1
   servername3  processname1
   servername4  processname1

Итак, столбец 1 - это мой список целевых хостов (мой инвентарь). Столбец 2 - это уникальные значения имени процесса, специально присвоенные значению имени сервера. Часто встречается один и тот же сервер. Некоторые серверы имеют только одно имя процесса, другие могут иметь от 2 до N. Это означает, что мой целевой хост может повторяться для уникального списка имен процессов. Я хочу использовать оба динамических списка из этого выходного списка пар, и мне нужно, чтобы оба значения в каждом наблюдении были связаны и присвоены переменным. Мне не обязательно использовать динамический инвентарь, мне просто нужно решение. Мне также нужно передать на целевой хост и значение в {{processname #}} с помощью команды: или shell: modules. (Это уникально, нет модулей, связанных с этой необходимостью)

При необходимости у меня есть способ отфильтровать эти данные и вывести их в формате JSON или YAML, создав отдельный файл YML для каждого хоста. Хотя я бы предпочел обрабатывать их динамически; предварительная обработка списка приемлема.

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

Что я сделал до сих пор: я попытался прочитать и попытаться установить эти пары, как в файлах /etc/ansible/hosts/host_vars/servername#.yml. Это крайне уродливо, так как мне приходится предварительно обрабатывать вывод данных в формате YML. Но он не дает мне списка хостов, на который можно ссылаться в моем учебнике. Так что, хотя кажется, что hostvar - логичный выбор, я не могу обойти его стороной.

Что мне нужно:

- The suggested format of the data?  JSON? YAML? Other? (if I cannot read it in dynamically.
- Is putting this in host_vars correct?
- Last night I saw another answer using set_fact, would that help?

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

Примечание: МНОГИЕ предлагали использовать host_vars, но мне кажется, что это зарезервировано для имен хостов и связанных значений портов и прокси. Я могу ошибаться.

===================================================================

ОБНОВЛЕНИЕ: Спасибо за помощь в правильном направлении. Я обновил наш скрипт инвентаризации, чтобы выводить список хостов в формате JSON. Первый новый вариант - вывод хостов в JSON. Пример: {"my_host": ["servername1", "servername2",]}

Вызов этого скрипта динамической инвентаризации отлично работает!

ansible all -m ping servername1 | УСПЕХ => {"изменено": false, "ping": "pong"} имя_сервера2 | УСПЕХ => {"изменено": false, "ping": "pong"}

Далее: Вторая новая опция в сценарии инвентаризации заключалась в добавлении нового переключателя для ввода имени хоста. Эта часть до сих пор меня смущает. Вот результат: showInv --host = servername1

{"servername1": ["processname1", "processname2", "processname3",]}

Последняя часть, которую мне не хватает, - это то, как я вызываю скрипт инвентаризации с определенным "--host = {{my_host}}" из моей playbook.

Похоже, мне нужно найти переменную для существующего имени хоста и передать ее обратно в сценарий инвентаризации в качестве параметра переключателя "--host ="


person gantte    schedule 01.09.2017    source источник


Ответы (3)


Вы говорите, что вас устраивает динамическая инвентаризация. Сделать свой собственный.

Вот документы.

Вам нужно создать сценарий, который будет делать две вещи:

  • при выполнении с --list обрабатывает ваш файл и выводит этот JSON на стандартный вывод:

    { "myhosts": ["servername1", "servername2", "servername3"] }
    
  • при выполнении с --host servername1 выводит этот JSON на стандартный вывод:

    { "myprocesses": ["processname1", "processname2"] }
    

Таким образом, с --list вы должны предоставить уникальный список хостов. В моем примере они принадлежат группе myhosts.

И с --host <hostname> вы должны предоставить список dict переменных хоста для этого хоста (<hostname>). В моем примере есть переменная списка myprocesses, которая содержит все процессы для этого хоста.

Тогда просто позвоните ansible-playbook -i my_inv_script myplaybook.yml.

Пример сценария:

---
- hosts: myhosts
  tasks:
    - debug:
        msg: "Process name is {{ item }}"
      with_items: "{{ myprocesses }}"

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

person Konstantin Suvorov    schedule 01.09.2017
comment
Спасибо. Я вижу, как это должно работать. Еще один вопрос: при повторном включении вызова в сценарий инвентаризации, как мне включить --host ‹hostname› в -i my_inv_script? Могу я процитировать это как -i my_inv_script --host {{myhosts}}? - person gantte; 01.09.2017
comment
Вы просто указываете свой сценарий инвентаризации с помощью -i my_inv_script, а затем Ansible внутренне вызывает my_inv_script --list, чтобы вывести список всех хостов, а затем вызывает my_inv_script --host <hostname> для каждого хоста, чтобы получить его переменные. - person Konstantin Suvorov; 02.09.2017
comment
Есть ли другой способ сделать это? Мой сценарий инвентаризации не поддерживает --list. Скрипт - Perl. Сценарий принимает несколько параметров, чтобы получить желаемый результат из нашей базы данных. Я оборачиваю сценарий perl с правильными параметрами внутри сценария оболочки bash. Пример: invList -a appReleasever -p platform -e releaseVer и т. Д. Таким образом, при использовании оболочки внутри оболочки bash поиск исходной оболочки базовой оболочки выводит список хостов для динамической инвентаризации. Нет --list. Могу ли я назначить переменную, имитирующую добавление --host = {{hostname}}? - person gantte; 04.09.2017
comment
Обновление: я изменил оболочку сценария bash, чтобы разрешить --list и выводить динамический инвентарь. Это работает. Я также изменил оболочку сценария bash, чтобы разрешить --host ‹space› a_hostname. Выполнено вручную, это работает. Но прогоняя его с помощью приведенного выше примера playbook, я получаю ошибку: fatal: [hostname1]: FAILED! = ›{Failed: true, msg: 'myprocesses' is undefined} Значит, значение {{myprocesses}} не определено. Что мне не хватает? Спасибо. - person gantte; 04.09.2017

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

Пожалуйста, найдите ниже ссылку на мой динамический инвентарь, написанный на php https://github.com/walden-it/ansible-ij/blob/master/inventory.php

взгляните на функции get_vars () и get_hosts (), чтобы увидеть, как заполняется массив.

А если вам это нужно, вот дамп базы данных, на которую смотрит этот скрипт: https://github.com/walden-it/ansible-ij/blob/master/ansible.sql

Затем вы просто указываете его с -i inventory в прогоне ansible или добавляете его как inventory_file в ansible.cfg

person Juan Manuel García    schedule 01.09.2017
comment
Если вы можете улучшить свой ответ (я предполагал, что вы можете, по второму абзацу, который вы написали), сделайте это. Это могло бы помочь большему количеству пользователей с тем же вопросом ... - person Leonardo Alves Machado; 01.09.2017

Закрытие этого. С помощью предложений Константина у меня теперь есть рабочий спектакль. Что не сразу очевидно, так это то, что Ansible творит за кулисами некую «магию». Мне пришлось изменить свой скрипт инвентаризации, который генерирует мой динамический инвентарь, чтобы принять опцию переключателя «--list» и опцию «--host hostname».

Как только это было сделано, я мог запустить playbook с -i listInv, и Ansible внутренне вызывает этот скрипт как listInv --list, который создает мой динамический список инвентаризации. Затем он переходит к with_items и внутренне вызывает сценарий как listInv --host {{items}} и выводит соответствующие имена процессов.

Кроме того, вывод JSON, сгенерированный моим скриптом, должен был содержать поле «group» (первое), «myprocess». Изначально у меня это было как «my_process», и это не удалось. Исправлено удаление подчеркивания, ошибка.

Все работает сейчас. Это отличный пример для обучения, но он по-прежнему волшебный.

Плейбук выглядит так:

- hosts: all
  gather_facts: no
  connection: local

  tasks:
    - debug:
        msg: "Process name is {{ item }}"
      with_items:  "{{ myprocess }}"
person gantte    schedule 05.09.2017