IBM Senior DevOps Engineer & Integration Architect. Официальный DevOps ментор и коуч в IBM   Привет, Хабр! Давайте поговорим про асинхронность в Ansible, а именно о том, что это и зачем использовать.В Ansible есть понятие Async Actions. Ansible устанавливает подключение к целевым серверам через SSH. Это означает, что соединения SSH остаются активными на протяжении всего выполнения таска в плейбуке. Иногда нам может понадобиться выполнить длительный таск или процесс, который превышает тайм-аут SSH. Мы можем просто не захотеть, чтобы SSH-соединение оставалось активным на протяжении всей операции или же можем захотеть запустить несколько процессов одновременно и проверить их позже. Или другой вариант использования, возможно, для запуска одного или нескольких процессов, даже не удосужившись проверить их статус. Все это может быть достигнуто с помощью асинхронных действий. Допустим, в рамках развертывания нашего веб-приложения, есть скрипт, который отслеживает и выполняет некоторые проверки, скажем healthchecks на веб-сервере. Он находится по пути opt/monitor/checks.py. Скрипты выполняют различные проверки, как например проверку стабильности, чтобы убедиться, что веб-сервер остается в сети не менее пяти минут без каких-либо проблем. Таким образом, очевидно, что для завершения выполнения этого скрипта требуется не менее пяти минут. Мы не хотим, чтобы Ansible поддерживал сеанс SSH, пока скрипт не завершит выполнение. Мы хотим сообщить Ansible, что это асинхронная задача (таск), поэтому надо запустить ее и проверять, скажем, каждую минуту. Мы используем директиву async, чтобы указать максимальное время, в течение которого ожидаем выполнения таска. В нашем случае, скажем, шесть минут, учитывая другие проверки, которые необходимо выполнить. Директива async сообщает Ansible, что это асинхронный таск, поэтому просто пусть запустит ее и проверит позже. По умолчанию Ansible проверяет каждые 10 секунд. Если мы хотим изменить это, можно использовать директиву poll. Проверять каждые 10 секунд для нас слишком часто, и мы не хотим ждать пять минут, потому что вдруг скрипт выйдет в ошибку после первой минуты? Мы также не хотим тратить оставшиеся четыре минуты на ожидание, пока Ansible проверит статус. В связи с чем проверка каждую минуту кажется хорошей идеей. Устанавливаем значение poll на 60. Давайте добавим еще один таск  для мониторинга, например, баз данных и дадим ему шесть минут на выполнение и poll каждые 60 секунд. Что здесь происходит? Когда Ansible начинает выполнение, он сначала выполняет первую таску, и все равно будет ждать завершения этой таски. Асинхронность не означает, что Ansible будет запускать это и двигаться вперед. Он будет отслеживать состояние скрипта и ждать, пока не истечет указанное время. В данном случае 360 секунд. Таким образом, в данном случае он запустит первую проверку, затем подождет около шести минут, пока она не завершится, после чего запустит второй скрипт для проверки базы данных и подождет еще шесть минут до завершения. Если бы мы запустили их параллельно, то могли бы сэкономить много времени. Таким образом, нам необходимо запустить первую таску, и чтобы Ansible немедленно перешел ко второй таске и начал вторую проверку, а затем дождался завершения обеих тасков в конце. Сделать это можно установив значение poll равным нулю. Установив значение poll в ноль, мы просим Ansible не ждать, а сразу перейти к следующему таску. В этом случае Ansible перейдет к следующему таску. Однако сразу после запуска второй таски завершит работу. Мы ничего не сделали, чтобы Ansible ждал завершения таски в конце. Для этого сначала нужно зарегистрировать результат тасок в переменной. Итак, в этом случае мы регистрируем результат первой таски, которая отслеживает веб-приложение, в переменную с именем webapp_result. Также регистрируем результат второй таски, которая заключается в мониторинге базы данных, в переменную db_result. Так мы получим новую таску до конца, которая называется проверка статуса таска. Для проверки статуса таски используем модуль async_status. Таким образом, одним из параметров, которые принимает модуль async_status, является идентификатор таска, и мы могли бы получить идентификатор задания для предыдущего таска используя webapp_result, который мы зарегистрировали, и .ansible_job_id. Итак, здесь мы передаем идентификатор задания для предыдущего таска, а затем ждем, пока этот таск не будет завершен. Однако стоит помнить, что не все модули поддерживают асинхронность. Нам нужно добавить плей в плейбук, который будет мониторить веб-апку в течении 5 минут, чтобы убедиться что с приложением все в порядке, но мы не хотим держать открытым ssh-соединение все это время. Также у нас есть второй плей на мониторинг базы данных, оба плея будут выполняться параллельно. Результаты выполнения зарегистрируем в переменные: В современном мире развития программного обеспечения необходимость быстрого и автоматизированного деплоя становится все более важной. Однако использование инструментов, таких как Kubernetes, не всегда доступно или оправдано. Ansible же является гибким и мощным инструментом, который может быть использован в любой обстановке. Приглашаю вас на бесплатный вебинар, в рамках которого мои коллеги поделятся с вами своими знаниями и опытом в области использования Ansible для деплоя приложений. Вы узнаете, как настроить автоматический процесс развертывания с помощью Ansible и Docker, минуя сложности и необходимость в Kubernetes. Редактор