Разработка и тестирование Ansible-ролей с использованием Molecule и Podman

    Одно из основных преимуществ Red Hat Ansible Automation Platform заключается в том, что ее язык описания автоматизаций читабелен не только для пары-тройки гуру, но и почти для всех, кто имеет отношение к ИТ. Поэтому вносить свой вклад в автоматизацию могут любые специалисты, что сильно облегчает организацию межкомандного взаимодействия и внедрение автоматизации на уровне корпоративной культуры.



    Однако, когда делом занимается такая масса народа, очень важно все тщательно тестировать. При разработке Ansible-контента, вроде плейбуков, ролей или коллекций, мы очень рекомендуем предварительно проверять все в тестовой среде, прежде чем выкатывать в продакшн. Цель такого тестирования – удостовериться, что все работает как надо, чтобы избежать неприятных сюрпризов на «боевых» системах.

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

    Вот как это декларируется в документации проекта:

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

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

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

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

    Molecule использует драйверы для предоставления целевых инстансов на базе различных технологий, включая Linux-контейнеры, виртуальные машины и облачных провайдеров. По умолчанию он идет с тремя предустановленными драйверами: Docker и Podman для контейнеров, а также драйвером Delegated для создания кастомных интеграций. Драйверы для других провайдеров предоставляются сообществом разработки проекта.

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

    Используя Molecule с драйвером Podman, мы с нуля разработаем и протестируем новую роль Ansible, которая развертывает веб-приложение на базе веб-сервера Apache и должна работать на Red Hat Enterprise Linux (RHEL) 8 или Ubuntu 20.04.

    Мы разбираем типовой сценарий, когда роль должна работать на различных версиях операционной системы. Используя Podman и Linux-контейнеры, мы можем создать несколько инстансов, чтобы протестировать роль на разных версиях ОС. Благодаря своей легковесности, контейнеры позволяют быстро итерировать функциональность роли прямо по ходу разработки. Использование контейнеров для тестирования ролей применимо в данной ситуации, поскольку роль конфигурирует только запущенные инстансы Linux. Для тестирования на других целевых системах или облачных инфраструктурах можно использовать драйвер delegated или другие драйверы, предоставляемые сообществом.

    Что нам понадобится


    Для примеров из этой статьи нужна физическая или виртуальная машина Linux с установленными Python 3 и Podman (мы используем RHEL 8.2). Также Podman должен был сконфигурирован для запуска rootless-контейнеров. Установка Podman выходит за рамки этой статьи, для получения соответствующей информации см. официальную документацию. Установка Podman на RHEL 8 также описывается в документации по контейнерам RHEL 8.

    Приступаем


    Molecule выполнен в виде Python-пакета и, соответственно, устанавливается через pip. Первым шагом мы создаем выделенное Python-окружение и устанавливаем в него наш Molecule:

    $ mkdir molecule-blog
    $ cd molecule-blog
    $ python3 -m venv molecule-venv
    $ source molecule-venv/bin/activate
    (molecule-venv) $ pip install "molecule[lint]"
    

    Обратите внимание, что мы устанавливаем Molecule с опцией «lint», чтобы pip также поставил инструменты «yamllint» и «ansible-lint», которые позволят нам использовать Molecule для статического анализа кода роли на предмет соответствия стандартам кодирования Ansible.

    Установка скачивает все необходимые зависимости из интернета, включая Ansible. Теперь смотрим что мы установили:

    $ molecule --version
    molecule 3.0.4
       ansible==2.9.10 python==3.6
    

    Что ж, пора использовать команду «molecule», чтобы инициализировать новую роль Ansible.

    Инициализируем новую роль Ansible


    Вообще говоря, при разработке новой роли Ansible, она инициализируется командой «ansible-galaxy role init», но мы будем использовать вместо этого команду «molecule». При этом мы получим ту же структуру роли, что и с командой «ansible-galaxy», а также базовую заготовку кода для запуска тестов Molecule.

    По умолчанию Molecule использует для выполнения тестов драйвер Docker. Поскольку мы хотим использовать вместо него podman, то при инициализации роли командой «molecule» надо указать соответствующий драйвер с помощью опции «--driver-name=podman».

    Переключаемся обратно в каталог «molecule-blog» и инициализируем новую роль «mywebapp» следующей командой:

    $ molecule init role mywebapp --driver-name=podman
    --> Initializing new role mywebapp...
    Initialized role in /home/ricardo/molecule-blog/mywebapp successfully.
    

    Molecule создает структуру нашей роли в папке «mywebapp». Переключаемся в эту папку и смотрим, что там:

    $ cd mywebapp
    $ tree
    .
    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── molecule
    │   └── default
    │       ├── converge.yml
    │       ├── INSTALL.rst
    │       ├── molecule.yml
    │       └── verify.yml
    ├── README.md
    ├── tasks
    │   └── main.yml
    ├── templates
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml
     
    10 directories, 12 files
    

    Molecule складывает свои конфигурационные файлы в подкаталог «molecule». При инициализации новой роли здесь появляется всего один сценарий, который называется «default». Позднее сюда можно добавить свои сценарии для тестирования различных условий. В этой статье мы будем использовать только сценарий «default».

    Проверим базовую конфигурацию в файле «molecule/default/molecule.yml»:

    $ cat molecule/default/molecule.yml 
    ---
    dependency:
      name: galaxy
    driver:
      name: podman
    platforms:
      - name: instance
        image: docker.io/pycontribs/centos:7
        pre_build_image: true
    provisioner:
      name: ansible
    verifier:
      name: ansible
    

    Как мы и просили, в этом файле указано, что для тестов применяется драйвер Podman. Здесь же задается платформа по умолчанию для тестового инстанса, через контейнерный образ «docker.io/pycontribs/centos:7», который мы потом поменяем.

    В отличие Molecule v2, Molecule v3 не задает линтер по умолчанию. Поэтому откроем конфигурационный файл «molecule/default/molecule.yml» и допишем в конце конфигурацию lint:

    $ vi molecule/default/molecule.yml
    ...
    verifier:
      name: ansible
    lint: |
      set -e
      yamllint .
      ansible-lint .
    

    Сохраним и закроем файл, и запустим команду «molecule lint» из корневой папки нашего проекта, чтобы прогнать линтер по всему проекту:

    $ molecule lint
    

    На выходе получаем несколько ошибок, поскольку в файле «meta/main.yml» нет ряда требуемых значений. Исправим это: отредактируем файл «meta/main.yml», добавив «author», «company», «license», «platforms» и удалив пустую строку в конце. Для краткости обойдемся без комментариев, и тогда наш «meta/main.yaml» будет выглядеть так:

    $ vi meta/main.yml
    galaxy_info:
      author: Ricardo Gerardi
      description: Mywebapp role deploys a sample web app 
      company: Red Hat 
     
      license: MIT 
     
      min_ansible_version: 2.9
     
      platforms:
      - name: rhel
        versions:
        - 8 
      - name: ubuntu
        versions:
        - 20.04
     
      galaxy_tags: []
     
    dependencies: []
    

    Еще раз прогоним по проекту линтер и убедимся, что ошибок больше нет.

    $ molecule lint
    --> Test matrix
        
    └── default
        ├── dependency
        └── lint
        
    --> Scenario: 'default'
    --> Action: 'dependency'
    Skipping, missing the requirements file.
    Skipping, missing the requirements file.
    --> Scenario: 'default'
    --> Action: 'lint'
    --> Executing: set -e
    yamllint .
    ansible-lint . 
    

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

    Создаем тестовый инстанс


    По умолчанию Molecule задает только один инстанс, которые называется «instance» и создается из образа «Centos:7». Наша роль, если помните, должна работать на RHEL 8 и Ubuntu 20.04. Кроме того, поскольку она запускает веб-сервер Apache в качестве системной службы, нам нужен контейнерный образ с включенным «systemd».

    У Red Hat есть официальный Universal Base Image для RHEL 8 с включенным «systemd»:

    • registry.access.redhat.com/ubi8/ubi-init

    Для Ubuntu нет официального образа с «systemd», поэтому мы воспользуемся образом, который поддерживается силами Джефа Джирлинга (Jeff Geerling) из сообщества Ansible:

    • geerlingguy/docker-ubuntu2004-ansible

    Чтобы получить инстансы с «systemd», подправим конфигурационный файл «molecule/default/molecule.yml», убрав из него инстанс «centos:7» и добавив два новых инстанса:

    $ vi molecule/default/molecule.yml
    ---
    dependency:
      name: galaxy
    driver:
      name: podman
    platforms:
      - name: rhel8
        image: registry.access.redhat.com/ubi8/ubi-init
        tmpfs:
          - /run
          - /tmp
        volumes:
          - /sys/fs/cgroup:/sys/fs/cgroup:ro
        capabilities:
          - SYS_ADMIN
        command: "/usr/sbin/init"
        pre_build_image: true
      - name: ubuntu
        image: geerlingguy/docker-ubuntu2004-ansible
        tmpfs:
          - /run
          - /tmp
        volumes:
          - /sys/fs/cgroup:/sys/fs/cgroup:ro
        capabilities:
          - SYS_ADMIN
        command: "/lib/systemd/systemd"
        pre_build_image: true
    provisioner:
      name: ansible
    verifier:
      name: ansible
    lint: |
      set -e
      yamllint .
      ansible-lint .
    

    С помощью этих параметров мы монтируем для каждого инстанса временную файловую систему «/run» и «/tmp», а также том «cgroup». Кроме того, мы включаем функцию «SYS_ADMIN», необходимую для запуска контейнеров с Systemd.

    Если делать все по уму и выполнять этот пример на машине RHEL 8 с включенным SELinux, то еще надо установить в true логический параметр «container_manage_cgroup», чтобы контейнеры могли запускать Systemd, (подробнее см. документацию RHEL 8):

    sudo setsebool -P container_manage_cgroup 1
    

    Для инициализации этих инстансов Molecule использует Ansible Playbook. Изменим и добавим параметры инициализации, модифицировав словарь «provisioner» в конфигурационном файле «molecule/default/molecule.yml».

    Он принимает те же самые опции конфигурации, что прописаны в конфигурационном файле «ansible.cfg». Например, обновим конфигурацию провайдера (provisioner), добавив секцию «defaults». Установим интерпретатор Python в «auto_silent», чтобы деактивировать предупреждения. Включим callback-плагины «profile_tasks», «timer» и «yaml», чтобы профайлерская информация включалась в вывод Playbook. И наконец, добавим секцию «ssh_connection» и отключим SSH pipelining, поскольку он не работает с Podman:

    provisioner:
      name: ansible
      config_options:
        defaults:
          interpreter_python: auto_silent
          callback_whitelist: profile_tasks, timer, yaml
        ssh_connection:
          pipelining: false
    

    Сохраним этот файл и создадим инстанс командой «molecule create» из корневого каталога нашей роли:

    $ molecule create
    

    Molecule выполнит инициализационный плейбук и создаст оба наших инстанса. Проверим их командой «molecule list»:

    $ molecule list
    Instance Name    Driver Name    Provisioner Name    Scenario Name    Created    Converged
    ---------------  -------------  ------------------  ---------------  ---------  -----------
    rhel8            podman         ansible             default          true       false
    ubuntu           podman         ansible             default          true       false
    

    Также проверим, что оба контейнера запущены в Podman:

    $ podman ps
    CONTAINER ID  IMAGE                                                   COMMAND               CREATED             STATUS                 PORTS  NAMES
    2e2f14eaa37b  docker.io/geerlingguy/docker-ubuntu2004-ansible:latest  /lib/systemd/syst...  About a minute ago  Up About a minute ago         ubuntu
    2ce0a0ea8692  registry.access.redhat.com/ubi8/ubi-init:latest         /usr/sbin/init        About a minute ago  Up About a minute ago         rhel8
    

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

    Заключение


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

    Red Hat
    Программные решения с открытым исходным кодом

    Комментарии 13

      0

      Молекула мертва, потому что её highly opinionated не работает IRL.
      1) Большинство людей хочет проверять плейбуки, а не роли.
      2) Тесты для тривиальных ролей писать особо не надо, а для нетривиальных у молекулы нет никаких возможностей правильно описать нетривиальность (например, внешние зависимости).
      3) Драйвера ужасны. Любая роль, выходящая за рамки "ой мы тут сделали file: state=directory и нам надо написать ТЕСТЫ ДЛЯ ЭТОЙ РОЛИ" тут же утыкается в то, что докер на сервера похож, мягко говоря, не совсем — привет systemd, привет reboot, привет ntp, привет /etc/hosts, и т.д. А попытка поменять драйвер с контейнерного на (хотя бы виртуалки) открывает бездны нового порядка. Например, плейбука для подъёма драйвера пишется в /tmp и используется оттуда, даже если драйвер поменяли. (Перезагрузите компьютер, чтобы всё начало работать).


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


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

        0
        Amarao, тесты инфраструктуры на Goss не пробовали писать? Как оцените инструмент?
          0

          Я мельком её (его?) смотрел. Их подход работает для простых случаев, а в них и так всё хорошо. В сложных случаях же выкрутасы с ещё одним template language — ой, не надо.


          Мы используем testinfra, у которой помимо мощи pytest'а под капотом ещё какая-никакая интеграция с ansible'ом (можно использовать инвентори и дёргать модули в checkmode'е, а если очень хочется, то можно и транспорт ансибла использовать).

          0
          1) Большинство людей хочет проверять плейбуки, а не роли.
          Совершенно не обязательно. В парадигме ансибл роли это функции, которые и нужно проверять. Плейбуки это скорее полное функциональное тестирование.
          Одно другое не заменяет.
          2) Тесты для тривиальных ролей писать особо не надо, а для нетривиальных у молекулы нет никаких возможностей правильно описать нетривиальность (например, внешние зависимости).
          Во-первых надо, может вам не надо — так не пишите. Во-вторых у молекулы есть requirements management, prepare стадия и т.д. Что именно не хватает?
          Любая роль, выходящая за рамки «ой мы тут сделали file: state=directory и нам надо написать ТЕСТЫ ДЛЯ ЭТОЙ РОЛИ» тут же утыкается в то, что докер на сервера похож, мягко говоря, не совсем — привет systemd, привет reboot, привет ntp, привет /etc/hosts, и т.д.
          Вы понимаете что молекула и впрочем ансибл тут совершенно ни при чем? Это технические сложности с докером, к ним и обращайтесь, а лучше используйте podman как в статье рекомендуется. Хотя бы /etc/hosts и systemd вас перестанут волновать. Ну или используйте delegated.
          Например, плейбука для подъёма драйвера пишется в /tmp и используется оттуда, даже если драйвер поменяли.
          Опять же, с виртуальным, или еще лучше — delegated драйвер, это почти все равно как гонять это на обычном сервере. Молекула тут вообще ни при чем, это проблема с вашими ролями и вашим окружением. Она то свое дело делает.
          Молекула мертва, потому что её highly opinionated не работает IRL
          Скорее всего вы ожидаете от этого проекта много того, чего он никогда в жизни не обещал и не был предназначен. Все ваши проблемы из-за ваших специфических технических сложностей и из-за непонимания ансибл и его принципа построения ролей в частности.
            0

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


            - call_role: rolename
              return_variable: foo

            И внутри роли - return: somevalue


            к сожалению, ничего этого нет. Вместо этого у нас глобальные переменные с несовместимыми lifetimes.


            Насчёт моего окружения вы правы. Взял молекулу, взял ансибл, сказал запускать на libvirt'е, а потом поменял драйвер на openstack, а libvirt всё ещё используется, потому что записано в /tmp (и имеет больший приоритет, чем то, что в плейбуке). Я один день на это "моё окружение" потратил и полностью для себя молекулу закопал.


            Основная же проблема в том, что reusable roles в отсутствии изоляции — необоснованная фантазия. Это легко заметить по, например, даже rhel'овому коду для ансибла — openshift, ceph-ansible — у обоих всё, мягко говоря, не в рамках мечтаний о "reusable roles". Роль обычно пишется под задачу и в отсутствии задачи смысла не имеет. А тогда уже надо плейбуки тестировать.


            Насчёт непонимания анисбла — да, спасибо, это вы точно заметили. Каждый раз, когда я в ansible bingo дописываю пример, я глубоко не понимаю как это можно понимать.

              0
              к сожалению, ничего этого нет. Вместо этого у нас глобальные переменные с несовместимыми lifetimes.
              О чем вы вообще? Какие еще несовместимые lifetimes? Что вы делаете с ансиблом? о_О
              Основная же проблема в том, что reusable roles в отсутствии изоляции — необоснованная фантазия.
              Я лет 7 наверное слушаю постоянное нытье что роли в ансибле это плохо, они плохо работают, это никогда не работает и т.д. и т.п. И каждый раз когда дело доходит до деталей, оказывается что человек просто не следует никаким вообще good practices, guidelines, нет никакого нормального дизайна, а иногда просто творит необъяснимые странные вещи. Но виноват ансибл и роли.
              Вот у вас все плохо, а у меня все прекрасно с reusable roles, кому лучше?
              Каждый раз, когда я в ansible bingo дописываю пример, я глубоко не понимаю как это можно понимать.
              Это поправимо, читайте больше документации, делайте хороший продуманный дизайн перед тем как запускать хаос написанный на коленках, наймите девопса наконец-то вместо сисадмина, и будет вам счастье. :)
                0

                Скажите, сколько живёт переменная, заданная в task/vars? А переменная, заданная в play/vars? А set_fact? А если переменная set_fact из include? А если переменная из role/defaults, которая была include?


                Вы знаете, мы очень много пишем на ансибле, и у нас сложилась очень сильная практическая школа. Один из принципов этой школы состоит в том, что чем проще, тем лучше (даже если решение будет неуниверсальным). Это значает, что никаких include_vars в зависимости от переменных, никогда не используется include_role, а include_tasks в loop — это code smell (который иногда нужен, но которого надо избежать). И один из принципов говорит, что нельзя бороться за универсализацию ролей. Чем более универсальна роль, тем более волшебным образом она взрывается.


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


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


                (Вот вам контр-пример того, как писать не надо — роль пытается принимать стопятьсот решений https://github.com/AlexeySetevoi/ansible-clickhouse/blob/master/tasks/main.yml… и взрывается, если процесс решений не совсем такой, как ожидали. Например, case sensitive file system. Баг до сих пор не заслали, но он там есть).

                  0
                  Скажите, сколько живёт переменная, заданная в task/vars? А переменная, заданная в play/vars? А set_fact? А если переменная set_fact из include? А если переменная из role/defaults, которая была include?
                  Это неправильный вопрос. Правильный вопрос — «какой у них scope и priority?» Документация отвечает на этот вопрос.
                  Один из принципов этой школы состоит в том, что чем проще, тем лучше
                  Это конечно очень оригинальная идея, предлагаю запатентовать, украдут же.
                  Чем более универсальна роль, тем более волшебным образом она взрывается.

                  чем меньше решений принимается на Ансибле, тем лучше

                  совершеннейший кошмар для программирования (принятия решений).

                  Я рад что вы на своем опыте открываете good practices ансибла, но лучше все-таки учиться на чужих ошибках. Все правильно, ансибл — не для программирования, у ансибл девов это уже мантра. Но есть люди, при виде микроскопа у которых, руки сразу тянутся к гвоздям.
                  оказывается, что в отрыве от плейбуки она не особо и нужна. Так что тестировать надо плейбуки.
                  Вот как вы к этом выводу пришли, для меня загадка. Нужно тестировать отдельную фунциональность ролей, каждая из которых «хорошо умеет делать что-то одно».
                    0

                    Ну вот видите, вроде, согласились, а потом строго наоборот перевернули. Вы говорите расхожую unix-истину "хорошо умеет делать что-то одно". Не хорошо, а минимально необходимо. Роль для postgress не умеет "хорошо настраивать постгресс", а настраивает только то, что нужно в проекте. Это снижает сложность ролей на несколько порядков и именно в этом месте попытка писать роли как программы или функции (которые делают одно, но делают хорошо), натыкается на полное отсутствие изоляции. Одна ошибка в именновании приватной перменной (ой, у нас же нет приватных перменных) и роль взрывает проект из-за того, что еёйный set_fact с database_ip оверрайдит roles/vars/database_ip в другой роли. Разумеется, существует техника defensive programming по именованию приватных переменных в роли (что увеличивает нагрузку на пишущего в несколько раз); но лучший выход из ситуации — не пытаться делать "хорошо", а делать минимально необходимое без запаса на расширение. Нужно расширение — перепиши простой предыдущий код. Это легче, чем сопровождать универсальный код.

                      0
                      Разумеется, существует техника defensive programming по именованию приватных переменных в роли (что увеличивает нагрузку на пишущего в несколько раз);
                      Да, есть практика ставить префиксы ролей перед переменными чтобы не путаться. Но в питоне тоже надо underscore перед переменными ставить чтобы отличить приватные.
                      Так что если писать сначала нормально, то никакой нагрузки на пишущего нет. А если и линтер настроить чтобы проверял это, то вообще можно спать спокойно.
                      Роль для postgress не умеет «хорошо настраивать постгресс», а настраивает только то, что нужно в проекте.
                      Ну если она делает все что нужно для постгрес в проекте, то не вижу проблемы. Если же она пытается прописать IP везде где можно, вмешиваясь там где другие роли работают и т.д. — то это уже дизайн проблема.
                      Для таких вещей можно, кстати, использовать коллекции, где можно хостить много ролей, которые делают что-то одно, и плейбуки, которые их комбинируют чтобы сделать что-то большое и сложное.
                        0

                        То есть проблемы с изоляцией имён не существует. В питоне есть локальные переменные, в Ансибле нет, "но в ведь в питоне приватные перменные тоже underscore обозначают".


                        Насчёт "прописать IP" — этот вопрос мы ещё даже близко не затронули, потому что всё что касается хождения по чужим перменным — боль и постоянная балансировка между кривым решением, code smell и лапшой.


                        В целом я вашу позицию понял — вы проблем не видите, а всё остальное — моя некомпетентность. Ваша позиция мне ясна, менять её у меня стимула нет.

                          0
                          питоне есть локальные переменные, в Ансибле нет, «но в ведь в питоне приватные перменные тоже underscore обозначают».
                          Да, потому что:
                          ансибл — не для программирования

                          Вы сами это признаете, а потом требуете от него быть языком программирования.
                          Или может в терраформе есть какие-то приватные переменные?
                          вы проблем не видите, а всё остальное — моя некомпетентность.
                          Я их не вижу потому что использую для каждого дела свою утилиту. Если хочется попрограммировать — ansible-runner вам в помощь.
            0

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


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


            1. это далеко не каждому сможет подойти
            2. не отменяет проблем с systemd, reboot итд

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

          Самое читаемое