Автоматизация инфраструктуры в GCP с Deployment Manager

deployment manager

Даже не знаю, как так получилось, но даже регулярно пересекаясь с Google Cloud Platform последние два года, я абсолютно упустил тот факт, что в GCP есть свой собственный инструмент для автоматизации развёртывания инфраструктуры: создания виртуальных машин, аккаунтов, сетей и прочего. Но он реально есть! В главном меню даже есть ссылка.
Инструмент называется Deployment Manager и он может автоматически создать практически всё, что есть Google Cloud. Прямо с одной команды. Так как DM разрабатывал Гугл, то у первого весьма извилистая кривая обучения, не всегда свежая документация, и иногда неочевидные логика. Но штука работает. Так как до этого я в основном автоматизировал развёртывание приложений от хоста и вверх — через всякие VagrantAnsibledocker-compose или kubectl, по посмотреть, как делать первую половину задачи — от хоста и вниз, — будет весьма интересно.

Как это работает

Принцип в чём-то похож на тот, что используется в docker-compose или Ansible. Мы задаём файл конфигурации, который описывает инфраструктуру приложения — виртуальные машины, сети, файрволы и остальное, а Deployment Manager из этого файла их и создаёт. Так как он относится к конфигурации как единому юниту развёртывания — «деплойменту», то позже по нему можно запросить статус, обновить какие-то узлы, или даже удалить целиком.

Что интересно (но совсем не удивительно), DM не станет создавать, например, новые виртуальные машины, если эти машины уже есть. Это поведение по умолчанию, его можно переопределить, и оно отлично иллюстрирует концепцию декларативной «желаемой конфигурации», а не императивного «сделай вот так». С этим поведением, правда, может выйти и косяк. Например, если два деплоймента создают виртуальные машины с одинаковым именем, то тот, кто пришёл последним, свою машину не создаст, а вместо этого попытается отдолжить её у товарища. Дебагить такие штуки — очень увлекательно.

Простой пример конфигурации деплоймента

Вот, например, как можно декларативно создать виртуальную машину:

Если перед этим мы где-тто установили и настроили Cloud SDK, а гугловый Deployment Manager API включён (что очень часто случается по умолчанию), то из командной строки эту конфигурацию можно отправить прямиком в облако:

Смотрим на результаты

А теперь мы можем убедиться, что деплоймент удался. Во-первых, посмотрим, что он реально создался:

deployment manager UI

А во-вторых, проверим, что созданная им виртуальная машина тоже где-то рядом:

Небольшое улучшение: добавляем машине внешний IP

Вот что можно сделать лучше. В такой конфигурации у виртуальной машины не будет внешней айпишки, так что все входящие соединения из внешней, не внутренней гугловой сети, туда не пройдут. В том числе это касается и попыток зайти на VM по SSH.

Исправить это очень легко. Нужно всего-лишь добавить такой вот accessConfig в networkInterfaces, и все разрешённые файрволом соединения смогут пройти. Если VM создавалась в дефолтной сети, то SSH будет разрешён по-умолчанию.

Более реалистичный пример

Создавать виртуалки по одиночке очень здорово для блог-постов, но для реального мира этого маловато. В нормальной жизни скорее всего придётся создавать сразу несколько ресурсов. Какие-то из них будут ссылаться друг на друга, и поэтому в деплойменте появятся явные и неявные зависимости, а это значит, что создавать их нужно по очереди и в определённом порядке. Так как Deployment Manager создаёт ресурсы параллельно и все сразу, то эту иерархию и очерёдность надо будет как-то обозначить.
Есть как минимум два способа это сделать: через метаданные и через ссылки.

Явные зависимости через метаданные

Это самый простой, но по моему мнению немного брутфорсный способ задать иерархию. Например, если нам нужно создать сеть и подключённую к ней виртуальную машину, то обозначить очерёдность «сначала создай сеть, потому машину» можно вот так:

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

Зависимости через ссылки

Посмотрим на такой пример. Допустим, мы хотим создать виртуальную машину, подключённую к отдельной сети, и в которую разрешён SSH. В терминологии GCP нам нужно будет создать три ресурса: сеть, правило в файрволе и виртуальную машину. А именно, сначала сеть, а уже потом всё остальное. Чтобы объяснить это DM’у, можно расставить вот такие ссылки-зависимости:

Когда мы отправим эту конфигурацию в облако, то уже через UI будет очень заметно, что ресурсы создаются по очереди:

Создаётся сеть

Через пару секунд:

Создаётся всё остальное

Ну и конечно можно проверить, что VM действительно подключена к новой сети, и SSH-правило для файрвола тоже там:

Сети

Правила файрвола

Заключение

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

Deployment Manager — вполне прикольный. Да, с ним немного тяжело начать, потому что внятных примеров для него как-то не особо, да и те, что есть, не всегда работают с текущей версией гуглового API. Да, чтобы найти ответы на некоторые очень очевидные вопросы, вроде какие конфигурационные свойства можно задавать, или как проверить правильность схемы шаблона, нужно делать неожиданно много Гугла. Но пока мне удавалось найти хоть что-то, так что жить можно.

Сейчас мне интересно, насколько DM пересекается по фичам с  Terraform, который работает в том же поле. По ощущениям, DM будет проигрывать. Хотя кто его знает, с Terraform я ведь ещё не работал. Но, думаю, прежде чем соваться туда, стоит посмотреть на ещё парочку интересных штук от Deployment Manager, благо они там есть.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *