Привет, Хабр. Я Александр Габидуллин, старший инженер внедрения в Группе Астра. Основная часть моей работы — автоматизация установки и разворачивания наших продуктов. Нередко заказчик ставит задачу, для которой нет готового «коробочного» решения — тогда я создаю своё.
Один из таких случаев — обновление парка из десятков тысяч рабочих станций с ALSE 1.7 на 1.8 без остановки бизнес-процессов.
Перед нами стояла задача: обеспечить бесшовное мажорное обновление десятков тысяч рабочих станций крупного промышленного холдинга с ALSE 1.7 на 1.8. Жёсткие требования исключали компромиссы: нулевой простой для пользователей, гарантированная сохранность кастомной экосистемы и усиление настроек безопасности в процессе.
В этой статье я расскажу, как мы создали Ansible-коллекцию, которая превратила рутинное обновление в промышленный процесс с 98.2% успешных запусков с первого раза.
1. Цель: не только обновить, а трансформировать
Мы обеспечивали ключевой этап цифровой трансформации, где мажорное обновление ОС было стратегическим шагом для повышения безопасности, стабильности и управляемости всей ИТ-инфраструктуры.
Ключевые требования:
Абсолютная бесшовность процесса для пользователей. Инженер в офисе или на месторождении не должен был столкнуться с внезапным «синим экраном», потерей данных или нерабочим ПО после мажорного обновления. Его рабочий день и бизнес-процессы не должны были прерваться ни на минуту. Фактически, мы должны были провести сложнейшую операцию, пока «пациент» продолжал работать.
Гарантированная сохранность всей кастомной экосистемы. Десятки специализированных пакетов, корпоративных сертификатов, уникальных конфигураций сетевых подключений и проприетарное ПО. Каждый такой элемент был критически важен для конкретного бизнес-процесса, и его потеря была недопустима.
Реальный нулевой простой бизнес-сервисов. В условиях круглосуточной работы предприятия простои означали прямые финансовые потери.
Усиление настроек безопасности. Требовалось гарантировать, что в процессе мажорного обновления ни одна из защитных мер (настройки ЗПС, блокировки интерпретаторов) не будет скомпрометирована.
2. Первые версии утилиты мажорного обновления: было сложно

Изначально за основу нашего процесса мы взяли штатные инструменты мажорного обновления — astra-full-upgrade (для графического режима) и astra-console-upgrade (для консоли). Их концепция элегантна и продумана: это полноценная установка новой ОС с последующим переносом данных и пользовательских настроек, а не просто «апдейт» пакетов поверх существующей системы.
Как это работало в первых версиях «из коробки»:
Предварительные проверки: Утилита проводила строгий аудит системы на соответствие требованиям: наличие свободного пространства, достаточного для создания резервных копий, проверка режима ЗПС, верификация пакетной базы на возможность переноса в целевую ОС .
Загрузка пакетов: Система скачивала все необходимые пакеты новой версии ОС (ALSE 1.8) в кеш и сторонние пакеты из внешних репозиториев, если стояло внешнее ПО, что позволяло провести установку впоследствии даже без доступа к сети.
Создание целевой системы: На месте исходной системы сначала создается образ (резервная копия), затем производиться загрузка с этого образа, разворачивание chroot-окружения с использованием исходной дисковой конфигурации и разворачивание целевой системы в этом chroot-окружении. Это обеспечивает отказоустойчивость на всем процессе проведения мажорного обновления. Ключевой особенностью было то, что разделы
/home,/bootи/boot/efiне копировались, а переиспользовались — это гарантировало сохранность пользовательских данных и загрузчика.Перенос пользовательских данных и конфигураций: После активации мажорного обновления при следующей перезагрузке происходил переход на новую систему. Старая ОС оставалась на диске в виде резервной копии, предоставляя возможность отката с помощью утилиты
astra-revert-upgrade.
Где мы столкнулись со стеной:
Утилита изначально разрабатывалась для работы в связке с системами управления конфигурациями и не содержала собственного механизма массового запуска. Масштабирование, контроль выполнения и оркестрация сознательно выносились на уровень инфраструктуры заказчика.
Такое разделение ответственности задало рамки дальнейшего внедрения. В ходе проекта мы столкнулись с рядом практических задач, связанных с интеграцией, расширяемостью и устойчивостью процесса обновления:
Масштабирование под парк рабочих станций
Изначально утилита была рассчитана на работу в связке со средствами управления конфигурациями, поэтому сама по себе не включала механизм массового запуска. На практике это оказалось вполне удобным: мы быстро интегрировали её с существующей у заказчика системой, благодаря чему централизованный запуск и контроль мажорного обновления заработали без необходимости добавлять в утилиту собственный сложный оркестратор.
Расширение конфигурации под нетипичные сценарии
Базовая конфигурация (upgrade.conf.yaml) специально сделана предсказуемой и безопасной по умолчанию — чтобы утилита надёжно работала в стандартных окружениях. В ходе проекта стало понятно, что заказчику требуется больше гибкости, и здесь встроенный механизм скриптов сыграл ключевую роль. Мы использовали возможность подключения пользовательских скриптов на разных этапах процесса, что позволило без изменения утилиты реализовать кастомные требования: от установки специфичных пакетов до интеграции нестандартных политик.
Адаптация под индивидуальные процессы заказчика
Во время внедрения выяснилось, что некоторые требования — например, взаимодействие с пользователем через GUI или интеграция с корпоративными системами заказчика — выходят за рамки типовых задач утилиты. Эти сценарии мы закрыли через внешние инструменты и расширения, сохранив при этом стабильность и чистоту базового функционала.
Дополнительные проверки и устойчивость к политике безопасности
Разнообразие настроек и политик на рабочих станциях требовало расширить перечень предварительных проверок. Мы оперативно добавили необходимые механизмы как в коллекцию, так и в саму утилиту, благодаря чему инструмент стал ещё устойчивее и надёжнее.
Пару примеров для понимания: Проверка umask, если на обновляемой машине выставлено umask 0027, то это затрагивало не только пакеты утилиты мажорного обновления.
Проверка включен или нет digsig ( ЗПС ), так как первые версии утилиты некорректно работали в режиме ЗПС.
3. Ansible в дело: Рождение коллекции и Push-модели
Так родилась идея создать собственную Ansible-коллекцию. На первом этапе мы реализовали push-модель, которая позволяла администратору централизованно и принудительно запускать мажорное обновление на группах хостов. Это был продуманный оркестратор всего процесса, а не просто набор скриптов.
Что это дало на практике:
- Единый контур управления для сотен машин через Ansible Inventory
- Сквозная идемпотентность — повторный запуск роли не ломал систему
- Расширенные предварительные проверки (prechecks), выходящие за рамки штатной утилиты:
Архитектурные особенности реализации
Код роли был разбит на теги и этапы, это обеспечивало гибкость, переиспользуемость и возможность пропускать шаги для оптимизации времени обновления:
# Основные этапы выполнения роли: - precheck.yml # Базовая проверка готовности - check_version_alse.yml # Проверка версии ОС - preparation.yml # Установка зависимостей - util_install.yml # Установка утилиты мажорного обновление - full_update.yml # Минорное обновление с 1.7.x до 1.7.6 - force_migration.yml # мажорное обновление с 1.7.6 до 1.8.1 - rollback_migration.yml # Откат при необходимости
Ключевые технические инновации:
1. Графический интерфейс процесса — создание прогресс-баров и уведомлений на рабочем столе и экране блокировки через кастомные bash-скрипты, запускаемые через systemd:
- name: Run progress.sh command: systemd-run /bin/bash "{{ migrate_tmp_dir }}/progress.sh"
2. Гибкая система тегов — возможность запускать отдельные этапы (только подготовку, только минорное обновление, только мажорное обновление):
ansible-playbook main.yml --tags "prepare" ansible-playbook main.yml --tags "precheck" ansible-playbook main.yml --tags "update"
3. Кастомизация через переменные — единый конфиг позволял выбирать режимы работы:
migrate_migration_status: true/false # Включить мажорное обновление migrate_update_status: true/false # Включить минорное обновление migrate_rollback_status: true/false # Включить откат обновления migrate_digsig_status: true/false # Управление ЗПC
Результат: Мы получили не просто обертку вокруг штатной утилиты, а полноценную систему оркестрации, которая превращала сложный многоэтапный процесс в одну команду ansible-playbook, выполняемую для всего парка рабочих станций одновременно. Это был качественный скачок от ручного управления к промышленной автоматизации.
4. Тесты, тесты... и первые грабли

Первые прогоны в тестовом контуре выявили спектр непредвиденных сценариев. Казалось , мы предусмотрели все в prechecks, но реальность внесла свои коррективы.
С какими «граблями» мы столкнулись
Тонкости работы с ЗПС: Автоматическое отключение digsig через Ansible не всегда срабатывало предсказуемо. В некоторых конфигурациях требовалась дополнительная перезагрузка для полной выгрузки модулей безопасности из памяти ядра, иначе утилита обновления не запускалась. Поэтому команда разработки реализовала возможность мажорного обновления без отключения ЗПС.
Сетевые артефакты: В изолированных сегментах сети пакеты из локальных репозиториев могли «зависать» при параллельной загрузке на 100+ машин, вызывая таймауты apt. Но благодаря заложенной функциональности в утилиту мажорного обновления, имелась возможность делать тонкую настройку параметров загрузки.
Конфликты версий пакетов: Кастомные сборки ПО заказчика иногда требовали интерактивных ответов во время установки. Это выливалось в «тихие» сбои, когда обновление формально проходило успешно, но критичное бизнес‑приложение отсутствует в новой системе.
Как мы выстроили процесс тестирования
Мы создали пирамиду тестовых стендов
Базовый стенд — "чистая" ALSE 1.7.6 для отладки идеального сценария
Нагруженный стенд — системы с имитацией активной работы пользователей (открытые приложения, смонтированные сетевые диски)
Проблемный стенд — специально "сломанные" конфигурации: переполненные диски, сбитые настройки безопасности, частично удаленные пакеты
Каждый кейс мы фиксировали, дорабатывали коллекцию и писали дополнительные валидации. Например, добавили проверку на фрагментацию дискового пространства и создали отдельные task-файлы для восстановления "битых" систем перед мажорным обновлением.
Совместная работа как ключ к скорости
Отдельно стоит отметить слаженную работу команды специалистов со стороны заказчика. Их вклад стал одним из ключевых факторов успеха.
Коллеги не просто сообщали о возникающих проблемах, а проводили глубокий первичный анализ ошибок на своих стендах, структурировали логи и предоставляли нам четкие, воспроизводимые кейсы.
Это позволило нашей команде сосредоточиться не на расшифровке сырых данных, а сразу на поиске и внедрении решений. Такой подход значительно ускорил цикл обратной связи и повысил качество каждой новой версии как нашей Ansible-коллекции, так и базовой утилиты обновления.
Итеративный процесс оттачивания
Это был классический agile-подход в действии:
Утроенный понедельник: Прогон тестов на 10+ конфигурациях;
Вечерний разбор полетов: Анализ логов и выявление ошибок;
Ночной билд: Выпуск новой версии коллекции с исправлениями;
Утренний регресс: Проверка, что новое не сломало старое.
Особую ценность представляло тестирование откатов — мы убедились, что в любой точке процесса можно безопасно откатиться к предыдущей версии ОС без потери данных. Для этого мы создали отдельные сценарии принудительного прерывания мажорного обновления на каждом из этапов.
Результат: После трех недель интенсивного тестирования мы прошли путь от 40% успешных мажорных обновлений до стабильных 98%. Каждые грабли, на которые мы наступили на нашем пути, делали нас сильнее, а набор инструментов перерос из теоретического решения в боеспособный продукт.
Параллельно мы активно взаимодействовали с командой разработчиков утилиты. Сообщали о найденных багах или необходимых фичах в штатной утилите мажорного обновления, предлагали улучшения. Многие наши идеи и правки были оперативно внедрены в следующие сборки.
5. Pull-модель с GUI: как мы сделали обновления удобными
Одним из ключевых запросов от заказчика была минимизация влияния на пользователей при обновление, и чтобы пользователь минимально мешал обновлению. Так на свет появилась вторая роль коллекции — migrate_pull.
Ее фичи:
GUI-интерфейс для пользователя с возможностью выбора времени установки.
Автоматический опрос и логирование ответов.
Вывод прогресс-баров и уведомлений на рабочий стол и экран блокировки.
Возможность запуска кастомных post-install скриптов (например, для переноса прикладного ПО).
Финальным и самым сложным этапом была адаптация под продуктивный контур заказчика. Здесь мы столкнулись с:
Версионностью кастомных пакетов (требовалось жестко фиксировать версии в
upgrade.conf.yaml).Разными схемами установки корпоративного ПО.
Необходимостью тонкой настройки сценариев для сохранения работоспособности специализированного софта.
Наша коллекция доказала свою гибкость, позволив описать все эти нюансы в виде конфигурационных файлов и шаблонов.
6. В цифрах

А зачем мы собирали статистику? Казалось бы, ответ очевиден - для руководства, но на самом деле она нужна была самой команде.
Мы делаем изменения, их становиться все больше, появляются новые проверки и новые версии утилиты, и нам самим хотелось увидеть, к чему приводят наши старания.
На момент написания статьи успешно мигрировано более 10870 ( пока статья получала общее согласование, счетчик перевалил за 50.000 успешных обновлений ) рабочих станций по всей стране. Процесс продолжается в плановом режиме.
Операционные показатели успеха:
Среднее время мажорного обновления одного рабочего места: менее 2 часов
Процент успешных обновлений с первого раза: 98.2%
Что означают эти цифры для бизнеса:
Снижение операционных рисков за счет перехода на актуальную, поддерживаемую версию ОС
Повышение производительности сотрудников благодаря современным функциям в ALSE 1.8
Сокращение будущих затрат на техническую поддержку благодаря единообразию окружения
Масштабируемость решения — отработанный процесс легко тиражировать на другие проекты
7. Уроки, которые мы вынесли для будущих проектов
Этот проект в очередной раз доказал простую истину: самые сложные технологические вызовы покоряются там, где сочетаются три ключевых элемента:
Сильная межфункциональная команда, где разработчики, инженеры и архитекторы работают как единый организм
Гибкость и готовность слышать заказчика, превращая его требования в технологические решения
Итеративный подход к решению задач, где каждый провал становится шагом к будущему успеху
Главный урок: автоматизация — это не про замену людей, а про умножение их возможностей. Наша Ansible-коллекция не исключила специалистов из процесса, а позволила им сосредоточиться на сложных кейсах, передав рутину машинам.
P.S. Если вам интересны технические детали реализации Ansible-коллекции — отпишитесь в комментариях. Возможно, темой для следующей статьи будет именно глубокий разбор ее устройства.
А если вы руководитель проекта, задумывающийся о подобной трансформации — будем рады поделиться опытом и метриками, которые помогут обосновать подобные инициативы в вашей компании.
