Перешел с Terraform на CloudFormation — и пожалел

Представлять инфраструктуру в виде кода в повторяемом текстовом формате — простая лучшая практика для систем, с которой не нужно мышевозить. За этой практикой закрепилось название — Infrastructure as Code, и пока что для ее осуществления, особенно в AWS, есть два популярных инструмента: Terraform и CloudFormation.

Перешел с Terraform на CloudFormation — и пожалел
Сравниваю опыт работы с Terraform и CloudFormation

До прихода в Twitch (он же Amazon Jr.) я трудился в одном стартапе и года три использовал Terraform. На новом месте я тоже вовсю использовал Terraform, а потом компания продавила переход на все а-ля Amazon, включая CloudFormation. Я усердно разрабатывал лучшие практики и для того, и для другого, и оба инструмента использовал в очень сложных рабочих процессах в масштабах организации. Позднее, вдумчиво взвесив последствия перехода с Terraform на CloudFormation, я убедился, что Terraform, наверное, — лучший выбор для организации.

Terraform Ужасный

Бета-версия ПО

У Terraform еще даже не вышла версия 1.0, и это — веская причина им не пользоваться. С тех пор, как я сам его впервые опробовал, он сильно изменился, но тогда еще terraform apply часто ломался после нескольких обновлений или просто через пару лет эксплуатации. Я бы сказал, что «сейчас-то все по-другому», но… так вроде все говорят, нет? Есть изменения, несовместимые с предыдущими версиями, хотя они уместны, и даже чувство такое, что синтаксис и абстракции хранилищ ресурсов теперь что надо. Инструмент как будто правда стал лучше, но… :-0

С другой стороны, AWS хорошо постаралась, поддерживая совместимость с предыдущими версиями. Все, наверное, потому, что их сервисы часто хорошенько тестируют внутри организации и лишь потом, переименовав, публикуют. Так что «хорошо постарались» это еще слабо сказано. Поддерживать совместимость с предыдущими версиями API для такой многовариантной и сложной системы, как AWS, невероятно тяжело. Любой, кому приходилось поддерживать общедоступные API, используемые так же широко, должен понимать, как трудно это делать на протяжении стольких лет. А вот поведение CloudFormation на моей памяти ни разу с годами не изменилось.

Знакомься, нога… это пуля

Насколько я знаю, удалить ресурс постороннего стека CloudFormation из своего стека CF невозможно. Примерно так же дело обстоит и с Terraform. Он позволяет импортировать существующие ресурсы в свой стек. Функция, можно сказать, потрясающая, но с большой силой приходит и большая ответственность. Стоит только занести ресурс в стек и, пока ты работаешь со своим стеком, удалить или изменить этот ресурс нельзя. Однажды это аукнулось. Как-то на сайте Twitch кто-то, не замышляя ничего дурного, случайно импортировал чью-то группу безопасности AWS в свой собственный стек Terraform. Ввел несколько команд и… группа безопасности (вместе со входящим трафиком) исчезла.

Terraform Великий

Восстановление из неполных состояний

Иногда CloudFormation не может полностью перейти из одного состояния в другое. При этом он постарается вернуться к предыдущему. Жаль, это не всегда осуществимо. Отлаживать потом то, что получилось, бывает страшноватенько — никогда не знаешь, обрадуется ли CloudFormation, что его взламывают — пусть и для починки. А получится или нет вернуться к предыдущему состоянию, он толком определять не умеет и по умолчанию часами висит в ожидании чуда.

Terraform же, напротив, склонен восстанавливаться после неудачных переходов куда изящнее и предлагает расширенный отладочный инструментарий.

Более ясные изменения в состояния документа

«Ладно, балансировщик нагрузки, ты меняешься. Но как?»

—обеспокоенный инженер, готовый нажать кнопку «принять».

Иногда мне нужно проделать кое-какие манипуляции с балансировщиком нагрузки в стеке CloudFormation — например, добавить номер порта или изменить группу безопасности. ClouFormation изменения отображает слабо. Я же, как на иголках, раз по десять перепроверяю файл yaml, чтобы убедиться, что ничего нужного не стер, а лишнего — не добавил.

Terraform в этом плане куда прозрачнее. Порой он даже слишком прозрачен (читай: достает). К счастью, в последнюю версию включили улучшенное отображение изменений — теперь точно видно, что изменяется.

Гибкость

Пишите ПО от обратного.

Говоря прямо, самая важная отличительная черта долгоживущего ПО — это способность адаптироваться к изменениям. Любое ПО пишите от обратного. Я вот чаще всего прокалывался на том, что брал «простенький» сервис, а потом принимался впихивать все в единый стек CloudFormation или Terraform. И конечно же, спустя месяцы вскрывалось, что я все понял не так, и сервис-то на самом деле не простой! И вот мне нужно неким образом разбить большой стек на малые составляющие. Когда работаешь с CloudFormation, сделать это возможно, только предварительно воссоздав существующий стек, а этого я, со своими БД, не делаю. Terraform же позволял препарировать стек и расчленить его на более понятные меньшие части.

Модули в git

Делиться кодом Terraform между многочисленными стеками гораздо проще, чем кодом CloudFormation. С Terraform можно поместить код в репозиторий git и обращаться к нему, используя семантический контроль версий. Любой, у кого есть доступ в этот репозиторий, может заново использовать общий код. Эквивалент от CloudFormation — S3, но у него нет тех же преимуществ, и нет ни одной причины, по которой нам вообще стоит отказаться от git в пользу S3.

Организация росла и способность делиться общими стеками достигла критического уровня. С Terraform все это получается легко и естественно, тогда как CloudFormation заставит вас попрыгать через кольца, прежде чем у вас заработает нечто подобное.

Operations as code

«Заскриптуем и ладно».

—инженер за 3 года до того, как изобрести велосипед Terraform.

Когда речь о разработке ПО, то Go или программа на Java — это не просто код.

Перешел с Terraform на CloudFormation — и пожалел
Code as Code

Есть ведь еще инфраструктура, на которой она работает.

Перешел с Terraform на CloudFormation — и пожалел
Infrastructure as Code

Но откуда она там? Как ее мониторить? Где обитает ваш код? Нужно ли разработчикам разрешение на доступ?

Перешел с Terraform на CloudFormation — и пожалел
Operations as Code

Быть разработчиком ПО — это вам не просто код писать.

Не AWS единым: вы наверняка пользуетесь услугами других поставщиков. SignalFx, PagerDuty или Github. Может быть, у вас есть внутренний сервер Jenkins для CI/CD или внутренняя панель управления Grafana для мониторинга. Infra as Code выбирают по разным причинам, и любая одинаково важна для всего, связанного с ПО.

Когда я работал в Twitch, мы ускоряли сервисы внутри смешанных встроенных систем и систем AWS Amazon’а. Мы штамповали и поддерживали множество микросервисов, увеличивая эксплуатационные издержки. Обсуждения проходили примерно в таком ключе:

  • Я: Блин, многовато телодвижений для разгона одного микросервиса. Мне вот эту фигню придется использовать, чтобы создать AWS аккаунт (мы шли к 2 аккаунтам на микросервис), потом эту — для настройки оповещений, еще эту — для репозитория кода, и эту — для списка адресов электронной почты, ну и вот эту…
  • Лид: Заскриптуем и ладно.
  • Я: Лады, но сам скрипт изменится. Нужен будет способ, как проверить, что все эти встроенные штуковины amazon’а имеют актуальное состояние.
  • Лид: Звучит неплохо. И для это скрипт напишем.
  • Я: Отлично! А скрипту наверняка еще надо будет задать параметры. Примет он их?
  • Лид: Да примет, куда денется!
  • Я: Процесс может измениться, потеряется обратная совместимость. Потребуется какой-нибудь семантически контроль версий.
  • Лид: Отличная идея!
  • Я: Инструменты можно изменить вручную, внутри пользовательского интерфейса. Нам потребуется способ, как это проверять и исправлять.

…3 года спустя:

  • Лид: И получился у нас terraform.

Мораль басни такова: даже если вы по уши во всем amazon’овском, вы все равно пользуетесь чем-нибудь не от AWS, и у этих сервисов есть состояние, которое использует язык для конфигурации, чтобы это состояние синхронизировать.

CloudFormation lambda vs git-модули terraform

lambda — это решение CloudFormation для вопроса пользовательской логики. С помощью lambda можно создавать макросы или пользовательский ресурс. Такой подход представляет дополнительные сложности, которых нет в семантическом контроле версий модулей git у Terraform. Для меня самой насущной проблемой стало управление разрешениями для всех этих пользовательских lambda (а это десятки аккаунтов AWS). Другой по важности стала проблема типа «что было раньше — курица или яйцо?»: она была связана с кодом lambda. Сама эта функция — инфраструктура и код, и она сама нуждается в мониторинге и обновлениях. Последним гвоздем в гроб стала трудность в семантическом обновлении изменений кода lambda; еще нужно было сделать так, чтобы действия стека без прямой команды не менялись между запусками.

Помню, как-то захотелось мне создать канареечный деплой для среды Elastic Beanstalk с классическим балансировщиком нагрузки. Проще всего было бы сделать второе развертывание для EB рядом с производственной средой, сделав еще шаг: объединив автоматически масштабируемую группу канареечного деплоя с LB развертывания в производственную среду. А раз Terraform использует ASG beantalk как вывод, это потребует 4 лишние строки кода в Terraform. Когда я поинтересовался, нет ли сопоставимого решения в CloudFormation, мне указали на целый репозиторий в git с конвейером развертывания и прочим: и все это — ради того, что могли бы сделать несчастные 4 строчки кода Terraform.

Он лучше обнаруживает дрейф

Убедитесь, что реальность соответствует ожиданиям.

Обнаружение дрейфа — очень мощная функция operations as code, потому что помогает убедиться, что реальность соответствует ожиданиям. Она доступна и с CloudFormation и с Terraform. Но по мере роста рабочего стека поиск дрейфа в CloudFormation выдавал все больше ложных обнаружений.

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

CDK и будущее CloudFormation

CloudFormation трудно управлять в крупных, межинфраструктурных масштабах. Многие из этих трудностей признаны, и инструменту нужны такие вещи как aws-cdk, структура для определения облачной инфраструктуры в коде и проведения ее через AWS CloudFormation. Будет любопытно взглянуть, что ждет aws-cdk в будущем, но ему трудно будет состязаться с другими преимуществами Terraform; чтобы подтянуть CloudFormation, потребуются глобальные изменения.

Чтобы Terraform не разочаровал

Это же «инфраструктура как КОД», а не «как текст».

Первое впечатление от Terraform у меня сложилось довольно дурное. Думаю, я просто не понял подхода. Почти все инженеры по первой невольно воспринимают его как текстовый формат, который надо преобразовать в желаемую инфраструктуру. НЕ НАДО ТАК.

Прописные истины хорошей разработки ПО относятся и к Terraform

Я видел, как многие практики, принятые для создания хорошего кода, игнорируются в Terraform. Вы годами учились, чтобы стать хорошим программистом. Не отказывайтесь от этого опыта просто потому, что работаете с Terraform. Прописные истины хорошей разработки ПО относятся и к Terraform.

Как уж код и не задокументировать?

Мне попадались огромные стеки Terraform совершенно без документации. Как можно писать код страницами — совершенно без документации? Добавляйте документацию, в которой объясняется ваш код Terraform (ударение здесь на слово «код»), почему этот раздел так важен, и что вы делаете.

Как можно разворачивать сервисы, которые некогда были одной большой функцией main()?

Мне встречались очень сложные стеки Terraform, представленные в виде единого модуля. Почему мы так не разворачиваем ПО? Зачем дробим крупные функции на более мелкие? Те же ответы справедливы и для Terraform. Если модуль у вас слишком велик — надо его разбить на модули поменьше.

Разве ваша компания не пользуется библиотеками?

Я видел, как инженеры, раскручивая новый проект при помощи Terraform, тупо копи-пейстили громадные куски из других проектов в свои собственные, а потом ковыряли их, пока не начинало работать. Вот вы у себя в компании стали бы работать так с «боевым» кодом? Мы же не просто так пользуемся библиотеками. Да, не все должно быть библиотекой, но куда мы без общих библиотек в принципе?!

Разве вы не пользуетесь PEP8 или gofmt?

В большинстве языков есть стандартная принятая схема форматирования. В Python это PEP8. В Go — gofmt. У Terraform есть свой: terraform fmt. Пользуйтесь на здоровье!

Вы станете пользоваться React, не зная JavaScript?

Модули Terraform могут упростить какую-то часть создаваемой вами сложной инфраструктуры, но это еще не значит, что можно можно в ней вообще не шарить. Хотите правильно использовать Terraform без понимания ресурсов? Вы обречены: время будет идти, а вы так и не освоите Terraform.

Вы кодите синглтонами, или внедряя зависимости?

Внедрение зависимостей — признанная лучшая практика для разработки ПО, которую предпочитают синглтонам. Как это пригодится в Terraform? Мне встречались модули Terraform, зависящие от удаленного состояния. Вместо того, чтобы писать модули, извлекающие из удаленного состояния, напишите модуль, который принимает параметры. А потом передайте эти параметры в модуль.

Ваши библиотеки делают десять вещей хорошо или одну — отлично?

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

Как вы производите изменения в библиотеках без обратной совместимости?

Общему модулю Terraform, как и обычной библиотеке, нужно как-то сообщать пользователям об изменениях без обратной совместимости. Когда происходят такие изменения в библиотеках, это раздражает, и точно так же раздражает, когда изменения без обратной совместимости производятся в модулях Terraform. Рекомендуется применять git tags и semver при использовании модулей Terraform.

Производственный сервис запущен у вас на ноутбуке или в датацентре?

У Hashicorp есть инструменты вроде terraform cloud для запуска вашего terraform. Эти централизованные сервисы облегчают управление, аудит и одобрение изменений terraform.

Разве вы не пишете тесты?

Инженеры признают, что код нужно тестировать, но сами при этом часто забивают на проверки, работая с Terraform. Для инфраструктуры это чревато коварными моментами. Я советую «тестировать» или «создавать примеры» стеков с использованием модулей, которые можно корректно задеплоить для проверки во время CI/CD.

Terraform и микросервисы

Жизнь и смерть микросервисных компаний зависит от скорости, обновления и разрушения новых микросервисных рабочих стеков.

Самый распространенный негативный момент, связанный с микросервисными архитектурами и от которого никак не избавятся, связан с работой, а не с кодом. Если воспринимать Terraform, лишь как способ автоматизировать только инфраструктурную сторону микросервисной архитектуры, то вы лишаете себя подлинных преимуществ этой системы. Сейчас уже все — как код.

Источник: habr.com

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