1.3 Infrastructure as Code (IaC) #
🎯 Что такое Infrastructure as Code #
IaC — это управление инфраструктурой с помощью кода вместо ручных процессов.
Представьте строительство дома:
- Без IaC: каждый раз объясняете строителям на словах, что делать
- С IaC: у вас есть подробные чертежи, по которым можно построить идентичный дом
🔄 Проблемы ручного управления #
Типичная ситуация без IaC #
Проблема ручного управления:
Администратор настраивает первый сервер вручную:
- Подключается по SSH
- Обновляет пакеты
- Устанавливает nginx
- Настраивает автозапуск
- Выполняет еще 50 команд…
Через месяц нужен второй сервер, но никто не помнит точную последовательность действий. Приходится гуглить и восстанавливать по памяти.
Проблемы ручного подхода #
- Configuration Drift - серверы “расходятся” по конфигурации
- Снежинки - уникальные серверы, которые боятся трогать
- Нет версионирования инфраструктуры
- Долгое восстановление после сбоев
- Сложно масштабировать
🛠️ Решение: Infrastructure as Code #
Принципы IaC #
-
Декларативный подход - описываем ЧТО хотим, а не КАК делать
-
Идемпотентность - повторное выполнение даёт тот же результат
💡 Идемпотентность означает, что операция может быть выполнена множество раз с одинаковым результатом. Если команда уже создала ресурс, повторный запуск не создаст дубликат, а проверит и при необходимости обновит существующий.
-
Версионирование - инфраструктура в Git
-
Тестируемость - можно тестировать изменения
Пример с Terraform #
Пример Terraform-конфигурации:
Описание желаемой инфраструктуры в декларативном стиле:
Создание веб-сервера:
- Используем образ AMI с идентификатором ami-0c55b159cbfafe1d0
- Тип инстанса: t2.micro (бесплатный уровень)
- Метки: имя “WebServer” и окружение “Production”
Настройка группы безопасности:
- Разрешаем входящие соединения на порт 80 (HTTP)
- Разрешаем входящие соединения на порт 443 (HTTPS)
- Доступ открыт для всех IP-адресов
Применение изменений #
Процесс применения изменений:
- Планирование: Просматриваем, какие ресурсы будут созданы, изменены или удалены
- Применение: Выполняем запланированные изменения
- Результат: Получаем точно такую же инфраструктуру каждый раз!
🏗️ Популярные инструменты IaC #
1. Terraform (HashiCorp) #
Плюсы:
- Работает с любыми провайдерами (AWS, Azure, GCP, etc.)
- Большое сообщество
- Хорошая документация
Минусы:
- Свой язык HCL
- State файлы нужно хранить
Пример использования: Пример использования провайдера AWS:
Настройка Terraform для работы с Amazon Web Services:
- Указываем регион us-west-2 (“Западное побережье США”)
- Создаем виртуальную частную сеть (VPC)
- Назначаем CIDR-блок 10.0.0.0/16 (около 65,000 IP-адресов)
- Добавляем метку с именем “MainVPC”
2. AWS CloudFormation #
Плюсы:
- Нативная интеграция с AWS
- Нет дополнительной установки
- Автоматический rollback при ошибках
Минусы:
- Только для AWS
- JSON/YAML могут быть громоздкими
Пример: Пример AWS CloudFormation шаблона:
Описание инфраструктуры в формате YAML:
- Указываем версию шаблона CloudFormation 2010-09-09
- Определяем ресурс EC2-инстанса с именем “WebServer”
- Указываем свойства: образ AMI, тип инстанса и метки
3. Ansible #
Плюсы:
- Простой YAML синтаксис
- Agentless (не требует установки на целевые серверы)
- Идеально для конфигурации серверов
Минусы:
- Менее подходит для создания инфраструктуры
- Может быть медленным на больших инвентарях
Пример: Пример Ansible playbook:
Описание задач для автоматической настройки веб-серверов:
- Определяем целевые серверы (группа “webservers”)
- Устанавливаем пакет nginx через менеджер пакетов apt
- Запускаем сервис nginx и добавляем в автозапуск
4. Pulumi #
Плюсы:
- Используете привычные языки программирования (Python, TypeScript, Go)
- Богатые возможности логики
- Хорошие IDE возможности
Минусы:
- Относительно новый
- Меньше примеров в интернете
Пример (Python): Пример Pulumi конфигурации на Python:
Описание инфраструктуры на пивычном языке программирования:
- Импортируем библиотеку pulumi_aws для работы с Amazon Web Services
- Создаем EC2-инстанс с именем “web-server”
- Указываем свойства: тип t2.micro, образ AMI и метки
- Экспортируем публичный IP-адрес сервера для дальнейшего использования
🎯 Реальный кейс: Миграция на IaC #
Ситуация: Стартап без IaC #
Проблемы:
- 5 серверов настроены руками
- Каждый уникальный
- Деплой занимает 2 часа
- Страх что-то сломать
Решение: Поэтапная миграция #
Поэтапная миграция на IaC:
Шаг 1: Инвентаризация
- Импортируем существующие ресурсы в Terraform state
- Привязываем EC2-инстанс и группу безопасности к Terraform-конфигурации
Шаг 2: Описание в коде
- Создаем файл main.tf, описывающий текущую инфраструктуру
Шаг 3: Тестирование
- Проверяем, что Terraform не планирует никаких изменений (“Никаких изменений”)
Шаг 4: Постепенные улучшения
- Фиксируем результат в системе контроля версий Git
Результат через 3 месяца #
- Время деплоя: 2 часа → 15 минут
- Количество ошибок: -80%
- Возможность отката: 0 → 100%
- Документированность: 20% → 100%
📋 Лучшие практики IaC #
1. Структура проекта #
Рекомендуемая структура Terraform-проекта:
- Папка terraform/: корневая директория проекта
- environments/: конфигурации для разных окружений
- dev/: конфигурация разработки
- staging/: конфигурация тестовой среды
- prod/: конфигурация продакшена
- modules/: переиспользуемые модули
- vpc/: модуль для сетевой инфраструктуры
- ec2/: модуль для виртуальных машин
- rds/: модуль для управляемых баз данных
- README.md: документация проекта
- .gitignore: правила игнорирования файлов в Git
- environments/: конфигурации для разных окружений
2. Используйте модули #
Пример использования модулей:
Неправильно: Дублирование кода с повторением одинаковых ресурсов много раз
Правильно: Использование переиспользуемого модуля:
- Указываем путь к модулю веб-сервера
- Задаем количество экземпляров (3 сервера)
- Передаем параметры: тип инстанса и окружение
3. Переменные окружения #
Пример определения переменных:
Определение конфигурируемых параметров с валидацией:
Переменная environment:
- Описание: название окружения
- Тип: строка
- Значение по умолчанию: “dev”
Переменная instance_count:
- Описание: количество инстансов
- Тип: число
- Значение по умолчанию: 1
- Правило валидации: должно быть положительным числом
4. Безопасность #
Правила безопасности в IaC:
Неправильно: Никогда не сохраняйте пароли и секреты непосредственно в коде!
Правильные подходы:
-
Автоматическая генерация: Позволяем AWS автоматически генерировать и управлять мастер-паролем
-
Использование переменных: Передаем пароль через переменную окружения или систему управления секретами
5. State управление #
Настройка удаленного хранилища state:
Конфигурация для безопасного хранения Terraform state в AWS S3:
Основные параметры:
- Имя S3-бакета: “mycompany-terraform-state”
- Ключ файла: “prod/terraform.tfstate” (для продакшен-окружения)
- Регион: us-west-2
Механизмы безопасности:
- Блокировка state-файла через DynamoDB таблицу
- Использование шифрования для защиты данных
🧪 Тестирование IaC #
1. Статическая проверка #
Инструменты статической проверки Terraform:
Встроенные команды:
- terraform fmt: автоматическое форматирование кода по стандартам
- terraform validate: проверка синтаксиса и структуры конфигурации
Дополнительные инструменты:
- tfsec: специализированная проверка безопасности Terraform-конфигураций
- checkov: комплексная проверка на соответствие лучшим практикам
2. Тестирование в изолированной среде #
Процесс тестирования в изолированной среде:
- Создание тестового workspace: Отдельное пространство для тестов с именем “test”
- Развертывание: Применение инфраструктуры с параметром environment=“test”
- Выполнение тестов: Проверка вывода на наличие ключевого слова “test”
- Очистка: Автоматическое удаление ресурсов и workspace после тестирования
3. Terratest (Go) #
Пример автоматизированного теста с Terratest (Go):
Функция для автоматического тестирования Terraform-инфраструктуры:
Основные этапы:
- Настройка тестовой конфигурации с указанием пути к Terraform-файлам и параметров
- Отложенное удаление ресурсов после завершения теста
- Инициализация и применение Terraform-конфигурации
- Получение IP-адреса созданного инстанса
- HTTP-проверка с повторными попытками и ожиданием ответа 200 с текстом “Hello World”
🎯 Практическое задание #
Задание 1: Первый Terraform проект #
- Установите Terraform
- Создайте AWS Free Tier аккаунт
- Напишите конфигурацию для создания:
- VPC
- Public subnet
- EC2 инстанс с nginx
- Примените конфигурацию
- Проверьте, что сайт доступен
- Уничтожьте ресурсы
Задание 2: Ansible playbook #
- Создайте inventory файл с вашими серверами
- Напишите playbook для установки:
- Docker
- Docker Compose
- Git
- Запустите playbook
- Проверьте результат
📊 Метрики успеха IaC #
Показатели зрелости команды #
Уровни зрелости управления инфраструктурой:
Уровень 1 - Ручное управление:
- Настройка серверов вручную
- Отсутствие документации процессов
- Длительное восстановление после сбоев
Уровень 2 - Скрипты:
- Использование bash-скриптов для автоматизации
- Частичная документация процессов
- Ограниченная повторяемость
Уровень 3 - Infrastructure as Code:
- Полное описание инфраструктуры в коде
- Контроль версий всех изменений
- Автоматическое тестирование конфигураций
- Быстрое и надежное восстановление
🎯 Заключение #
Infrastructure as Code — это основа современного DevOps. Ключевые принципы:
✅ Всё в коде - никаких ручных изменений
✅ Версионирование - каждое изменение отслеживается
✅ Тестирование - проверяйте изменения до применения
✅ Модульность - переиспользуйте код
✅ Безопасность - никаких секретов в коде
Помните: Переход на IaC — это инвестиция в будущее. Сначала может быть сложно, но экономия времени и нервов окупится многократно.
🤔 Вопросы для размышления #
Вопрос 1: Идемпотентность Bash #
Идемпотентен ли обычный Bash скрипт?
#!/bin/bash
# Пример скрипта
mkdir /opt/myapp
cp app.jar /opt/myapp/
systemctl start myapp
Ответ и объяснение
Нет, не идемпотентен. При повторном запуске:
mkdir
выдаст ошибку, если папка уже существуетcp
перезапишет файл (может быть ОК)systemctl start
выдаст ошибку, если сервис уже запущен
Как сделать идемпотентным через shell:
#!/bin/bash
# Идемпотентная версия
mkdir -p /opt/myapp # -p не ругается если папка есть
cp app.jar /opt/myapp/ # перезапись ОК
systemctl is-active myapp || systemctl start myapp # запускаем только если не активен
# Или через if-условия
if [ ! -d "/opt/myapp" ]; then
mkdir /opt/myapp
fi
if ! systemctl is-active --quiet myapp; then
systemctl start myapp
fi
Вопрос 2: Модули в Ansible vs Terraform #
В чем отличие понятия “модуль” в Ansible и Terraform?
Ответ и объяснение
Ansible модули:
- Атомарные задачи - каждый модуль выполняет одну конкретную операцию
- Встроенные в Ansible - уже готовые к использованию
- Примеры:
apt
,yum
,copy
,service
,user
- Идемпотентность встроена - модули сами проверяют текущее состояние
- name: Install nginx
apt:
name: nginx
state: present # идемпотентно - установит только если нет
Terraform модули:
- Группировка ресурсов - логически связанный набор ресурсов
- Переиспользуемые компоненты - создаются пользователем или сообществом
- Примеры: модуль VPC, модуль веб-сервера, модуль базы данных
- Абстракция сложности - скрывают детали реализации
module "vpc" {
source = "./modules/aws-vpc"
cidr_block = "10.0.0.0/16"
environment = "prod"
}
Ключевое отличие:
- Ansible модуль = готовый инструмент для выполнения задачи
- Terraform модуль = шаблон для создания набора ресурсов
Следующий раздел: 1.4 Мониторинг и Observability