Расскажу немного о себе. Я работаю в проекте Standoff365, который предоставляет платформу для комплексной защиты кибер угроз. Я занимаюсь автоматизацией развертывания кибер полигонов или другими словами цифровых инфраструктур компаний различной архитектуры.
И стояла основная задача, быстро разворачивать цифровую инфраструктуру "по кнопке". Казалось, уже всё есть, есть инструменты, подходы, бери и используй, но "дьявол кроется в деталях". В этой статье я расскажу как мы готовились к возможности внедрения юзер-френдли конфигуратора.
Основная идея, в удобном инструменте (WEB-portal), желательно в GUI рисовать схему цифровой инфраструктуры и передавать их в систему развертывания (Deployer).
Что у нас было
-
Могли выбрать любые инструменты.
-
WEB-портал должен что-то передать, чтобы Deployer мог "переварить" сформированную конфигурацию.
-
Техническое задание. Это разворачивать любые(в разумных приделах) архитектуры "живых" компаний
-
Что значит живых!? Это: полная готовность инфраструктуры к работе, все пользователи заведены в сервисах с нужными правами, все сервисы настроены и работают в боевом режиме. Если кратко: подготовка цифровых двойников.
-
Любые OS
-
Любые ПО
-
Любые сетевые связности
-
Выбор инструмента
Инструмента особо выбирать не пришлось, нужен был максимальных охват поддерживаемых платформ, поддерживаемых приложений, сетевых инструментов, развитый комьюнити и остального по мелочи 😊
В общем, остановились на - ansible.
В ansible есть основной элемент конфигурации, это inventory. В принципе, подходит для возможности конфигурации внешним инструментом, но вот подход к конфигурированию нужно было пересмотреть. Общепринятый подход, который описан на официальном сайте основан на объединении хосты в группы по функциональному признаку и описыванию переменных для групп и хостов:
all:
children:
itop:
hosts:
itop32:
gitlab:
hosts:
gitlab1:
os_linux:
hosts:
gitlab1:
itop32:
Т.е. если нам какой-то сценарий(playbook) запустить на все сервера os_linux , мы просто выбираем нужную группу. Эту группу еще можно предварительно настроить, указать, к примеру, параметры подключения. Довольно удобно.
Но когда нужно 200-300 разнородных машин прописать в inventory, да еще как-то динамически и не ошибиться, задача превращалась в дни конфигурирования и переразвертывания.
Встала основная задача, как же конфигурировать.
Техническое задание для интеграции
Т.о. мы подошли к основному вопросу:
Как средствами ansible inventory конфигурировать гетерогенные инфраструктуры и "натравливать" playbook-и для разворачивания не урезая функционал ansible inventory(наследования переменных, приоритизации, прозрачности)? Что и стало технических заданием для подготовки инструментов конфигурирования.
Описание решения
Самое значимое решение, это было: отвязать группы ansible inventory от функционала разворачиваемого на хостах.
В чем заключался такой подход
-
Для конкретного хоста в Ansible inventory задается роль в общей инфраструктуре. Для каждого хоста заводилась переменная, какой полный сценарий там будет установлен, начиная с ОС и до мелких настроек приложений.
-
Группы больше не использовались по функциональному разделению и поэтому можно их использовать для инфраструктурного конфигурирования.
-
Минимальный элемент конфигурирования стал хост с конкретным сценарием, который расположен в конкретной подсети, которая настроена на конкретном шлюзе, который подключен к другому шлюзу и т.д.
-
В дополнении в этому, для конфигурирования взаимодействия хоста с другими хостами введены группы переменных:
-
Группа конфигурационных переменных внешних сервисов по отношению к текущему (к примеру: для хоста задается информация о внешнем DNS)
-
Группа конфигурационных переменных внутренних сервисов по отношению к текущему (к примеру: для хоста задается версия устанавливаемого ПО)
-
Таким образом мы получили вполне лаконичное описание инфраструктуры которые ложится в структуру ansible inventory.
All:
children:
internet:
hosts:
router1:
servicename: router
subnet_srv:
vars:
external_router: router1
hosts:
gitlab:
servicename: gitlab
serviceversion: "16.11.10"
itop:
servicename: itop
serviceversion: "2.4"
subnet_ws:
vars:
external_router: router1
hosts:
ws-admin:
servicename: admin_windows10
ws-finance:
servicename: finance_windows11
subnet_subnet1:
vars:
external_router: router2
hosts:
router2:
servicename: router
subnet_db:
vars:
external_router: router2
hosts:
mysql:
servicename: mysql_debian11
subnet_is:
hosts:
is:
servicename: is_astra175
Как вы могли заметить:
-
для групп подсетей указывается конкретный роутер, за которым закреплена подсеть. Что формирует связи сетей с роутером.
-
для сервисов gitlab и itop задана конфигурация внутреннего сервиса.
Дополнение
Не в рамках этой статьи, но для общего понимания важности подхода отмечу: каждый хост в рамках ansible inventory имеет все данные о соседних сервисах, их именах, какие сервисы установлены и как сконфигурированы. На этом строится интеграционное конфигурирование между сервисами на хостах (куда хосту ходить за DNS, где создавать учетки, какие права настраивать и т.п.).
Основная схема интеграции с WEB-portal получилась следующая:
Ansible inventory стал промежуточным звеном для выполнения развертывания инфраструктуры. (Работу самого Deployer в рамках этой статьи рассматривать не будем)
Применение решения
Такой подход позволил примерить решение следующих задачах:
-
Тестирование разрабатываемых продуктов на гетерогенные сети (разных клиентов антивирусов, ERP клиентов, SIEM и любым другим системам)
-
Тестированием глобальных продуктов, чтобы не развалить боевую инфраструктуру компании.
-
Тестирование маршрутизаторов.
-
И в принципе всего, где нужно разворачивать большой объем сервисов и инфраструктур с минимальными затратами.
Итого
Мы сформировали подход к конфигурированию практически любых инфраструктур с имеющимся инструментом и без больших затрат на разработку и реализацию.
От автора
Не ограничивайте себя функционалом конкретного инструмента, даже если инструмент выбран, добавив небольшие изменения можно его сделать намного эффективнее.
Автор: Wahrsager