5 способов развернуть инфраструктуру в облаке

Я тут задумался намедни… Вот если бы мне захотелось создать в облаке сеть, виртуальную машину и файрвол для неё, как бы я это сделал? И, хотите, верьте, хотите нет, насчитал аж 5 различных способов. Может, есть и больше, но всякие экзотические сценарии вроде пробраться в датацентр с паяльником я не рассматривал. Так вот, у каждого способа есть свои плюсы и минусы, и так как память уже не та, я решил их на всякий случай записать.

Способ первый: при помощи облачной веб-консоли.

Это самый очевидный и, наверное, самый часто используемый способ. У каждого уважающего себя облачного провайдера есть сайт, в название которого входит слово «консоль» (console.cloud.google.com, console.aws.amazon.com и т.д.). Это набор формочек с кнопочками, как правило, сомнительного дизайна (привет, Microsoft и Amazon), где через последовательность кликов и матюков можно создать практически всё что угодно.

Например, вот так создание виртуальной машины с сетью и правилом для файрвола выглядело бы в Google Cloud Console:

Создаём сеть
Правило для файрвола, разрешающее входящий SSH траффик
И виртуальная машина. В простонародье инстанс

Это хороший, простой способ, но, как и всё остальное в этом мире, идёт с комплектом плюсов и минусов.

Плюсы:

  1. Это, кажется, самый простой способ создавать объекты инфраструктуры. Консоль, как правило, старается предугадать, что мы создаём, и временами ей это удаётся. Ну а если сравнить, как мало нужно знать, чтобы создать балансировщик нагрузки в гугло-облаке через формочки, как много нужно помнить создавая его вручную, то консоль покажется вообще безусловным благом.
  2. С консолью проще всего экспериментировать. Допустим, я не помню, сможет ли сеть А общаться с сетью В через сеть Б, если АБ и БВ соединены между собой. А так, покликал несколько кнопок, создал тестовых виртуальных машинок, и вроде как всё становится ясно.

Минусы:

  1. Кликанье в консоль не масштабируется. Никак. Я могу создать одну виртуальную машинку. Может, пять. Но на десятой пальцы начнут заплетаться, а к сотне я, кажется, помру.
  2. Повторяемость. Ещё до того, как я помру, создавая сотую виртуальную машину руками, конфигурация машин начнёт отличаться. Где-то забыл, где-то по кнопке промазал, и вот он, непохожий друг на друга зоопарк машинок. Ну и в каждой девопс команде найдётся особой интеллектуальной одарённости организм, который тупо не может повторить данный ему набор инструкций, как бы внятно тот не объяснялся.

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

Способ второй. SDK и коммандная строка.

Ещё один инструмент, который раздают все уважающие себя облачные провайдеры, — утилита командной строки. gloud, aws, az и даже doctl. То есть вместо кликанья на кнопочки мы будем печатать в скриптик, но результат будет тем же — ресурсы, ресурсы и иногда баги. Создавать облачную инфраструктуру через командную строку всё еще просто, и даже гугл умудрился сделать свои команды вменяемо понятными.

Вот как создание сети, файрвола и виртуалки выглядит уже в Google SDK CLI:

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

Плюсы:

  1. CLI всё ещё проста как способ. Команды интуитивно понятны, просто какие-то вещи надо эпизодически догугливать.
  2. Командная строка уже слегка масштабируется. Инфраструктуру банка я бы из неё не разворачивал, но небольшой набор статичных ресурсов — почему бы и нет.
  3. Это повторяемый подход. Что одна виртуалка, что сто, магию copy-paste и bash скриптов никто не отменял.
  4. Это текстовые команды, а текст можно класть в git, а git — это благо. За возможность смотреть историю изменений инфраструктуры многие бы с радостью принесли в жертву отдел маркетинга.

Минусы:

  1. Масштабируемость подхода всё ещё ограничена. Десять идентичных виртуальных машин я, может, и создам, но десяток сетей, подсетей, файрволов, аккаунтов и прочих прелестей похоронит читаемость скрипта мгновенно.
  2. Набор команд в скрипте всё ещё не имеет прямой связи с набором ресурсов в облаке. Какие-то ресурсы могут быть уже созданы и их трогать не надо. Какие-то нужно всего-навсего перенастроить (добавить тэги). Но скрипту такие нюансы чужды.
  3. Даже написав нужные CLI команды для создания инфраструктуры, мы всё равно должны будем дописать команды для их удаления. Когда-нибудь.
  4. Иногда доступа к CLI тупо нет. Что если я хочу создавать ресурсы динамически, по запросу из какой-нибудь Cloud/Lambda функции? Файловая система в serverless — это немного моветон.

Но даже при всех этих минусах, выбирая между веб-консолью и CLI для проекта длительнее, чем один день, я всегда выберу CLI. Мне нравится текст, git, и возможность посмотреть, как же и зачем я создавал ту виртуальную машину месяц назад.

Способ третий: создание ресурсов через API

Глубоко под капотом CLI инструменты просто вызывают облачный REST API. А если это можно бездушному CLI, то почему бы не попробовать нам? К тому же, если нет доступа к файловой системе, или Azure SDK опять вышел забагованным, и опять нужно откатываться назад, но непонятно куда, и лучше бы я сразу начал с другого способа… В общем, почему бы не API? API никогда не врёт, всегда актуален, и его можно дёргать из любого приятного языка программирования. Сплошные достоинства.

Если бы я мог писать на Питоне, то создание VPC, VM и файрвола для гугла выглядели бы примерно вот так:

По количеству строк кода творение выглядит намного более упитанным, чем скрипт на SDK CLI. Но если убрать print и избыточные пустые строки, то кода станет раза в два меньше. Что круто, с минимальными модификациями этим кодом можно создать и десять, и сто виртуальных машин. Плюс, так как код написан на языке общего назначения, при помощи if‘ов, then‘ов, и прочих else'ов я могу писать очень чуткие к состоянию среды и задачам сценарии развёртывания.

Но как всегда на всякий плюс найдётся свой минус:

Плюсы:

  1. Доступ к файловой системе больше не нужен.
  2. Используя подходящий язык программирования при помощи API можно написать код под любой экзотический сценарий развёртывания.
  3. Git, масштабируемость и повторяемость — всё есть.

Минусы:

  1. Мощь языка программирования может стать и проклятием. Не знаю почему, но я никогда не видел читабельного кода, написанного для CI/CD и инфраструктурных проектов на императивном языке (эксперименты на функционально-декларативных пока не встречались). Есть что-то такое между облаками и императивным кодом, что тупо не стыкуется. А вот декларативные конфигурации, даже самые уродливые, всегда хотя бы терпимы.
  2. Создание ресурсов через API вызовы почему-то труднее, чем другими способами. Просто посмотрите ещё раз на код выше.
  3. Не все API созданы равными. Гугловые API, как правило, более или менее последовательны, тогда как Microsoft Azure API вызывал у меня много… противоречивых чувств.
  4. Несмотря на то, что API есть истина, даже они меняются. Не всегда в обратно совместимую сторону.

Тем не менее у такого способа есть своя ниша, поэтому спасибо, что живой. Особенно когда API + язык программирования — это тот базис, при помощи которого можно создать абсолютно всё что угодно.

Способ 4: Нативные средства развёртывания от облачного провайдера

Большинство крупных облачных провайдеров идут в комплекте со своими же средствами развёртывания. Это Cloud Deployment Manager для Google, ARM Templates для Azure и CloudFormation для AWS. Конфигурация оных по умолчанию идёт в декларативном стиле, что сильно спасает от императивного ада. Они поддерживают входные параметры, выходные данные, и даже возможность передавать последние на вход последующим скриптам, выстраивая таким образом иерархичные сценарии развёртывания. Что ещё здорово, нативные средства, как правило, рассматривают акт развёртывания как отдельный вид ресурса, так что его можно запросить, проверить статус, и даже удалить целиком. Ну и наконец ресурс-развёртывание иногда может сравнить уже созданную инфраструктуру с той, которую запросила конфигурация, и донастроить недостающие куски, вместо того, чтобы удалить всё и начать заново.

По традиции, вот как создание сети, файрвола и виртуалки будет выглядеть в Google’s Deployment Manager’овском YAML формате.

Круто ведь, правда? Но как и API, не все инструменты созданы равными. Из всего, что я пробовал, Гугловый DM зашёл лучше всего. Он в меру синхронизирован со своим же облаком, компактный, простой, и поддерживает некоторые фичи, которые рвут большинство конкурентов на тряпки: провайдеры типов и Python / Jinja шаблоны. Провайдеры типов позволяют подключать внешние REST API вместо недостающих типов ресурсов, а с шаблонами можно свести задачу к гибриду декларативного средства развёртывания и императивного языка, и отстрелить себе ногу одновременно с решением любой облачной задачи.

С другой стороны, есть Azure’s ARM Templates. Вроде бы Микрософт выкатили что-то новое пару лет назад — Blueprints или как там его, но на момент плотного взаимодействия с Azure основной штукой был ARM. Боже, как я его ненавидел. В далёкие средние века, когда мир, наконец, переехал с XML на более лаконичные языки для настроек типа JSON, Microsoft продолжал толкать XML как единственно верный путь во всевозможные склепы и мавзолеи (хотя XSLT мне очень нравился). Как только мир устал от JSON и переехал на ещё более лаконичный YAML или даже собственные DSL, MS наконец решили обновиться и возлюбили JSON. Возлюбили везде. Я помню, как первые версии .NET Core решили сменить XML .csproj файлы проектов на JSON. Это было так ущербно, что через пару же версий сами же Microsoft всё откатили назад.

Так вот, ARM шаблоны так и пишутся на JSON, и это просто убивает меня. Да, их можно написать и на YAML, но запах JSON и даже более древнего XML продолжает сквозить и дезодорировать пространство. Amazon’овский CloudFormation тоже пишется на JSON, но его хотя бы терпеть можно.

Ни разу в жизни мне не удалось написать ARM шаблон с первого раза. Ни разу. Даже простейшая задача вроде создать масштабируемое множество виртуальных машин со startup скриптом (virtual machine scale set — VMSS. В гугле такие вещи называют VM instance + autoscaler) могла растянуться на часы, потому что: то официальные примеры устарели, то из трёх допустимых конфигураций теперь разрешена только четвёртая, но для неё ещё нет доков, так что гадайте на кофейной гуще. Постоянные синтаксические ошибки, какое-то скрытое поведение, отсутствие сообщений о логических ошибках… В общем, никакого милосердия к человечеству. Всё можно было бы списать на кривые руки и мои ограниченные интеллектуальные способности, но на том же гугловом Deployment Manager я смог создать примеры для этого поста минут за десять, и это при том, что гугл я года два не трогал.

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

Плюсы:

  1. Размещение одного или множества ресурсов концептуально ничем больше не отличается.
  2. Конфигурации развёртывания — это текст, и, следовательно, он дружелюбен к git и вообще всячески копируем по местам.
  3. Конфигурации развёртывания можно скармливать CLI инструментам, API или даже веб-консоли.
  4. Как правило, созданные таким образом ресурсы можно обновлять и удалять при помощи той же самой конфигурации развёртывания.

Минусы:

  1. Некоторые облачные средства развёртывания — мучительный отстой, и ни причитания, ни человеческие жертвоприношения это не исправят.
  2. Даже хорошие средства развёртывания могут отставать по фичам от своего же облака. Например, Deployment Manager был долгое время уверен, что Google Cloud Functions существуют только в бете, одновременно с этим разрождаясь предупреждениями, что бетой пользоваться нельзя.
  3. Как правило, облачный провайдер поддерживает только свои ресурсы, так что если кому-то захотелось сделать гибридный AWS + Google сценарий — ну, удачи, чего уж там.
  4. Как правило, поддерживаются только облачные ресурсы. А ведь так часто хочется создать и гит репозиторий, и пользователей для него, да и всякие аккаунты и их группы. Облачный проект — это ведь не только машинки и сети.

Но если вам повезло с облаком и задачей, то нативный инструмент может быть прекрасен. Насколько я с содроганием вспоминаю Azure ARM Templates, настолько мне тепло зимой, вспоминая Google Cloud Deployment Manager. Но если вам всё-таки нужен мощный, непривязанный к конкретному облаку декларативный инструмент развёртывания — читайте дальше.

Способ намбер пять: Terraform

В моей прошлой жизни в качестве облачного консультанта мы начинали как апологеты нативных инструментов облачного развёртывания. Мол, гугл знает лучше, что в него развёртывают. Но уже через год-другой признали, что не всё так просто. Гугл, может, и знает, что в него развёртывают, но не всё поддерживает, и не всегда понимает, как именно его используют. А Terraform знает. Не знаю как, но они и все облака поддерживают, и рудиментарные структуры ветвления кода (if’ы, loop’ы), и декларативные вусмерть, и как-то чувствуют, что ещё может пригодиться в большом проекте. Плюс, его создала контора Hashicorp, которая наверняка продала душу дьяволу, ибо что у них не проект, то облачный шедевр — Vagrant, Consul, Vault, и т.д. У обычных людей так не бывает.

Плюс Terraform идёт с такой важной и неочевидной штукой как контроль за состоянием — данными о том, что и где сейчас должно быть (было) развёрнуто. Состояние можно класть в AWS S3, Google Cloud Storage, локальные файлы — куда угодно. На куски состояния (например, айдишки проектов и сетей) могут ссылаться другие сценарии развёртывания, поэтому множество репозиториев с командными / проектными кусками инфраструктуры могут жить изолированно, но ссылаться на общее понимание правды. Ну и в комплекте идут поддержка модулей и plugin SDK, чтобы дописывать поддержку пропущенных ресурсов.

Некоторые из проектов, которые мне попадались по работе, были настолько огромны, что их никто бы в жизни не пытался написать на том же Deployment Manager. Вот поэтому-то в какой-то момент мы начали предлагать Terraform как дефолтный инструмент для развёртывания инфраструктуры.

Вот как в TF выглядит наша многострадальная сеть и виртуальная машина:

Компактно ведь, да? Может, в строковом эквиваленте получилось чуть длиннее, чем в Google’s DM, но всё равно это намного короче, чем вызовы API методов напрямую, и намного надёжнее и масштабируемее, чем веб-консоль или командная строка.

Плюсы:

  1. Импорт уже существующих ресурсов, создание новых, обновление и удаление всего и вся.
  2. git, масштабируемость и повторяемость — всё осталось.
  3. Хранение состояния развёртывания во внешнем хранилище, что позволяет параллельным сценариям развёртывания сосуществовать в общей среде.
  4. Поддерживаются все основные облачные провайдеры + кастомные типы ресурсов (git репозитории, например).
  5. Всё, что не поддерживается, может быть написано на Go в качества плагина (я писал поддержку Azure Subscriptions дважды).

Но если напрячься, можно придумать и минусы:

  1. Я не уверен, что Terraform можно использовать без локальной файловой системы. Возможно, их платный Enterprise план позволяет такое колдунство, но в моих проектах мы всегда зависели от локального terraform.
  2. На самом деле не так много людей в мире знают, как писать большие проекты на Terraform. Это не совсем проблема TF как такового, но всё-таки в момент нужды непонятно куда (да и особо некуда) гуглить.
  3. Некоторые релизы Terraform слегка несовместимы со старыми релизами. Я смутно помню апгрэйд с 0.12 к 0.13, или что-то вроде этих чисел, и внезапно места хранения плагинов поменялись, и пришлось снова лезть в гугл спасаться.

Но сие есть мелочи, ибо Terraform остаётся моим дефолтным выбором для облака.

Мораль

Итак, в этом неожиданно длинном посте мы прошлись по аж пяти различным способам развёртывания инфраструктуры в облаке. Если бы у меня была возможность (а она есть) укоротить их до одного абзаца, то получилось бы что-нибудь вроде такого:

Используйте веб-консоль для исследования и экспериментов, SDK CLI для экспериментов побольше или для долгоживущих одиночных ресурсов, API для serverless окружения или создания короткоживущих ресурсов по запросу (например, создания пачки виртуальных машин для запуска тестов), нативные инструменты развёртывания для простых проектов и Terraform для всего остального. Всё, теперь вы всё знаете.

4 комментария к «5 способов развернуть инфраструктуру в облаке»

  1. >Я не уверен, что Terraform можно использовать без локальной файловой системы.
    Вообще, утверждают, что да, но я им не верю. 🙂

  2. >Я не уверен, что Terraform можно использовать без локальной файловой системы.

    Ответ можно.
    Я пользовался. И клиенты.
    До 5 чел команда бесплатно.
    https://www.terraform.io/cloud
    Там есть пару способов…
    Один из.
    Настраиваем tf-cloud слушать мой github или ваш любимый vcs.
    И всё. Инфра будет то так как вы написали. Даже tf state там можно в tf cloud хранить.

    1. Всё выполняется на их раннерах. Серверах итд.
      Можно настроить » авто approved..» и каждый комит в github. Будет обновить ваш аккаунт. Например добавить сервер или удалить.. итд.
      А может посылать письмо группе типа «вот такие изменения будут » изменить?? Принять или отказаться..
      Вы видите сразу результаты проверки и план.. !!!!
      Вообщем с телефона можно руками водить 😉

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

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