Откуда берется инфраструктура

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

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

Проблема не только во времени. Когда инфраструктура создается вручную, не остается надежной записи о том, что именно было построено. Разработчик А может создать сервер с одними параметрами, а разработчик Б — другой сервер с чуть другими настройками: возможно, из-за забывчивости, возможно, потому что интерфейс облачной консоли изменился. Эти мелкие различия приводят к трудноотлавливаемым багам: приложение отлично работает на стейджинге, но падает в продуктиве, хотя код идентичен.

Ручную инфраструктуру также сложно воспроизвести. Если команде нужно новое окружение — скажем, для QA-тестирования или демо клиенту — весь процесс приходится повторять с нуля. Каждый раз есть риск пропустить шаг или неправильно настроить параметр. Чем больше разрастается инфраструктура, тем шире становится разрыв между тем, что вы задумали, и тем, что в итоге создано.

Инфраструктура как код

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

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

Вот как выглядит простое описание инфраструктуры на Terraform:

resource "aws_instance" "app_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  tags = {
    Name = "ExampleAppServer"
  }
}

Эта концепция называется инфраструктура как код, или IaC. Идея проста: инфраструктура — это не то, что вы настраиваете один раз и забываете. Это то, что вы определяете, версионируете и управляете на протяжении всего жизненного цикла приложения. Так вы можете быть уверены, что staging и production окружения идентичны, каждое изменение отслеживается, а новые окружения можно развернуть в любой момент, не беспокоясь о пропущенных шагах.

Почему ручное управление не работает в масштабе

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

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

Настоящая цена — не время, потраченное на клики. Это неопределенность. Когда в продуктиве что-то идет не так, вы не можете быстро ответить на вопросы: "Что изменилось в инфраструктуре?" или "Это окружение настроено точно так же, как стейджинг?". Без инфраструктуры как кода на такие вопросы трудно ответить с уверенностью.

С чего начинается рабочий процесс Terraform

Именно здесь начинается рабочий процесс Terraform. Прежде чем запускать какие-либо команды, команда пишет описания инфраструктуры в конфигурационных файлах. Эти файлы становятся источником истины — не облачная консоль, не личные заметки и не чья-то память.

Рабочий процесс состоит из простого цикла:

  1. Write — Опишите инфраструктуру в конфигурационных файлах. Укажите серверы, сети, базы данных и другие необходимые ресурсы.

  2. Plan — Попросите Terraform показать, что изменится до применения изменений. Это дает возможность проверить и заметить ошибки.

  3. Apply — Примените изменения. Terraform сравнивает вашу конфигурацию с текущим состоянием инфраструктуры и вносит только те изменения, которые нужны для достижения желаемого состояния.

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

Что меняет инфраструктура как код

Когда вы внедряете инфраструктуру как код, в работе команды меняется несколько вещей:

Аудируемость становится автоматической. Каждое изменение инфраструктуры фиксируется в истории системы контроля версий. Вы можете увидеть, кто, что и когда изменил и зачем. Если возникает проблема в продуктиве, можно проверить, совпали ли изменения инфраструктуры с моментом возникновения проблемы.

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

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

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

Практическая отправная точка

Если вы новичок в инфраструктуре как коде, вот простой чек-лист для начала:

  • Выберите один небольшой элемент инфраструктуры, которым вы сейчас управляете вручную — например, один сервер или экземпляр базы данных.
  • Опишите его конфигурацию на Terraform или в вашем любимом IaC-инструменте.
  • Запустите plan, чтобы увидеть, что Terraform собирается изменить.
  • Примените конфигурацию и убедитесь, что результат совпадает с ожиданиями.
  • Зафиксируйте конфигурационные файлы в репозитории.
  • Удалите ручной ресурс и воссоздайте его, используя только конфигурационные файлы.

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

Вывод

Инфраструктура не появляется по волшебству, и управлять ей по памяти — плохая идея. Описание инфраструктуры как код превращает подверженный ошибкам ручной процесс в повторяемый, проверяемый и аудируемый рабочий процесс. Рабочий процесс Terraform — write, plan, apply — это просто практическая реализация этой идеи. Прежде чем запускать какую-либо команду, начните с определения того, что вы хотите. Это определение, хранящееся в системе контроля версий, становится единым источником истины для вашей инфраструктуры. Всё остальное следует из этого.