Представь: у тебя есть сервер на AWS, база данных, балансировщик, два окружения — staging и production. Всё это настраивалось вручную: зашёл в консоль, покликал, создал ресурс, прописал настройки. Месяц спустя нужно поднять ещё одно окружение — и ты снова кликаешь, пытаясь вспомнить, что именно делал тогда. Один параметр не тот — и всё сломалось.
Инфраструктура как код (IaC, Infrastructure as Code) решает именно эту проблему. Ты описываешь всю инфраструктуру в файлах — как обычный код — и применяешь её одной командой. Reproducibility, версионирование, никаких «снежинок» среди серверов.
Terraform от HashiCorp — самый популярный инструмент в этой нише. По данным Stack Overflow Developer Survey 2024, его используют больше 30% DevOps-инженеров. Конкуренты есть, но Terraform держит позиции за счёт зрелости экосистемы и поддержки почти любого облака.
Как это работает
Terraform читает .tf файлы, в которых ты описываешь желаемое состояние инфраструктуры. Потом сравнивает это с реальным состоянием — хранит его в state-файле — и делает только нужные изменения.
Три команды, которых хватает на 90% работы:
terraform init — инициализирует проект, скачивает провайдеры
terraform plan — показывает, что изменится (ничего не трогает)
terraform apply — применяет изменения
Провайдеры — это плагины, которые умеют общаться с конкретными API. Есть провайдеры для AWS, Google Cloud, Azure, Yandex Cloud, Digital Ocean, Cloudflare, GitHub, Kubernetes и ещё нескольких сотен сервисов. Реестр живёт на registry.terraform.io.
Базовый пример: поднимаем VPS на Yandex Cloud
Вот минимальный конфиг для создания виртуальной машины:
terraform {
required_providers {
yandex = {
source = "yandex-cloud/yandex"
version = "~> 0.90"
}
}
}
provider "yandex" {
token = var.yc_token
cloud_id = var.cloud_id
folder_id = var.folder_id
zone = "ru-central1-a"
}
resource "yandex_compute_instance" "web" {
name = "web-server"
platform_id = "standard-v3"
resources {
cores = 2
memory = 4
}
boot_disk {
initialize_params {
image_id = "fd8abc123" # Ubuntu 22.04
size = 20
}
}
network_interface {
subnet_id = yandex_vpc_subnet.main.id
nat = true
}
}
resource "yandex_vpc_network" "main" {
name = "main-network"
}
resource "yandex_vpc_subnet" "main" {
name = "main-subnet"
zone = "ru-central1-a"
network_id = yandex_vpc_network.main.id
v4_cidr_blocks = ["10.0.1.0/24"]
}
Запускаешь terraform apply — через 2–3 минуты сервер с сетью готов. Хочешь второй такой же — меняешь имя ресурса и снова apply. Хочешь удалить — terraform destroy.
State-файл: самое важное, что нужно понять
State-файл (terraform.tfstate) — это снимок текущего состояния инфраструктуры с точки зрения Terraform. По нему он понимает, что уже создано, а что нужно изменить или удалить.
Если работаешь один и state лежит локально — пока терпимо. Как только появляется второй человек в команде, всё ломается: у каждого своя версия state, конфликты неизбежны.
Решение — remote state. Популярные варианты:
- Terraform Cloud — есть бесплатный tier до 5 пользователей
- S3 + DynamoDB на AWS — классика, надёжно
- Yandex Object Storage + YDB — для тех, кто работает в российских облаках
- GitLab Managed Terraform State — если GitLab уже используется
Пример backend для S3:
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
Главное правило: никогда не коммить terraform.tfstate в git. Там могут быть секреты в открытом виде — пароли, токены, ключи доступа.
Переменные и модули
Повторяющийся код — признак плохой архитектуры. В Terraform с этим борются через переменные и модули.
Переменные:
variable "instance_count" {
type = number
default = 2
description = "Количество серверов"
}
Значения передаются через файл terraform.tfvars, переменные окружения (TF_VAR_instance_count=3) или флаги при запуске. Для чувствительных данных используй sensitive = true — Terraform скроет их вывод в логах.
Модули — это папки с набором .tf файлов. Описываешь типичную конфигурацию сервера один раз и переиспользуешь:
module "web_server" {
source = "./modules/web-server"
name = "prod-web"
cores = 4
memory = 8
}
Публичные модули есть на registry.terraform.io — тысячи готовых решений для AWS, GCP, Azure. Модуль для EKS-кластера, RDS-инстанса, VPC — всё есть, настраивай под себя.
Workspaces: несколько окружений из одного кода
Terraform Workspaces позволяют держать staging и production в одной кодовой базе, но с раздельными state-файлами:
terraform workspace new staging
terraform workspace new production
terraform workspace select staging
Внутри конфига можно ссылаться на имя окружения:
locals {
env = terraform.workspace
instance_size = {
staging = 2
production = 4
}
}
resource "yandex_compute_instance" "web" {
resources {
cores = local.instance_size[local.env]
}
}
Альтернативный подход — отдельные папки для каждого окружения (environments/staging/, environments/prod/) с общими модулями. Он более явный и удобен для крупных проектов.
Terraform против конкурентов
AWS CloudFormation — работает только с AWS, синтаксис JSON/YAML неудобен, трудно отлаживать. Если ты намертво привязан к AWS — можно, но Terraform гибче.
Pulumi — позволяет писать инфраструктуру на TypeScript, Python, Go. Удобен для команд, где инженеры хотят привычный язык программирования. Экосистема слабее, провайдеров меньше.
Ansible — скорее конфигурационный менеджмент, чем IaC. Хорош для настройки уже существующих серверов, но не для их создания. Часто используют вместе с Terraform: Terraform поднимает инфраструктуру, Ansible её настраивает.
OpenTofu — форк Terraform с открытой лицензией, появился после того, как HashiCorp в 2023 году сменила лицензию с open-source на Business Source License. Полностью совместим с Terraform, активно развивается. Если корпоративная политика против BSL — OpenTofu твой вариант.
Рабочий процесс в команде
Лучший паттерн — GitOps для инфраструктуры:
- Все изменения через pull request
- В CI запускается
terraform plan, результат публикуется в PR комментарием
- После approve — автоматический
terraform apply при мёрже в main
Это даёт ревью инфраструктурных изменений, историю в git и возможность откатиться.
Инструменты: Atlantis (self-hosted, бесплатный), Terraform Cloud с VCS-интеграцией, Spacelift для сложных сценариев.
Для качества кода добавь в CI:
terraform fmt — форматирует по стандарту
terraform validate — проверяет синтаксис
tflint — статический анализ, ловит типичные ошибки
checkov или tfsec — проверка безопасности конфигов
Типичные ошибки, которые дорого стоят
Секреты в .tf файлах. Никогда не пиши пароли и токены прямо в конфигах. Используй переменные окружения, HashiCorp Vault, AWS Secrets Manager или хотя бы terraform.tfvars с .gitignore.
Один гигантский state. Если prod, staging и все сервисы живут в одном state-файле — любое изменение затрагивает всё, terraform plan работает минутами. Дели по окружениям и сервисам.
Пропустить plan перед apply. Всегда смотри, что изменится. Terraform может пересоздать ресурс (удалить и создать заново) там, где ты ожидал просто update. В выводе это обозначается как -/+ вместо ~. Для базы данных это катастрофа.
Ручные изменения в консоли. Поменял что-то в AWS-консоли, не обновив Terraform — при следующем apply это изменение откатится. Либо всё через Terraform, либо ничего.
Нет защиты критичных ресурсов. lifecycle блок с prevent_destroy спасёт от случайного удаления баз данных и других важных ресурсов:
resource "aws_db_instance" "main" {
# ...
lifecycle {
prevent_destroy = true
ignore_changes = [password]
}
}
С чего начать прямо сейчас
Минимальный путь для первого знакомства:
- Поставь Terraform —
tfenv удобен для управления версиями
- Возьми бесплатный аккаунт в Yandex Cloud или Digital Ocean
- Создай простой ресурс — VPS или S3 bucket
- Добавь remote state
- Попробуй сломать через
destroy и восстановить через apply
Официальная документация на developer.hashicorp.com/terraform реально хорошая — с туториалами и интерактивными примерами. Сертификат HashiCorp Certified: Terraform Associate стоит $70 и хорошо структурирует знания.
Терраform имеет смысл вводить, когда у тебя больше одного окружения или больше одного человека в команде. До этого порога часто достаточно bash-скрипта и ручного управления. Не надо тащить тяжёлые инструменты туда, где они не нужны.
В REEXY при работе над корпоративными сайтами (от 15 000 ₽) и интернет-магазинами (от 10 000 ₽) мы регулярно обсуждаем с клиентами вопросы инфраструктуры: где хостить, как масштабироваться под нагрузку, нужен ли Kubernetes. Terraform в таких проектах — не модная игрушка, а способ сэкономить часы работы при каждом деплое и не зависеть от памяти конкретного инженера.