Terraform и OpenTofu
| Тип | инструмент Infrastructure as Code |
|---|---|
| Terraform | HashiCorp, 2014; с 2025 года HashiCorp — часть IBM |
| Лицензия Terraform | BUSL 1.1 (с августа 2023, ранее MPL 2.0) |
| OpenTofu | форк под эгидой Linux Foundation, 1.6.0 — январь 2024 |
| Лицензия OpenTofu | MPL 2.0 |
| Язык конфигурации | HCL |
| Язык реализации | Go |
| Ключевые понятия | провайдер, ресурс, модуль, состояние (state), план |
Terraform — инструмент Infrastructure as Code, который описывает облачную инфраструктуру — виртуальные машины, сети, базы данных, DNS-записи, кластеры Kubernetes — в декларативных файлах и приводит реальное состояние в соответствие с ними.[1] Пользователь пишет, что должно существовать, а Terraform вычисляет, какие API-вызовы нужны, показывает план и выполняет его. OpenTofu — открытый форк Terraform, появившийся после смены его лицензии в 2023 году; инструменты почти полностью совместимы, и всё сказанное ниже относится к обоим.[2]
История
HashiCorp выпустила Terraform в 2014 году; версия 1.0 со стабильными гарантиями совместимости вышла в 2021-м. Благодаря тысячам провайдеров Terraform стал стандартом описания облачной инфраструктуры.
В августе 2023 года HashiCorp перевела свои продукты с открытой лицензии MPL 2.0 на Business Source License, ограничивающую использование конкурентами.[3] В ответ сообщество создало форк OpenTofu, который принял Linux Foundation; первая стабильная версия 1.6.0 вышла в январе 2024 года.[4] С тех пор проекты развиваются раздельно: в OpenTofu, например, появилось встроенное шифрование файла состояния.[6] В феврале 2025 года HashiCorp вошла в состав IBM.[7]
Основные понятия
- Провайдер — плагин для конкретного API: AWS, Google Cloud, Azure, Yandex Cloud, Cloudflare, Kubernetes, GitHub. Провайдеры скачиваются из реестра при
init. - Ресурс (
resource) — управляемый объект: сервер, бакет, запись DNS. - Источник данных (
data) — чтение существующих объектов, которыми Terraform не управляет. - Переменные и выходы (
variable,output) — параметры и результаты конфигурации. - Модуль — переиспользуемый набор ресурсов (например, «сеть + кластер + база»), подключаемый с параметрами.
- Состояние (state) — файл
terraform.tfstate, связывающий описание с реальными объектами.
Пример
terraform {
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
backend "s3" {
bucket = "example-tf-state"
key = "prod/network.tfstate"
region = "eu-central-1"
}
}
variable "env" { default = "prod" }
resource "aws_s3_bucket" "assets" {
bucket = "example-assets-${var.env}"
tags = { env = var.env }
}
output "bucket_name" { value = aws_s3_bucket.assets.bucket }
Ссылки между ресурсами (aws_s3_bucket.assets.bucket) образуют граф зависимостей: Terraform сам определяет порядок создания и создаёт независимые ресурсы параллельно.
Рабочий цикл
terraform init # скачать провайдеры и модули, подключить backend
terraform fmt && terraform validate
terraform plan -out=tfplan # показать, что будет создано (+), изменено (~), удалено (-)
terraform apply tfplan
terraform destroy # удалить всё, что описано
tofu plan # то же самое в OpenTofu
План — главная гарантия безопасности: перед применением видно каждое изменение, и его проверяют на ревью в pull request. Особого внимания требуют строки «must be replaced»: изменение некоторых атрибутов приводит к пересозданию ресурса, а для базы данных это означает потерю данных.
Состояние
Файл состояния — самая чувствительная часть.[5]
- Его хранят не в Git, а в удалённом backend (S3-совместимое хранилище, Terraform Cloud, GitLab, Consul) с блокировкой, чтобы два человека не применяли изменения одновременно.
- В нём лежат атрибуты ресурсов, нередко с паролями и ключами в открытом виде — доступ к нему должен быть ограничен (см. Управление секретами).
- Ручные изменения в облаке вызывают дрейф (drift):
planпокажет расхождение и предложит вернуть описанное состояние. terraform importи блокиimportподключают уже существующие ресурсы, аstate mvи блокиmovedпозволяют переименовывать без пересоздания.
Практика
- Делить инфраструктуру на небольшие независимые конфигурации (сеть, данные, приложения) с отдельными файлами состояния — так меньше «радиус поражения» ошибки.
- Фиксировать версии провайдеров (
~> 5.0) и коммитить.terraform.lock.hcl. - Запускать
planв CI/CD на каждый pull request иapplyтолько после слияния — вручную или через Atlantis, Terraform Cloud, Spacelift. - Использовать проверки tflint, checkov, trivy для поиска ошибок и небезопасных настроек.
Terraform создаёт инфраструктуру, но обычно не настраивает программы внутри серверов — для этого применяют Ansible или образы, собранные заранее. Альтернативы с языками общего назначения — Pulumi и AWS CDK.