DevOps

Terraform: основы Infrastructure as Code

2021 год: крупный провайдер потерял весь prod кластер из-за ошибочного `kubectl delete` выполненного junior-инженером. Восстановление заняло 8 часов. Если бы инфраструктура была описана в Terraform: `terraform apply` - 15 минут до полного восстановления с идентичной конфигурацией.

  • **Spotify** управляет тысячами микросервисов через Terraform - каждый новый сервис получает стандартный набор ресурсов через внутренние модули: RDS, S3, IAM роли, мониторинг.
  • **GitHub** использует Terraform для управления AWS инфраструктурой: все изменения через PR, автоматический plan в CI, apply только после апрува - GitOps принципы для IaC.
  • **Terraform Cloud** позволяет командам запускать plan/apply в управляемой среде с централизованным state и audit log - каждое изменение инфраструктуры отслеживается.

Провайдеры: мост между Terraform и API

В 2014 году HashiCorp выпустила Terraform с одной идеей: инфраструктура - это код, который можно версионировать, ревьюить и воспроизводить. Провайдер - это плагин, который знает API конкретного облака или сервиса и транслирует HCL-декларации в API-вызовы. Сегодня реестр Terraform содержит 3000+ провайдеров.

**Провайдеры:** официальные (AWS, Azure, GCP, Kubernetes - от HashiCorp или облачных вендоров), партнерские (Datadog, PagerDuty, Cloudflare), community. Версионирование провайдеров критично: `~> 5.0` означает >=5.0, <6.0. **Terraform Registry:** registry.terraform.io - центральный реестр. `terraform init` скачивает провайдеры в `.terraform/providers/`. **Provider lock file:** `.terraform.lock.hcl` фиксирует хеши провайдеров - коммитить в Git обязательно.

Зачем коммитить `.terraform.lock.hcl` в Git?

Ресурсы и Data Sources: строительные блоки

Ресурс в Terraform - это управляемый инфраструктурный объект: EC2 инстанс, S3 бакет, DNS-запись. Data source - это объект, которым управляет не Terraform, но его данные нужны для конфигурации (существующий VPC, AMI ID, сертификат). Зависимости между ресурсами Terraform вычисляет автоматически - строит граф и применяет параллельно где возможно.

**Неявные зависимости:** `aws_instance.web` ссылается на `aws_security_group.web.id` - Terraform автоматически создает SG перед инстансом. **Явные зависимости:** `depends_on = [aws_s3_bucket.data]` - когда зависимость не видна из атрибутов. **Data sources:** `data.aws_ami.ubuntu.id` - находит последний Ubuntu AMI без хардкода ID. **Lifecycle:** `create_before_destroy = true` - создать новый ресурс перед удалением старого (zero-downtime замена). `prevent_destroy = true` - защита prod ресурсов от случайного удаления.

Нужно создать EC2 инстанс в существующем VPC (не управляемом Terraform). Как получить VPC ID?

State: как Terraform помнит что создал

Terraform state - файл `terraform.tfstate`, где хранится маппинг между ресурсами в HCL и реальными объектами в облаке. Это не просто кеш - без state Terraform не знает что уже создано и создаст дубликаты. Хранение state - одно из важнейших архитектурных решений в любом Terraform проекте.

**Проблемы с локальным state:** нет командной работы (у каждого свой state), нет блокировки (race condition при параллельном apply), нет резервных копий. **Remote state backend:** S3 + DynamoDB (AWS), Azure Blob Storage, GCS, Terraform Cloud. **State locking:** DynamoDB table с атрибутом `LockID` блокирует state при apply - предотвращает concurrent изменения. **Чувствительные данные в state:** пароли и секреты хранятся в state в открытом виде - шифрование бакета обязательно. **Команды:** `terraform state list`, `terraform state show aws_instance.web`, `terraform state mv` (переименование), `terraform state rm` (удалить из state без удаления ресурса).

Два инженера одновременно запустили `terraform apply` для одного state. Что произойдет при настроенном DynamoDB locking?

Модули: переиспользование и абстракция

Модуль Terraform - это пакет HCL-файлов с входными переменными, ресурсами и выходными значениями. Как функция в программировании: скрывает детали реализации, принимает параметры, возвращает данные. Реестр Terraform содержит тысячи готовых модулей: `terraform-aws-modules/vpc/aws`, `terraform-aws-modules/eks/aws`.

**Структура модуля:** `variables.tf` (входные параметры), `main.tf` (ресурсы), `outputs.tf` (выходные значения), `versions.tf` (требования к провайдерам). **Источники модулей:** локальный путь `./modules/vpc`, Git `github.com/org/terraform-modules//vpc`, Terraform Registry `registry.terraform.io/modules/hashicorp/...`. **Best practices:** модуль не должен иметь backend - state управляется в root module. Входные переменные - с validation блоками. Outputs - всё что может понадобиться вызывающему.

Terraform plan показывает что будет сделано - если plan выглядит правильно, apply всегда безопасен

Plan строится на state и конфигурации, но реальное состояние облака может отличаться от state. Ресурсы могут быть удалены вручную или изменены снаружи Terraform.

Перед критическим apply стоит запустить `terraform refresh` или `terraform plan -refresh=true` для синхронизации state с реальностью. В prod нужны `prevent_destroy` и обязательный review плана в CI.

Модуль `terraform-aws-modules/vpc/aws` из реестра - как зафиксировать версию модуля?

Ключевые идеи

  • **Провайдеры** транслируют HCL в API облачных сервисов; `.terraform.lock.hcl` фиксирует версии - его нужно коммитить в Git.
  • **State** - маппинг HCL ресурсов к реальным объектам. Remote backend (S3 + DynamoDB) обязателен для командной работы: history + locking + шифрование.
  • **Модули** - переиспользуемые пакеты с inputs/outputs; версионировать явно, не использовать latest. Plan/apply цикл всегда: проверить план, получить апрув, применить.

Связанные темы

Terraform - фундамент для GitOps и управления кластерами:

  • GitOps: ArgoCD и Flux — Terraform создает кластер, GitOps управляет деплоями в него - две взаимодополняющие практики
  • CI/CD пайплайны — terraform plan и apply запускаются из CI/CD пайплайнов с автоматической проверкой и апрувом

Вопросы для размышления

  • Как правильно организовать terraform workspace или отдельные state файлы для dev/staging/prod?
  • Что делать если state содержит секреты (например пароль RDS) - как это разрешить без хардкода?
  • Как тестировать Terraform модули - какие инструменты (terratest, terraform test) и когда их применять?

Связанные уроки

  • os-12-virtualization
  • net-50-cloud-networking
Terraform: основы Infrastructure as Code

0

1

Войти