Инфраструктура как код: почему конфигурация серверов должна быть в Git
Вы собираетесь выкатить новую функцию. Код приложения готов, тесты проходят, пул-реквест одобрен. Но тут кто-то спрашивает: «Мы обновили конфиг балансировщика для нового эндпоинта?» Никто не уверен. Тот, кто вносил последние изменения в балансировщик, в отпуске. В облачной панели видна текущая конфигурация, но никто не знает, что менялось на прошлой неделе и зачем.
Такая ситуация повторяется в командах каждый день. Изменения инфраструктуры зависят от «племенных знаний», ручных шагов и доступности конкретных людей. Если этого человека нет — изменение откладывается. Если он забыл шаг — сервер ломается молча. А когда что-то идёт не так, поиск первопричины превращается в раскопки чатов, писем и воспоминаний.
Есть способ лучше. Опишите свою инфраструктуру как код.
Что на самом деле означает «Инфраструктура как код»
Infrastructure as Code (IaC) — это практика описания серверов, сетей, баз данных, балансировщиков нагрузки и всех остальных компонентов инфраструктуры в текстовых файлах. Эти файлы хранятся в репозитории системы контроля версий, как и код вашего приложения.
Ключевое изменение — в том, как вы описываете инфраструктуру. Вместо пошаговых команд вроде «Заходи по SSH на сервер, выполни эту команду для установки Nginx, затем отредактируй этот конфиг» вы пишете декларацию того, какой должна быть инфраструктура. Например: «Мне нужен сервер с Nginx версии 1.24, слушающий порт 443, с таким-то TLS-сертификатом и такими-то правилами прокси».
Инструмент, обрабатывающий эти файлы, читает вашу декларацию, сравнивает её с текущим состоянием инфраструктуры и вносит необходимые изменения для соответствия. Это называется управлением желаемым состоянием (desired state management).
Вот как выглядит простая декларативная конфигурация на Terraform:
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
user_data = <<-EOF
#!/bin/bash
apt-get update
apt-get install -y nginx
systemctl enable nginx
systemctl start nginx
EOF
tags = {
Name = "web-server"
}
}
resource "aws_security_group" "web_sg" {
name = "web-sg"
description = "Allow HTTP and SSH"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
Этот файл декларирует именно то, что вам нужно: EC2-инстанс с установленным Nginx и группа безопасности, разрешающая веб-трафик. Terraform сравнивает эту декларацию с текущим состоянием вашего AWS-аккаунта и вносит только те изменения, которые необходимы для соответствия.
Как это меняет вашу повседневную работу
Когда инфраструктура — это код, изменение конфигурации сервера больше не означает вход на машину и ввод команд. Это означает редактирование файла, открытие пул-реквеста, получение ревью и слияние изменения. Сервер обновляется автоматически при применении новой конфигурации.
Это полностью меняет рабочий процесс:
Каждое изменение отслеживается. История коммитов в вашем репозитории точно скажет, как выглядела конфигурация продакшн-балансировщика во вторник на прошлой неделе. Никаких догадок, никаких «кажется, кто-то менял эту настройку».
Изменения проверяемы. Прежде чем любое изменение инфраструктуры попадёт в продакшн, оно проходит тот же процесс ревью кода, что и изменения приложения. Участники команды могут комментировать, предлагать улучшения и ловить ошибки до того, как они вызовут простой.
Любой может предложить изменения. Разработчик, которому нужен новый пул соединений к базе данных, может написать конфигурацию и отправить пул-реквест. Ему не нужно ждать, пока у команды эксплуатации появится свободное время. Команда эксплуатации ревьюит изменение вместо того, чтобы выполнять его.
Откаты просты. Если изменение конфигурации вызвало проблемы, вы откатываете коммит и применяете заново. Вам не нужно вспоминать точную последовательность ручных шагов для отмены изменения.
Концепция желаемого состояния
Самая важная идея в инфраструктуре как коде — это желаемое состояние (desired state). Ваши конфигурационные файлы описывают идеальное состояние вашей инфраструктуры. Инструмент IaC непрерывно следит за тем, чтобы фактическое состояние соответствовало желаемому.
Если кто-то вручную изменил настройку на сервере, инструмент обнаруживает отклонение (drift) и возвращает её обратно. Если сервер упал и был заменён, инструмент автоматически разворачивает новый сервер с правильной конфигурацией. Вы не пишете скрипты, которые выполняются один раз. Вы определяете цель, и система поддерживает эту цель.
Это принципиально отличается от старого подхода, когда вы писали скрипт для настройки сервера, запускали его один раз и надеялись, что после этого ничего не изменится. С желаемым состоянием система самовосстанавливается и самопроверяется.
Чем инфраструктура как код не является
Инфраструктура как код — это не конкретный инструмент. Terraform, AWS CloudFormation, Ansible, Pulumi и многие другие — это реализации этой концепции. Инструмент менее важен, чем сама практика: относиться к конфигурации инфраструктуры как к версионируемому, проверяемому, декларативному коду.
Это также не про полное устранение ручной работы. Вам всё ещё нужно понимать свою инфраструктуру. Вы всё ещё принимаете проектные решения о сетях, безопасности и масштабировании. Но эти решения закодированы в файлах, которые можно проверять, тестировать и воспроизводить.
Почему это важно для CI/CD
Инфраструктура как код — это основа для того, чтобы относиться к изменениям инфраструктуры так же, как к изменениям приложения в вашем CI/CD-пайплайне. Когда ваша инфраструктура — это код, вы можете:
- Запускать автоматические тесты для изменений инфраструктуры до их применения
- Проверять синтаксическую корректность конфигурационных файлов
- Автоматически проверять нарушения политик безопасности
- Применять изменения через тот же пайплайн, который разворачивает приложение
- Обеспечивать согласованность между окружениями
Без инфраструктуры как кода ваш CI/CD-пайплайн может обрабатывать только код приложения. Изменения инфраструктуры остаются ручными, подверженными ошибкам и невидимыми для пайплайна. Это создаёт разрыв, когда развёртывание приложения автоматизировано, а инфраструктура, на которой оно работает, — нет.
Практический чеклист для начала
Если вы рассматриваете внедрение инфраструктуры как кода, вот практическая отправная точка:
- Выберите одно окружение для начала. Не пытайтесь конвертировать всю инфраструктуру сразу. Начните со стейджинга или разработки.
- Пишите декларативные файлы, а не скрипты. Сосредоточьтесь на том, что вы хотите, а не на том, как этого достичь. Декларативные файлы легче ревьюить и поддерживать.
- Храните всё в системе контроля версий. Ваш репозиторий должен содержать все конфигурационные файлы, а не только те, которые часто меняются.
- Ревьюйте изменения инфраструктуры как код. Требуйте пул-реквесты и утверждения для изменений инфраструктуры, как вы делаете для изменений приложения.
- Тестируйте перед применением. Используйте инструменты, которые могут проверять ваши конфигурационные файлы и симулировать изменения до того, как они попадут на реальные серверы.
- Документируйте желаемое состояние, а не шаги. Ваши файлы должны описывать целевую конфигурацию, а не последовательность команд для её достижения.
Вывод
Инфраструктура как код превращает серверы из чёрных ящиков, понятных лишь нескольким людям, в документированные, воспроизводимые и управляемые компоненты. Каждое изменение конфигурации оставляет след в истории коммитов. Каждый сервер может быть пересобран с нуля с одинаковыми результатами. Каждый участник команды может предлагать улучшения инфраструктуры без необходимости глубокого операционного доступа.
В следующий раз, когда кто-то спросит, что изменилось в продакшене на прошлой неделе, вам не придётся гадать. Вы откроете репозиторий и проверите лог коммитов. Вот в чём разница между инфраструктурой как искусством и инфраструктурой как кодом.