Timur
господа, ещё такой вопрос - кто-то использует генерацию плейбуков при помощи jinja2? У меня есть ряд сервисов, которые при обновлении надо трогать в определённом порядке, и вот я хотел бы дать возможность определять порядок и что именно делать разработчикам - вынеся это в отдельную конфигурацию. Впоследствии мы просто передаём пайплайну селекторы деплойментов, создаётся плейбук и в нужном порядке все сервисы обновляются. Поругайте плиз.
Alexander
А потом бегают все с красными глазами в поисках косяка при генерации))
Timur
ну запуск пайплайна будет отдельным шагом, конечно :)
Alexander
Лучше сделать плей пер сервис
Timur
да, но что делать, если сервис зависит от других сервисов?
Timur
т.е. я как бы не против :)
Timur
это прямо драматически упростило бы дело, хехе
Alexander
Логику можно реализовать 1000 и 1 способом. Особенно если постичь "программирование на ансибле", как говорит мой коллега
Alexander
Вопрос правильности уместен только в случае полной картины и контекста проекта. Кроме конечно основ и бест практик - это маст хэв.
Timur
в современном мире все эти вещи разруливаются оркестраторами типа кубернетеса, но у нас его пока нет, поэтому приходится костылями, конечно. пока в процессе миграции.
Artem
Зачем?
Если я правильно понимаю тут дело в типе данных переменных, так как например в переменной ansible_eno1 имееться массив данных в json, если я укажу просто текстовую переменную она в себе не будет содержать необходимую вложенность, поправьте меня если я не прав
Artem
возможно есть пределённое правила объявления переменных, но я не нашёл инфы по этому поводу
Timur
Т.е. структуру словаря
Artem
Что именно в вашей переменной содержится - можете показать?
Это как предположение, смотрите проблема в том что я не могу подобрать нужную форму записи yml - name: Create interface within Netbox with only required information netbox_interface: netbox_url: netbox_token: data: enabled: "{{ item.enabled }}" device: "{{ inventory_hostname }}" name: "{{ item.name }}" mac_address: "{{ item.mac_address }}" form_factor: 1000Base-T (1GE) mtu: "{{ item.mtu }}" #description: "{{ item.module }}" state: present delegate_to: 127.0.0.1 with_items: - { enabled: "{{ ansible_eno1.active }}", name: "{{ ansible_eno1.device }}", mac_address: "{{ ansible_eno1.macaddress }}", mtu: "{{ ansible_eno1.mtu }}", module: "{{ ansible_eno1.module }}" } - { enabled: "{{ ansible_enp2s0.active }}", name: "{{ ansible_enp2s0.device }}", mac_address: "{{ ansible_enp2s0.macaddress }}", mtu: "{{ ansible_enp2s0.mtu }}", module: "{{ ansible_enp2s0.module }}" }в данной записи название интефейсов прописаны вручную как и вложенность (ansible_eno1.active), я бы хотел получить список интерфейсов и подставить его в цикле ansible_СЮДА.active. Вы не можете подсказать как это можно реализовать?
Ruslan
Это как предположение, смотрите проблема в том что я не могу подобрать нужную форму записи yml - name: Create interface within Netbox with only required information netbox_interface: netbox_url: netbox_token: data: enabled: "{{ item.enabled }}" device: "{{ inventory_hostname }}" name: "{{ item.name }}" mac_address: "{{ item.mac_address }}" form_factor: 1000Base-T (1GE) mtu: "{{ item.mtu }}" #description: "{{ item.module }}" state: present delegate_to: 127.0.0.1 with_items: - { enabled: "{{ ansible_eno1.active }}", name: "{{ ansible_eno1.device }}", mac_address: "{{ ansible_eno1.macaddress }}", mtu: "{{ ansible_eno1.mtu }}", module: "{{ ansible_eno1.module }}" } - { enabled: "{{ ansible_enp2s0.active }}", name: "{{ ansible_enp2s0.device }}", mac_address: "{{ ansible_enp2s0.macaddress }}", mtu: "{{ ansible_enp2s0.mtu }}", module: "{{ ansible_enp2s0.module }}" }в данной записи название интефейсов прописаны вручную как и вложенность (ansible_eno1.active), я бы хотел получить список интерфейсов и подставить его в цикле ansible_СЮДА.active. Вы не можете подсказать как это можно реализовать?
откуда взялись ansible_eno1 (и другие) ? ты их руками объявил либо из факта?
Artem
откуда взялись ansible_eno1 (и другие) ? ты их руками объявил либо из факта?
да, это ручной вариант который я хочу автоматизировать
Timur
Я пока не понимаю, что откуда берется
Lamobot
Это как предположение, смотрите проблема в том что я не могу подобрать нужную форму записи yml - name: Create interface within Netbox with only required information netbox_interface: netbox_url: netbox_token: data: enabled: "{{ item.enabled }}" device: "{{ inventory_hostname }}" name: "{{ item.name }}" mac_address: "{{ item.mac_address }}" form_factor: 1000Base-T (1GE) mtu: "{{ item.mtu }}" #description: "{{ item.module }}" state: present delegate_to: 127.0.0.1 with_items: - { enabled: "{{ ansible_eno1.active }}", name: "{{ ansible_eno1.device }}", mac_address: "{{ ansible_eno1.macaddress }}", mtu: "{{ ansible_eno1.mtu }}", module: "{{ ansible_eno1.module }}" } - { enabled: "{{ ansible_enp2s0.active }}", name: "{{ ansible_enp2s0.device }}", mac_address: "{{ ansible_enp2s0.macaddress }}", mtu: "{{ ansible_enp2s0.mtu }}", module: "{{ ansible_enp2s0.module }}" }в данной записи название интефейсов прописаны вручную как и вложенность (ansible_eno1.active), я бы хотел получить список интерфейсов и подставить его в цикле ansible_СЮДА.active. Вы не можете подсказать как это можно реализовать?
не пробовали изменить код? loop: '{{ ansible_interfaces }}' loop_control: loop_var: 'interface' И в таске использовать: '{{ hostvars[ansible_host]["ansible_"~interface]["mtu"] }}' итд
Lamobot
В loop можно фильтрами список интерфейсов уменьшить, убрать там lo итд
Artem
В loop можно фильтрами список интерфейсов уменьшить, убрать там lo итд
спасибо,похоже на то что нужно сейчас буду пробовать, просто с loop ещё не разобрался😊
Lamobot
У этого метода есть косяки, так как иногда в названии интерфейсов встречаются тире, они в фактах ансибла будут заменены на подчеркивания, но это всё можно в loop: поправить
Lamobot
да, действительно походу что то нужно, сейчас буду разбираться как убрать ненужные интерфейсы, спасибо))
Небольшой фикс: loop: '{{ ansible_interfaces|reject("match","lo|veth.*|docker.*|br-.*|tun.*")|map("replace", "-", "_")|list }}' loop_control: loop_var: 'interface' И покороче если использовать ansible_facts вместо hostvars: '{{ ansible_facts[interface]["mtu"] }}'
Lamobot
что-нибудь типа: when: 'docker0' not in item.interface_name
Лучше использовать фильтры в самом loop: выражении
Artem
Небольшой фикс: loop: '{{ ansible_interfaces|reject("match","lo|veth.*|docker.*|br-.*|tun.*")|map("replace", "-", "_")|list }}' loop_control: loop_var: 'interface' И покороче если использовать ansible_facts вместо hostvars: '{{ ansible_facts[interface]["mtu"] }}'
единстенное что заметил что когда я пытаюсь считать вложенность следующего уровня '{{ ansible_facts[interface]["ipv4"]["address"] }}' данных нету ok: [localhost] => (item=eno1) => { "192.168.0.93": "VARIABLE IS NOT DEFINED!: float object has no element 0", "ansible_loop_var": "interface", "interface": "eno1" }но если запросить на прямую через дебаг ansible_facts.eno1.ipv4.address то всё есть ok: [localhost] => { "ansible_facts.eno1.ipv4.address": "192.168.0.93" }
Artem
можно ли как то в loop указать сохранять все данные внутри массива?
Artem
сразу не заметил, ip выводиться сразу в первой строке, но возможно ансиблу ненравиться "VARIABLE IS NOT DEFINED!: float object has no element 0"
Artem
вот мой плейбук - name: Create interface within Netbox with only required information netbox_interface: netbox_url: netbox_token: data: enabled: '{{ ansible_facts[interface]["active"] }}' device: "{{ inventory_hostname }}" name: '{{ ansible_facts[interface]["device"] }}' mac_address: '{{ ansible_facts[interface]["macaddress"] }}' form_factor: 1000Base-T (1GE) mtu: '{{ ansible_facts[interface]["mtu"] }}' #description: "{{ item.module }}" state: present loop: '{{ ansible_interfaces|reject("match","lo|veth.*|docker.*|br-.*|ip_vti*|gre*|ip6tnl*|tunl*|ifb*|bond*")|map("replace", "-", "_")|list }}' loop_control: loop_var: "interface" delegate_to: 127.0.0.1 - name: Attach a new available IP netbox_ip_address: netbox_url: netbox_token: data: address: '{{ ansible_facts[interface]["ipv4"]["address"] }}' family: 4 interface: name: '{{ ansible_facts[interface]["device"] }}' device: "{{ inventory_hostname }}" #vrf: "{{ item.type }}" is_primary: true state: present loop: '{{ ansible_interfaces|reject("match","lo|veth.*|docker.*|br-.*|ip_vti*|gre*|ip6tnl*|tunl*|ifb*|bond*")|map("replace", "-", "_")|list }}' loop_control: loop_var: "interface" delegate_to: 127.0.0.1
Artem
первый шаг проходит отлично
Artem
а вот второй TASK [Attach a new available IP] ******************************************************************************************************************************************************************** task path: /home/adronov/@@@/infra/netbox_new.yml:42 An exception occurred during task execution. To see the full traceback, use -vvv. The error was: KeyError: 'is_primary' failed: [@@@ -> 127.0.0.1] (item=eth1) => {"ansible_loop_var": "interface", "changed": false, "interface": "eth1", "module_stderr": "Traceback (most recent call last):\n File \"/home/adronov/.ansible/tmp/ansible-tmp-1576147467.5-32638249685426/AnsiballZ_netbox_ip_address.py\", line 102, in <module>\n _ansiballz_main()\n File \"/home/adronov/.ansible/tmp/ansible-tmp-1576147467.5-32638249685426/AnsiballZ_netbox_ip_address.py\", line 94, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File \"/home/adronov/.ansible/tmp/ansible-tmp-1576147467.5-32638249685426/AnsiballZ_netbox_ip_address.py\", line 40, in invoke_module\n runpy.run_module(mod_name='ansible.modules.net_tools.netbox.netbox_ip_address', init_globals=None, run_name='__main__', alter_sys=True)\n File \"/usr/lib/python2.7/runpy.py\", line 188, in run_module\n fname, loader, pkg_name)\n File \"/usr/lib/python2.7/runpy.py\", line 82, in _run_module_code\n mod_name, mod_fname, mod_loader, pkg_name)\n File \"/usr/lib/python2.7/runpy.py\", line 72, in _run_code\n exec code in run_globals\n File \"/tmp/ansible_netbox_ip_address_payload_8zdAKM/ansible_netbox_ip_address_payload.zip/ansible/modules/net_tools/netbox/netbox_ip_address.py\", line 517, in <module>\n File \"/tmp/ansible_netbox_ip_address_payload_8zdAKM/ansible_netbox_ip_address_payload.zip/ansible/modules/net_tools/netbox/netbox_ip_address.py\", line 294, in main\n File \"/tmp/ansible_netbox_ip_address_payload_8zdAKM/ansible_netbox_ip_address_payload.zip/ansible/modules/net_tools/netbox/netbox_ip_address.py\", line 327, in _handle_state_new_present\n File \"/tmp/ansible_netbox_ip_address_payload_8zdAKM/ansible_netbox_ip_address_payload.zip/ansible/modules/net_tools/netbox/netbox_ip_address.py\", line 364, in ensure_ip_address_present\n File \"/tmp/ansible_netbox_ip_address_payload_8zdAKM/ansible_netbox_ip_address_payload.zip/ansible/module_utils/net_tools/netbox/netbox_utils.py\", line 235, in update_netbox_object\nKeyError: 'is_primary'\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1} An exception occurred during task execution. To see the full traceback, use -vvv. The error was: KeyError: 'is_primary'
Artem
Timur
Зачем replace в фильтрах?
Artem
Зачем replace в фильтрах?
в некоторых интерфейсах в названии есть "-" их заменяем на "_" специфика пайтон
Artem
так как в одной из функций нам нужно считать и записать название сетевого интерфейса, если он будет содержать "-" то крашанётся
Timur
Крашнется как раз наоборот - если попытается обратиться к отсутствующему в словаре ключу, который вы получили в результате замены
Artem
может я не правильно выразился, не поддерживает имена переменных с "-"
Timur
В синтаксисе вида myvar[key1][key2][key3] в значениях ключей дефисы поддерживаются
Timur
См. документацию: https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#ansible-allows-dot-notation-and-array-notation-for-variables-which-notation-should-i-use
Lamobot
Зачем replace в фильтрах?
В фактах словари с параметрами интерфейсов названы с подчеркиваниями, а в списке интерфейсов с тире: "br_612565defd8b": { "active": true, "device": "br-612565defd8b", "features": {
Lamobot
И что?
Как найти адрес интерфейса с именем "br-612565defd8b" ?
Timur
А, стоп
Timur
О каких фактах идет речь?
Lamobot
О каких фактах идет речь?
Факты хоста - сведения о сетевых интерфейсах
Timur
А, понял
Timur
Тогда - да, наверное, замена нужна
Lamobot
вот мой плейбук - name: Create interface within Netbox with only required information netbox_interface: netbox_url: netbox_token: data: enabled: '{{ ansible_facts[interface]["active"] }}' device: "{{ inventory_hostname }}" name: '{{ ansible_facts[interface]["device"] }}' mac_address: '{{ ansible_facts[interface]["macaddress"] }}' form_factor: 1000Base-T (1GE) mtu: '{{ ansible_facts[interface]["mtu"] }}' #description: "{{ item.module }}" state: present loop: '{{ ansible_interfaces|reject("match","lo|veth.*|docker.*|br-.*|ip_vti*|gre*|ip6tnl*|tunl*|ifb*|bond*")|map("replace", "-", "_")|list }}' loop_control: loop_var: "interface" delegate_to: 127.0.0.1 - name: Attach a new available IP netbox_ip_address: netbox_url: netbox_token: data: address: '{{ ansible_facts[interface]["ipv4"]["address"] }}' family: 4 interface: name: '{{ ansible_facts[interface]["device"] }}' device: "{{ inventory_hostname }}" #vrf: "{{ item.type }}" is_primary: true state: present loop: '{{ ansible_interfaces|reject("match","lo|veth.*|docker.*|br-.*|ip_vti*|gre*|ip6tnl*|tunl*|ifb*|bond*")|map("replace", "-", "_")|list }}' loop_control: loop_var: "interface" delegate_to: 127.0.0.1
параметра is_primary в доке модуля не нахожу https://docs.ansible.com/ansible/latest/modules/netbox_ip_address_module.html
Timur
а вот второй TASK [Attach a new available IP] ******************************************************************************************************************************************************************** task path: /home/adronov/@@@/infra/netbox_new.yml:42 An exception occurred during task execution. To see the full traceback, use -vvv. The error was: KeyError: 'is_primary' failed: [@@@ -> 127.0.0.1] (item=eth1) => {"ansible_loop_var": "interface", "changed": false, "interface": "eth1", "module_stderr": "Traceback (most recent call last):\n File \"/home/adronov/.ansible/tmp/ansible-tmp-1576147467.5-32638249685426/AnsiballZ_netbox_ip_address.py\", line 102, in <module>\n _ansiballz_main()\n File \"/home/adronov/.ansible/tmp/ansible-tmp-1576147467.5-32638249685426/AnsiballZ_netbox_ip_address.py\", line 94, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File \"/home/adronov/.ansible/tmp/ansible-tmp-1576147467.5-32638249685426/AnsiballZ_netbox_ip_address.py\", line 40, in invoke_module\n runpy.run_module(mod_name='ansible.modules.net_tools.netbox.netbox_ip_address', init_globals=None, run_name='__main__', alter_sys=True)\n File \"/usr/lib/python2.7/runpy.py\", line 188, in run_module\n fname, loader, pkg_name)\n File \"/usr/lib/python2.7/runpy.py\", line 82, in _run_module_code\n mod_name, mod_fname, mod_loader, pkg_name)\n File \"/usr/lib/python2.7/runpy.py\", line 72, in _run_code\n exec code in run_globals\n File \"/tmp/ansible_netbox_ip_address_payload_8zdAKM/ansible_netbox_ip_address_payload.zip/ansible/modules/net_tools/netbox/netbox_ip_address.py\", line 517, in <module>\n File \"/tmp/ansible_netbox_ip_address_payload_8zdAKM/ansible_netbox_ip_address_payload.zip/ansible/modules/net_tools/netbox/netbox_ip_address.py\", line 294, in main\n File \"/tmp/ansible_netbox_ip_address_payload_8zdAKM/ansible_netbox_ip_address_payload.zip/ansible/modules/net_tools/netbox/netbox_ip_address.py\", line 327, in _handle_state_new_present\n File \"/tmp/ansible_netbox_ip_address_payload_8zdAKM/ansible_netbox_ip_address_payload.zip/ansible/modules/net_tools/netbox/netbox_ip_address.py\", line 364, in ensure_ip_address_present\n File \"/tmp/ansible_netbox_ip_address_payload_8zdAKM/ansible_netbox_ip_address_payload.zip/ansible/module_utils/net_tools/netbox/netbox_utils.py\", line 235, in update_netbox_object\nKeyError: 'is_primary'\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1} An exception occurred during task execution. To see the full traceback, use -vvv. The error was: KeyError: 'is_primary'
Там же сказано о причинах ошибки
Lamobot
Ошибка об этом и говорит The error was: KeyError: 'is_primary'
Timur
И в выхлопе модуля об этом же говорится
Timur
The error was: KeyError: 'is_primary' failed
Artem
если я правильно понимаю проблема в том что у меня на выходе должно быть "значение" а в данном случае ip это "ключ" получаеться ok: [localhost] => (item=eno1) => { "192.168.0.93": "VARIABLE IS NOT DEFINED!: float object has no element 0", "ansible_loop_var": "interface", "interface": "eno1" }
Artem
вот эту - name: Attach a new available IP netbox_ip_address: netbox_url: netbox_token: data: address: '{{ ansible_facts[interface]["ipv4"]["address"] }}' family: 4 interface: name: '{{ ansible_facts[interface]["device"] }}' device: "{{ inventory_hostname }}" #vrf: "{{ item.type }}" is_primary: true state: present loop: '{{ ansible_interfaces|reject("match","lo|veth.*|docker.*|br-.*|ip_vti*|gre*|ip6tnl*|tunl*|ifb*|bond*")|map("replace", "-", "_")|list }}' loop_control: loop_var: "interface" delegate_to: 127.0.0.1
Lamobot
если я правильно понимаю проблема в том что у меня на выходе должно быть "значение" а в данном случае ip это "ключ" получаеться ok: [localhost] => (item=eno1) => { "192.168.0.93": "VARIABLE IS NOT DEFINED!: float object has no element 0", "ansible_loop_var": "interface", "interface": "eno1" }
Попробуйте поэкспериментировать с параметрами модуля. Или покопайтесь в коде, гугле, это связано с самим модулем, похоже. Попробуйте простейший вариант, попробовать добавить один ip без всяких параметров лишних.
Artem
прошлый рабочий вариант - name: Attach a new available IP netbox_ip_address: netbox_url: netbox_token: data: address: "{{ item.address }}" family: 4 interface: name: "{{ item.name }}" device: "{{ inventory_hostname }}" vrf: "{{ item.type }}" is_primary: true state: present delegate_to: 127.0.0.1 ignore_errors: yes with_items: # - { address: "{{ ansible_eno1.ipv4.address }}", name: "{{ ansible_eno1.device }}", type: Global } - { address: "{{ ansible_enp2s0.ipv4.address }}", name: "{{ ansible_enp2s0.device }}", type: Lan }
Angrey
Здравствуйте! Скажите пожалуйста как в ansible проверить плейбук?
Alex
проверить на предмет чего?
Timur
может человек до молекулы дорос :)
Timur
у меня у самого, правда, руки ещё не дошли
Angrey
Пытаюсь развернуть minio и сервак вроде развернул а куда писать роли хз(
Angrey
первый раз используя ansible
Dmitriy
Пытаюсь развернуть minio и сервак вроде развернул а куда писать роли хз(
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html вот же
Ivan
Товарисчи! подскажите пож. внезапно при запуске пелйбука появилась вот такая штука
Angrey
Спасибо!
Dmitriy
Спасибо!
да не за что, я бы вообще многое реккомендовал оборачивать в роли, очень удобная штука.