
Идея управления серверной инфраструктурой через код (Infrastructure as Code, IoC) не нова. Управление настройками через скрипты или файлы конфигурации позволяет стандартизировать настройку системы, масштабировать решение, снизить ошибки и исключить “человеческий фактор”. Shell-скрипты или их прототипы существовали с момента создания компьютеров, а с появлением виртуальных машин стало возможно заскриптовать настройку сервера с нуля. Однако сегодня я хочу сконцентрироваться на кодировании именно облачной инфраструктуры. Это интересно, потому что облака вывели фреймворки по управлению инфраструктурой на принципиально новый уровень.
Связано это, в первую очередь, с подходом по предоставлению облаком конечному пользователю единого API с помощью которого можно управлять любым ресурсом или сервисом в нем. Таким образом у пользователя появились возможность создания подобных фреймворков. Последующий же рост и популяризация самих облаков создали спрос и на системы управления ими, что стимулировало большой сегмент IT индустрии инвестировать в это направление.
Сегодня лидеры индустрии предоставляют 200+ сервисов которые работают на разных уровнях абстракции (IaaS, PaaS, SaaS), но все так же позволяют управлять всем через единый API. В данной статье я рассмотрю историю развития фреймворков для управления облачной инфраструктурой, выделив ключевые этапы и события, которые, по моему мнению, повлияли на их эволюцию.
Поскольку система управления облаком зачастую нераздельно связана с самим облаком и меня интересуют первопроходцы, я часто буду делать отсылку к AWS.
Эпоха CLI
Отсчет появления облаков, а также инструментов их кодирования логично вести с 2006 года с публичного релиза AWS SQS, S2, EC2.
В качестве инструмента управления на тот момент была доступна командная строка (CLI) и пакет для программирования (SDK). Управление через CLI/SDK тут же открыло возможности заскриптовать свои действия и сильно снизить количество рутинных операций, а также позволило создать библиотеки действий, делиться с коллегами и даже хранить в системе контроля версий. К сожалению, все это быстро превращалось в запутанное спагетти. Большое количество параметров и множество вариаций исходных условий приводило к тому, что то, что хорошо работало для демо примеров, было плохо применимо для решения реальных задач. Одним из важных факторов приводящих к этому была императивность работы с CLI/SDK. Например в псевдо коде можно сказать:
создай мне EC2 сервер размера Large
назови его ABC
Казалось бы все просто, но если вызвать эту команду 10 раз - получится 10 серверов с одинаковыми именами, за каждый придется платить и непонятно, какой из них надо удалять. В данном случае полагаться на имя сервера нельзя. Оно не должно быть уникально и создание будет работать пока не упрется в квоту. Также, если кто-то внесет изменения вручную, то синхронизировать состояние обратно не удасться. Для правильной идентификации надо хранить id созданной сущности, чтобы можно было обратиться к ней, а также атрибуты с ней связанные.
Хотя CLI/SDK являются основой, на которой базируются будущие поколения, использование их в чистом виде довольно ограничено и наиболее эффективно при выполнении разовых операций, не создающих постоянные сущности или инкрементальных действий.
Эпоха CloudFormation
Следующей большой вехой стало появление AWS CloudFormation в 2011 году. Это был первый серьезный подход к решению проблем идемпотентности и хранения состояния. Поскольку CloudFormation проприетарный инструмент, он получил отличную интеграцию и легкость использования в рамках AWS, но по тем же причинам не мог быть использован для других облаков. Инструмент получил декларативную нотацию и теперь, например, стало можно сказать:
должен быть один EC2 север размера Large
он должен быть назван ABC
CloudFormation создаст внутреннюю сущность - стек, к которому будут привязаны все созданные в результате него сущности. Таким образом, сколько бы раз мы не выполняли один и тот же стек, у нас всегда бу��ет 1 сервер. Если же мы захотим 2-й - мы можем создать 2-й стек из той же конфигурации. Важно, что стек обеспечивает синхронизацию и даже если кто-то руками изменит настройки - выполнение CloudFormation приведет все в норму.
Решение одних проблем привело к другим - CloudFormation не предлагал специального языка для описания, а использовал JSON с расширенным синтаксисом. В результате, хотя была возможность установить базовую связь между объектами, гибкость и читаемость, присущая инструментам CLI/SDK, значительно утрачивалась. Даже внедрение базовых функций приводило к низкой читаемости кода, и можно только посочувствовать инженерам, которые вынуждены были отлаживать такие решения. Проблемой также становится и формирование библиотек, наследование, которое было полностью открыто ранее.
С ростом возникает новая задача - необходимость обеспечить еще более значительный рост и взаимосвязь между стеками, чтобы они могли ссылаться на ресурсы друг друга. Однако при увеличении масштабов становятся заметными медленная скорость выполнения и недостаточная прозрачность процессов, связанных с отладкой и пониманием того, над чем система фактически работает (debuggability).
Со временем CloudFormation перешел к использованию YAML, улучшил синтаксис, внедрил множество новых функций и стал фундаментом для следующих поколений платформы.
Эпоха Terraform
Эта эра для меня самая любимая, поскольку именно в этот момент я начал заниматься облаками.
В 2014 вышел Hashicorp Terraform. Этот инструмент, исправил множество недостатков, сохранив достоинства CloudFormation. Од��им из ключевых изменений было удаление проприетарной составляющей, что позволило использовать инструмент для управления любым популярным облачным провайдером, сервисом или даже добавить собственную интеграцию в случае необходимости, поскольку он является open source.
Основой описания в Terraform стал собственный язык HCL (HashiCorp Configuration Language), который позволил создавать читабельный код, интегрировать встроенные функции и ссылаться на ресурсы без лишних проблем. Кроме того, Terraform работал с целыми папками, а не с отдельными файлами, что позволило разделить код на логические блоки и избежать создания огромных файлов с тысячами строк. Очень быстро была добавлена поддержка модулей и библиотек, а детализация планирования операций и логирование процесса выполнения были действительно на высоте. Отмечу также, что Terraform сразу использовал графовый движок и параллельно обрабатывал ресурсы, что значительно повышало его производительность по сравнению с CloudFormation того поколения.
Одной из основных проблем, связанных с "не проприетарностью", являлось управление состоянием и блокировками во время выполнения (когда несколько людей одновременно работают с одной и той же конфигурацией). Хотя эта проблема была оперативно решена с использованием ресурсов облачной инфраструктуры, она не стала настолько органично интегрированной, как в случае с CloudFormation. Кроме того, это добавляет ограничения при использовании вне облака, например только настроить PostgreSQL.
Далее возникали следующие сложности связанные с еще большим масштабированием:
Недостаток гибкости: требование большего количества функций, более удобного синтаксиса и поддержки циклов (для Terraform dсе это было реализовано с выходом HCL 2).
Потребность связывать между собой разные модули конфигурации и облачных провайдеров. То есть дать возможность настраивать multi cloud и писать инфраструктурный код с разбивкой по слоям
Высокий порог входа для разработчиков. Необходимо было изучить новый язык программирования, разобраться в устройстве облака, инфраструктурных компонентов и т.д.
Эпоха стабилизации
Здесь возникают 2 направления как вызовы уже имеющимся сложностям.
В конце 2015 года появилась первая версия Serverless фреймворка, которая была разработана с целью максимального упрощения жизни обычного разработчика. Он убрал детали и предоставил opinionated версию развертывания инфраструктуры. Это существенно упростило процесс написания небольших микросервисов. Serverless работал поверх AWS CloudFormation, поэтому движок выполнения был наиболее нативным, но сохранял все проблемы, о которых было упомянуто ранее. В случае, если простыми средствами не удавалось настроить конфигурацию, можно было обратиться к оригинальному CloudFormation и настроить через его. При дальнейшем усложнении системы, на каком-то этапе версия Serverless по сложности не сильно могла отличаться от чистого CloudFormation.
В 2016 вышел оркестратор над Terraform’ом - Terragrunt (уверен, были еще аналоги), цель которого повысить переиспользование кода, упростить поддержку больших конфигураций. С помощью него м��жно было еще раз шаблонизировать и параметризовать конфигурацию под разные окружения и больше переиспользовать имеющийся код (т.е. следовать принципу DRY), а также запускать выполнение сразу нескольких конфигураций.
Перечисленные инструменты существенно отличались своей целевой аудиторией. Serverless, в основном, нацелен на разработчиков бессерверных микросервисов на основе AWS Lambda, в то время как Terragrunt предназначен для DevOps-инженеров, работающих с большими конфигурациями. Однако, оба инструмента основаны на фундаменте уже существующих инструментов предыдущего поколения, что говорит о том, что эти исходные инструменты приобрели популярность и распространение, и у них есть четкая цель для дальнейшего развития.
Одним из главных вызовов в этот период стало стремление популяризировать эти инструменты и привлечь широкий круг инженеров, а также стирание границ между разработчиками и DevOps-инженерами.
Эпоха CDK
Я считаю, что следующую эпоху открыл выпуск AWS CDK (Cloud Development Kit) в 2019 году. Хотя на протяжении этого периода появилось множество новых инструментов, именно CDK совершил еще одну революцию, отвечая на потребности предыдущего периода - привлечение большего числа инженеров и разработчиков к написанию инфраструктурного кода. Он позволил описывать инфраструктуру с использованием знакомых программистам языковых конструкций, а затем преобразовывать результат в стек CloudFormation.
Таким образом, стало возможным избежать изучения нового синтаксиса и использовать всю мощь встроенных в язык функций, логических выражений и циклов. Хотя не все языки были сразу поддержаны, это был только вопрос времени. Теперь "Инфраструктура как Код" стала неотъемлемой частью процесса программирования, а не отдельной специализацией.
Были у AWS CDK и неоднозначные моменты. Во-первых, он работал поверх CloudFormation. Это означало, что он генерировал конфигурацию CloudFormation из кода и на этом его возможности заканчивались. Таким образом CDK сводился к красивой обертке над CloudFormation, а о его проблемах упоминалось выше. Во-вторых, мне, как человеку, который глубоко изучил синтаксис Terraform/HCL, Serverless и CloudFormation, показалось, что переход на обычный язык программирования, хоть и знакомый, скорее усложнял описание, чем помогал. Я считаю, что основной проблемой было необычное использование императивного языка в декларативном формате, в то время как специально разработанный язык HCL гораздо лучше подходил для таких операций. Однако, после наблюдения за реакцией разработчиков, которые ранее не работали с инфраструктурой, я понял, что для них AWS CDK гораздо более понятен, чем Terraform. Они быстро осваивались с использованием привычного языка программирования и легко создавали инфраструктурные ресурсы. Это доказало, что AWS CDK открывает двери для широкого круга разработчиков и делает процесс разработки инфраструктуры более доступным и интуитивным.
Спустя 3 года, в 2022 году Hashicorp пошел по тем же стопам и выпустил CDK для Terraform (CDKTF), что позволило разрабатывать инфраструктуру на привычном языке программирования, с дальнейшим преобразованием в Terraform, а не в CloudFormation. Такой подход предоставил разработчикам возможность использовать знакомый синтаксис и инструменты, но с преимуществами, которые предлагал Terraform для управления инфраструктурой.
В 2019 году также был выпущен open source продукт Pulumi, который, по моему мнению, является следующим этапом эволюции. Как и AWS CDK, он позволял описывать инфраструктуру на привычном императивном языке программирования, но не делал промежуточной трансформации в Terraform или CloudFormation. Это был свежий проект, не связанный с предыдущими итерациями. Кроме того, поскольку Pulumi являлся open source, он не был привязан к конкретному облаку, что добавляло гибкости и свободы в выборе платформы.
Эпоха AI
В 2023 году, все участники продолжают усиливать свой функционал и искать способы повысить эффективность разработки: писать код быстрее, выполнять отладку быстрее и понижать порог вхождения. Появляются и новые более экзотические подходы к описанию инфраструктуры. Например, продукт под названием IaSQL (Infrastructure as SQL) предлагает описывать всю инфраструктуру с помощью SQL запросов (на данный момент только для AWS). Лично я не являюсь фанатом SQL и даже не рассматривал такой подход, однако уверен найдется множество разработчиков, особенно DB-инженеров, которым это придется по душе. Кроме того, вопрос хранения состояния окружения в IaSQL надежно решен, так как основой этого продукта является Postgres, который его хранит.
Другое активное направление по ускорению разработки пришло из общего сектора - ChatGPT может помочь и здесь. Сейчас он в состоянии справляться с несложными конфигурациями Terraform некоторых провайдеров, а Pulumi уже выпустили AI модуль, который получил очень позитивные отзывы. Под капотом все тот же ChatGPT. Наиболее важная особенность бота здесь это возможность отредактировать изначально предложенную конфигурацию, что он и делает вполне грамотно.
Однако все же остается вопрос знаний автора: для редактирования необходимо иметь представление о том, что нужно изменить. То есть, требуются знания облачных технологий, при этом существенно снижается необходимость в знании конкретного инструмента. Больше нет необходимости заниматься рутинным написанием кода.
Заключение
Облачные платформы и инструменты автоматизации прошли несколько поколений, которые значительно ускорили процесс разработки и упростили его доступность. Однако, что остается неизменным и продолжает расти, так это сложность самих облачных систем. Еще ни один AI не предложил, как аккуратно вставить сгенерированную конфигурацию в имеющийся дизайн продакшн кодовой базы. Или как в этой кодовой базе настроить обратную связь для того, чтобы AI мог ее успешно оптимизировать. Таким образом текущие фичи по кодогенерации и AI перешли бы из категории начально уровня (снижение порога входа в программирование инфраструктуры) в профессиональную и стали бы настоящим подспорьем опытным инженерам.
Возможно, разработчики со временем и станут операторами ChatGPT, но вопрос о том, насколько результат будет оптимален, остается открытым. Освободившись от рутины, мы можем уделить больше времени изучению облачных платформ. Однако, будем ли мы стремиться к достижению оптимального результата или будем довольствоваться имеющимся кодогенератором и продолжать накапливать технический долг из-за необходимости действовать быстро или просто из-за лени? Ответ на этот вопрос зависит от ситуации, но ответить на него предстоит каждому конкретному инженеру.
