Пишите инфраструктуру как код, прежде чем снова кликнуть мышью

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

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

Есть способ лучше: пишите инфраструктуру как код.

Что на самом деле означает Infrastructure as Code

Infrastructure as Code (IaC) — это практика описания серверов, баз данных, сетей и других облачных ресурсов в текстовых файлах вместо кликов по интерфейсу. Эти файлы описывают желаемое состояние вашей инфраструктуры. Вы храните их в системе контроля версий, ревьювите как код приложения и применяете единообразно во всех окружениях.

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

Пишем первую конфигурацию

Terraform — один из самых популярных инструментов IaC. Вы пишете конфигурационные файлы с расширением .tf. Каждый файл описывает необходимые ресурсы и их связи.

Начните с файла main.tf. Первым делом определите провайдера. Провайдер — это плагин, который позволяет Terraform взаимодействовать с конкретной платформой: AWS, Google Cloud, Azure. Он указывает Terraform, где создавать ресурсы и какие учётные данные использовать.

provider "aws" {
  region = "ap-southeast-1"
}

После настройки провайдера определяйте ресурсы. Каждый ресурс следует шаблону: resource "тип" "локальное_имя". Локальное имя используется только внутри вашей конфигурации. Это не то имя, которое появится в консоли облачного провайдера.

Вот как создать виртуальный сервер, который AWS называет EC2-инстансом:

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

  tags = {
    Name = "app-server"
  }
}

А вот PostgreSQL-база данных через RDS:

resource "aws_db_instance" "app_database" {
  allocated_storage    = 20
  engine               = "postgres"
  engine_version       = "15"
  instance_class       = "db.t3.micro"
  db_name              = "myapp"
  username             = "admin"
  password             = var.db_password
  skip_final_snapshot  = true
}

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

Почему сначала это кажется сложнее

Написание конфигурационных файлов требует больше времени на старте, чем клики по панели управления. Нужно знать точные типы ресурсов, их обязательные аргументы и структуру файлов. Панель показывает выпадающие списки и флажки. Конфигурационный файл ожидает, что вы знаете, что означает ami-0c55b159cbfafe1f0 или что такое db.t3.micro.

Но эти начальные затраты окупаются в тот момент, когда нужно воспроизвести настройку. Нужно стейджинговое окружение, зеркалирующее продакшен? Скопируйте файлы, измените несколько значений и запустите ту же конфигурацию. Хотите понять, какая инфраструктура работает? Читайте файлы вместо поисков по консоли. Хотите проверить изменение до его применения? Откройте pull request и дайте команде обсудить diff.

Храните конфигурацию в системе контроля версий

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

Это даёт несколько преимуществ:

  • Каждое изменение инфраструктуры записано с указанием автора и причины.
  • Можно откатиться к предыдущему состоянию, если что-то пошло не так.
  • Новые члены команды видят полную инфраструктуру, читая репозиторий.
  • Автоматизированные проверки могут валидировать конфигурацию до того, как она попадёт в продакшен.

Чего вы не делаете

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

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

Практический рабочий процесс

Типичный рабочий процесс Terraform состоит из трёх фаз: write, plan, apply.

Сначала вы пишете или изменяете .tf-файлы. Здесь вы определяете желаемую инфраструктуру.

Затем запускаете terraform plan. Эта команда показывает, что Terraform собирается сделать, не выполняя действий. Она выводит подробный diff: какие ресурсы будут созданы, какие изменены, какие уничтожены. Вы изучаете этот план перед тем, как продолжить.

Наконец, вы запускаете terraform apply, чтобы выполнить план. Terraform делает API-вызовы к вашему облачному провайдеру для создания, обновления или удаления ресурсов, пока фактическое состояние не совпадёт с конфигурацией.

Краткий чек-лист для первого IaC-проекта

  • Выберите облачного провайдера и установите Terraform CLI.
  • Создайте файл main.tf с блоком провайдера.
  • Определите хотя бы один ресурс, например виртуальную машину или базу данных.
  • Запустите terraform init, чтобы загрузить плагин провайдера.
  • Запустите terraform plan, чтобы увидеть, что будет создано.
  • Запустите terraform apply, чтобы создать ресурсы.
  • Сохраните все .tf-файлы в Git-репозиторий и запушьте их.

Настоящая ценность проявляется позже

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

Начните с одного ресурса. Опишите его в файле. Положите в Git. Затем добавьте следующий ресурс. Привычка формируется быстрее, чем вы ожидаете, а уверенность, которую она даёт, стоит начальных усилий.