Инфраструктура в облаке — удобный и полезный инструмент. Кликнул пару раз в панели, создал виртуальную машину, настроил сеть, добавил группу безопасности — и всё заработало. Проблемы начинаются, когда нужно повторить эту же конфигурацию для тестового окружения. Или когда через месяц кто-то пытается понять, почему продакшен отличается от стейджинга. Или когда единственный человек, который помнит все ручные правки, уходит в отпуск.
Terraform — инструмент, который решает эти проблемы через описание инфраструктуры кодом. Вместо кликов в веб-интерфейсе вы пишете конфигурационные файлы, кладёте их в репозиторий и запускаете одну команду, чтобы поднять всё необходимое. В статье разберём, как это работает, с чего начать и что делать, если официальный реестр провайдеров недоступен из России.
ВАМ ПРИШЛО ПРИГЛАШЕНИЕ 💌
Приходите к нам в соцсети поделиться своим мнением и почитать, что пишут другие. А ещё там выходит дополнительный контент, которого нет на сайте — шпаргалки, опросы и разная дурка. В общем, вот тележка, вот ВК — велком!
Что такое инфраструктура как код
Инфраструктура, собранная вручную через консоль или CLI, держится на человеческом факторе. Администратор запоминает последовательность действий, но память ненадежна. В одном окружении версии пакетов свежее, в другом — устаревшие, сетевые параметры и правила групп безопасности отличаются. Разница между окружениями проявляется на релизе: тесты проходят, а продакшен падает.
Инфраструктура как код (IaC) убирает эту неопределённость. Вместо кликов и одноразовых команд вы пишете конфигурационные файлы. Эти файлы лежат в репозитории, проходят ревью, имеют историю изменений и позволяют откатиться к любой предыдущей версии. Никаких ручных правок — только код.
К чему приводит ручная настройка:
- окружения расходятся, потому что кто-то что-то забыл или сделал иначе;
- нет истории изменений — непонятно, что и когда меняли;
- откатиться невозможно, если что-то сломалось;
- вся инфраструктура завязана на одном исполнителе, который всё помнит.
IaC устраняет все эти проблемы. Вы пишете конфигурацию, кладёте её в Git, и любой участник группы может воспроизвести инфраструктуру одной командой.
Что делает Terraform и чем он отличается от соседей
Terraform — инструмент для создания и управления инфраструктурой через описание желаемого состояния. Вы пишете, что хотите получить: виртуальную машину с такими-то параметрами, сеть с определенными настройками, хранилище с конкретными правами. Terraform сам вычисляет, что уже есть, чего не хватает, и приводит реальность к описанию.
Новички часто путают Terraform с Ansible. Но они решают разные задачи.
Terraform создаёт ресурсы у облачного провайдера. Он подходит для всего жизненного цикла инфраструктуры: от создания сети и виртуальных машин до настройки баз данных и Kubernetes-кластеров. Ansible настраивает то, что уже создано, — устанавливает пакеты, копирует конфиги, разворачивает приложения.
| Инструмент | Задача | Подход | Когда нужен |
| Terraform | создание ресурсов у облачного провайдера | декларативный | нужно поднять и переиспользовать инфраструктуру |
| OpenTofu | то же самое, форк Terraform с открытой лицензией | декларативный | нужна лицензия MPL вместо BUSL |
| Ansible | настройка внутри уже созданных машин | императивный | установка пакетов, конфиги, деплой |
| Pulumi | описание инфраструктуры на языках программирования | декларативный | команда хочет писать на TypeScript или Go |
| CloudFormation | ресурсы внутри одного облака | декларативный | вся инфраструктура в AWS |
Terraform использует декларативный подход: вы описываете, что должно быть, а не как это сделать. Инструмент сам строит план и выполняет его.
Как устроен Terraform
Перед тем как писать первый конфиг, стоит разобраться в базовых понятиях. Без них вы будете выполнять команды, не понимая, что на самом деле происходит.
Провайдеры — плагины, которые превращают описание в вызовы API облака
Провайдер — это плагин, который Terraform использует для взаимодействия с конкретным сервисом. Для Yandex Cloud нужен провайдер yandex-cloud/yandex, для AWS — hashicorp/aws, для VK Cloud — vk-cs/vkcs.
Версию провайдера обязательно закрепляют в блоке required_providers. Без указания версии Terraform скачает последнюю, и в следующий раз конфигурация может повести себя иначе.
terraform {
required_version = "~> 1.15"
required_providers {
yandex = {
source = "yandex-cloud/yandex"
version = "~> 0.130"
}
}
}
Типичная ошибка новичка: пропустить блок required_providers и положиться на provider без версии. В следующем обновлении провайдера конфигурация может сломаться.
Ресурсы и источники данных
Ресурс — это объект, который Terraform создаёт, изменяет или удаляет. Виртуальная машина, группа безопасности, объектное хранилище — всё это ресурсы.
Источник данных (data source) читает информацию о существующем объекте. Например, можно получить ID последнего образа Ubuntu или параметры уже созданной сети.
Адресация ресурсов и источников данных выглядит одинаково: тип.имя. Например, yandex_compute_instance.web — это ресурс виртуальной машины с именем web.
Файл состояния — карта соответствия между описанием и реальными объектами
Когда Terraform создаёт ресурс, он запоминает его идентификатор и все параметры в файле состояния. При следующем запуске он сравнивает описание в конфиге с состоянием и вычисляет разницу.
Локальный файл состояния (terraform.tfstate) лежит в рабочей директории. Для командной работы его выносят в удалённое хранилище — об этом позже.
Язык HCL — блоки, аргументы, выражения
Terraform использует собственный язык HCL (HashiCorp Configuration Language). Всё строится вокруг блоков и аргументов.
Блок начинается с ключевого слова и содержит аргументы в фигурных скобках:
resource "yandex_compute_instance" "web" {
name = "web-server"
platform_id = "standard-v3"
zone = "ru-central1-a"
resources {
cores = 2
memory = 4
}
boot_disk {
initialize_params {
image_id = "fd8miiisblcuktpjr6sc"
size = 20
}
}
network_interface {
subnet_id = yandex_vpc_subnet.public.id
nat = true
}
}
Значения можно передавать между ресурсами через интерполяцию. В примере выше subnet_id берётся из другого ресурса — yandex_vpc_subnet.public.id.
Граф зависимостей
Terraform автоматически строит граф зависимостей между ресурсами. Если виртуальная машина ссылается на подсеть, Terraform создаст подсеть первой, а потом машину.
Явную зависимость можно задать через depends_on, но обычно это не требуется — Terraform сам находит связи по ссылкам в конфигурации.
Установка и доступ из России
Terraform устанавливается просто: скачиваете бинарный файл с официального сайта, кладёте в директорию из PATH и даёте права на выполнение.
На момент подготовки статьи актуальная стабильная ветка — 1.15.x. Последний патч — 1.15.8 от 8 июля 2026 года. В конце августа 2026 года вышла версия 1.16.0.
Важное изменение: с 2023 года Terraform распространяется под лицензией Business Source License 1.1 (BUSL) вместо Mozilla Public License. Это source-available лицензия, которая не ограничивает использование для управления собственной инфраструктурой, но запрещает использовать код для создания конкурентных коммерческих продуктов. Последняя версия под MPL — 1.5.x, именно её форкнуло сообщество в проект OpenTofu.
Главная практическая проблема для читателей из России: официальный реестр провайдеров registry.terraform.io ограничивает доступ из России. Terraform не может скачать провайдеров при init.
Что делать:
1. Настроить зеркало реестра через Selectel
Selectel предоставляет кеширующий прокси для Terraform Registry. Создайте файл .terraformrc в домашней директории:
provider_installation {
network_mirror {
url = "https://tf-proxy.selectel.ru/mirror/v1/"
}
direct {
exclude = ["registry.terraform.io/*/*"]
}
}
2. Использовать зеркало Yandex Cloud
Альтернативный вариант — зеркало от Yandex Cloud:
provider_installation {
network_mirror {
url = "https://terraform-mirror.yandexcloud.net/"
include = ["registry.terraform.io/*/*"]
}
direct {
exclude = ["registry.terraform.io/*/*"]
}
}
3. Устанавливать провайдеры из собственных реестров облачных провайдеров
Российские облачные провайдеры публикуют свои провайдеры в собственных реестрах. Для Yandex Cloud провайдер ставится из yandex-cloud/yandex. VK Cloud использует vk-cs/vkcs. Selectel — selectel/selectel.
Эти провайдеры скачиваются напрямую из реестров провайдеров, минуя registry.terraform.io.
Важно: проверяйте контрольные суммы скачанных бинарников. Официальные хеши публикуются в репозиториях провайдеров на GitHub.
Большая скидка — 16% на все курсы Практикума
Если вы читаете эту статью, тогда вы точно разбираетесь в технологиях. Стать лучше и зарабатывать больше можно после курсов Практикума — по программированию, анализу данных и искусственному интеллекту.
До 17 сентября на все курсы действует скидка 16%, она применится автоматически при оплате. Потом цены станут выше, поэтому не откладывайте!
Ещё настраиваете облако руками через консоль — начните с «Системного администратора»; уже пишете конфиги и разбираетесь со state — «DevOps»; беспокоитесь за секреты и доступы в пайплайне — «DevSecOps»; проектируете инфраструктуру для нескольких команд — «Архитектора решений».
Первый конфиг за пятнадцать минут
Теперь перейдём к практике. Будем разворачивать виртуальную машину с сетью, группой безопасности и объектным хранилищем в Yandex Cloud. Все примеры реальные — конфигурация проверена на работающем облаке.
Предупреждение: создание ресурсов в облаке тарифицируется. После проверки обязательно выполните terraform destroy, чтобы не тратить деньги.
Инициализация проекта
Создайте директорию для проекта и файл main.tf. Структура:
terraform-project/
└── main.tf
В main.tf описываем провайдер, сеть, подсеть, группу безопасности, виртуальную машину и объектное хранилище.
terraform {
required_version = "~> 1.15"
required_providers {
yandex = {
source = "yandex-cloud/yandex"
version = "~> 0.130"
}
}
}
provider "yandex" {
zone = "ru-central1-a"
}
# Сеть
resource "yandex_vpc_network" "main" {
name = "main-network"
}
# Подсеть
resource "yandex_vpc_subnet" "public" {
name = "public-subnet"
zone = "ru-central1-a"
network_id = yandex_vpc_network.main.id
v4_cidr_blocks = ["10.0.1.0/24"]
}
# Группа безопасности
resource "yandex_vpc_security_group" "web" {
name = "web-sg"
description = "Разрешает HTTP и SSH"
network_id = yandex_vpc_network.main.id
ingress {
protocol = "TCP"
description = "HTTP"
v4_cidr_blocks = ["0.0.0.0/0"]
port = 80
}
ingress {
protocol = "TCP"
description = "SSH"
v4_cidr_blocks = ["0.0.0.0/0"]
port = 22
}
egress {
protocol = "ANY"
description = "ANY"
v4_cidr_blocks = ["0.0.0.0/0"]
port = -1
}
}
# Объектное хранилище (бакет)
resource "yandex_storage_bucket" "data" {
bucket = "my-terraform-bucket-${random_string.suffix.result}"
acl = "public-read"
}
resource "random_string" "suffix" {
length = 6
special = false
upper = false
}
# Виртуальная машина
resource "yandex_compute_instance" "web" {
name = "web-server"
platform_id = "standard-v3"
zone = "ru-central1-a"
resources {
cores = 2
memory = 4
}
boot_disk {
initialize_params {
image_id = "fd8miiisblcuktpjr6sc" # Ubuntu 22.04 LTS
size = 20
}
}
network_interface {
subnet_id = yandex_vpc_subnet.public.id
nat = true
security_group_ids = [yandex_vpc_security_group.web.id]
}
metadata = {
ssh-keys = "ubuntu:${file("~/.ssh/id_rsa.pub")}"
}
}
output "vm_ip" {
value = yandex_compute_instance.web.network_interface.0.nat_ip_address
}
output "bucket_name" {
value = yandex_storage_bucket.data.bucket
}
Перед запуском убедитесь, что у вас есть:
- аккаунт в Yandex Cloud с оплаченным биллингом;
- сервисный аккаунт с правами на создание ресурсов;
- ключи доступа, настроенные через переменные окружения:
YC_TOKEN,YC_CLOUD_ID,YC_FOLDER_ID.
Теперь инициализируем проект:
terraform init
Terraform скачает провайдер Yandex Cloud (через настроенное зеркало или напрямую) и подготовит рабочую директорию.
Просмотр плана
Перед созданием ресурсов всегда смотрите план:
terraform plan
Вывод покажет, что будет создано. Знаки в выводе:
+— ресурс будет создан;–— ресурс будет удалён;~— ресурс будет изменён;-/+— ресурс будет заменён (удалён и создан заново).
В конце плана — счётчик изменений: сколько ресурсов добавится, изменится, удалится.
Привычка читать план целиком спасает от неожиданностей. Если план показывает удаление важного ресурса — остановитесь и разберитесь, почему.
Применение изменений
Когда план выглядит правильно:
terraform apply
Terraform покажет план ещё раз и запросит подтверждение. Введите yes.
Процесс займёт пару минут. После завершения в облаке появятся:
- сеть
main-network; - подсеть
public-subnetс диапазоном 10.0.1.0/24; - группа безопасности
web-sgс правилами для HTTP и SSH; - бакет с уникальным именем (суффикс добавляется случайной строкой);
- виртуальная машина
web-serverс Ubuntu 22.04, публичным IP и открытыми портами 80 и 22.
В панели Yandex Cloud вы увидите созданные ресурсы. Публичный IP машины появится в выводе после apply, а также можно посмотреть его через output:
terraform output vm_ip
Удаление ресурсов
После проверки удалите всё, что создали:
terraform destroy
Terraform покажет, что будет удалено, и запросит подтверждение. После yes все ресурсы исчезнут из облака.
В учебном проекте destroy вызывают сразу после проверки, чтобы не копить расходы.
Переменные и выходные значения
Жёстко зашитые значения в конфиге — плохая практика. Для разных окружений нужны разные параметры: имя бакета, размер диска, количество ядер. Переменные решают эту проблему.
Объявление переменной с типом и значением по умолчанию:
variable "vm_cores" {
description = "Количество ядер виртуальной машины"
type = number
default = 2
}
variable "vm_memory" {
description = "Объём памяти в ГБ"
type = number
default = 4
}
variable "bucket_name" {
description = "Имя бакета"
type = string
# значение обязательно — без default
}
variable "ssh_public_key_path" {
description = "Путь к публичному SSH-ключу"
type = string
default = "~/.ssh/id_rsa.pub"
}
Значения переменным можно передавать разными способами. Приоритет источников (от высшего к низшему):
- флаг командной строки
-varили-var-file; - файл
terraform.tfvarsилиterraform.tfvars.json; - переменные окружения с префиксом
TF_VAR_; - значение по умолчанию в объявлении переменной.
Файл terraform.tfvars:
vm_cores = 4
vm_memory = 8
bucket_name = "my-production-bucket"
Переменные окружения:
export TF_VAR_bucket_name="my-production-bucket"
Для секретов — паролей, токенов, ключей — используйте пометку sensitive:
variable "api_token" {
description = "Токен для доступа к API"
type = string
sensitive = true
}
Sensitive-переменные не отображаются в выводе plan и apply в открытом виде.
Выходные значения (output) передают информацию наружу — публичный IP машины, имя бакета, ID созданной сети:
output "vm_ip" {
description = "Публичный IP виртуальной машины"
value = yandex_compute_instance.web.network_interface.0.nat_ip_address
}
output "bucket_name" {
description = "Имя созданного бакета"
value = yandex_storage_bucket.data.bucket
}
Для промежуточных вычислений используйте locals:
locals {
instance_name = "${var.project_name}-web-${var.environment}"
common_tags = {
project = var.project_name
env = var.environment
managed_by = "terraform"
}
}
Защита API-ключей от утечки — задача, которую нужно решать на начальном этапе кодирования.
Состояние проекта и удалённое хранение
Файл состояния — самое ценное, что есть в проекте Terraform. Он содержит соответствие между описанием в конфиге и реальными объектами в облаке. Потеря состояния — потеря управления инфраструктурой.
Локальный файл terraform.tfstate подходит только для экспериментов. В командной работе нужен удалённый бэкенд.
Бэкенд хранит состояние в общем месте — объектном хранилище (S3, Yandex Object Storage, Google Cloud Storage) — и обеспечивает блокировку на время применения.
Настройка бэкенда для Yandex Object Storage:
terraform {
backend "s3" {
endpoint = "storage.yandexcloud.net"
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "ru-central1"
access_key = "ваш_access_key"
secret_key = "ваш_secret_key"
skip_region_validation = true
skip_credentials_validation = true
}
}
Для блокировки состояния используйте use_lockfile = true (Terraform 1.10+). При параллельных применениях один получит блокировку, остальные подождут.
Пять правил работы с состоянием:
- Никогда не редактируйте файл состояния вручную. Для правок есть команды
terraform stateиterraform import. - Не храните состояние в репозитории. Добавьте
*.tfstate*в.gitignore. - Шифруйте хранилище состояния — в нём лежат секреты в открытом виде.
- Ограничьте доступ к бэкенду. Только те, кто применяет изменения, должны иметь доступ.
- Регулярно делайте бэкапы состояния — в облачных хранилищах включите версионирование.
Чтобы подтянуть в управление ресурсы, созданные вручную, используйте terraform import. Современный способ — декларативный импорт через блок import {} (доступен в Terraform 1.5+ и OpenTofu 1.6+):
import {
to = yandex_compute_instance.existing
id = "идентификатор_виртуальной_машины"
}
Модули
Когда проект вырастает из одного файла, код становится нечитаемым. Модули помогают группировать ресурсы и переиспользовать их.
Структура модуля — три файла:
modules/vm/
├── main.tf # ресурсы модуля
├── variables.tf # входные переменные
└── outputs.tf # выходные значения
Подключение локального модуля:
module "web_vm" {
source = "./modules/vm"
vm_name = "web-server"
vm_cores = 2
vm_memory = 4
subnet_id = yandex_vpc_subnet.public.id
ssh_key = file("~/.ssh/id_rsa.pub")
}
Модуль из публичного реестра:
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
}
Четыре признака, что код пора выносить в модуль:
- один и тот же набор ресурсов повторяется в разных местах;
- конфигурация выросла до нескольких сотен строк и её сложно читать;
- вы хотите переиспользовать конфигурацию в другом проекте;
- в проекте работает несколько команд, и каждой нужна своя зона ответственности.
Организация окружений
Для разработки, тестирования и продакшена нужны отдельные контуры инфраструктуры. Есть два подхода, чтобы их развести.
Первый подход — рабочие пространства (workspaces). Один код, разные состояния для каждого окружения:
terraform workspace new dev
terraform workspace new prod
terraform workspace select dev
terraform apply
Рабочие пространства удобны для небольших проектов, но имеют ограничения: все окружения используют один бэкенд, и переключение между ними требует внимательности.
Второй подход — отдельные каталоги для каждого окружения:
terraform/
├── dev/
│ ├── main.tf
│ └── terraform.tfvars
├── stage/
│ ├── main.tf
│ └── terraform.tfvars
└── prod/
├── main.tf
└── terraform.tfvars
Каждый каталог имеет собственный бэкенд и состояние. Такой подход даёт больше контроля и изоляции.
Для продакшена чаще выбирают второй вариант. Он надёжнее, проще в аудите и не позволяет случайно применить изменения к продакшену, работая в dev-окружении.
Terraform в CI/CD
Ручной запуск terraform apply с ноутбука — источник проблем. В современной практике изменения в инфраструктуру проходят через пайплайн.
Порядок работы в CI/CD:
- Разработчик создаёт пул-реквест с изменениями в Terraform-конфигах.
- Пайплайн запускает проверки:
terraform fmt -check,terraform validate,terraform plan. - План публикуется в комментарии к пул-реквесту для ревью.
- После ревью и мержа в основную ветку пайплайн выполняет
terraform applyавтоматически. - Доступ к облаку выдаётся через короткоживущие токены — никаких ключей в переменных окружения пайплайна.
Блокировка состояния защищает от параллельных применений. Если два пайплайна запустятся одновременно, один получит блокировку, второй — ошибку и будет ждать.
Фрагмент конфигурации для GitHub Actions:
name: Terraform
on:
pull_request:
paths: ['terraform/**']
push:
branches: [main]
paths: ['terraform/**']
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.15.8
- name: Terraform Init
run: terraform init
working-directory: ./terraform
- name: Terraform Format
run: terraform fmt -check
working-directory: ./terraform
- name: Terraform Plan
run: terraform plan -out=tfplan
working-directory: ./terraform
if: github.event_name == 'pull_request'
- name: Terraform Apply
run: terraform apply tfplan
working-directory: ./terraform
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
Этапы и модели SDLC стоит изучить заранее.
Типичные ошибки новичков
Разберём восемь частых ошибок — по схеме «что сделали → что произошло → как правильно».
1. Применение без чтения плана
Что сделали: запустили terraform apply и сразу нажали yes.
Что произошло: случайно удалили продакшен-базу данных, потому что не заметили знак – перед важным ресурсом.
Как правильно: всегда читать план целиком. Для сложных проектов — выносить план в отдельный артефакт и согласовывать с командой.
2. Файл состояния в репозитории
Что сделали: закоммитили terraform.tfstate в Git.
Что произошло: секреты из состояния попали в историю репозитория, их пришлось срочно менять.
Как правильно: добавить *.tfstate* в .gitignore и использовать удалённый бэкенд.
3. Ручные правки ресурсов в панели облака
Что сделали: изменили размер диска вручную через консоль, не обновив Terraform-конфиг.
Что произошло: при следующем apply Terraform вернул диск к исходному размеру.
Как правильно: все изменения — только через Terraform. Если нужно что-то поменять — сначала меняем конфиг, потом применяем.
4. Секреты прямо в коде
Что сделали: написали password = “admin123” в main.tf.
Что произошло: пароль попал в репозиторий и в историю.
Как правильно: использовать переменные с sensitive = true и передавать значения через переменные окружения или защищённые хранилища.
5. Отсутствие закреплённых версий провайдеров
Что сделали: не указали версию провайдера в required_providers. Что произошло: через месяц провайдер обновился, и конфигурация перестала работать из-за breaking changes. Как правильно: всегда закреплять версии провайдеров.
6. Переименование ресурса
Что сделали: переименовали resource “yandex_compute_instance” “web” в “app”.
Что произошло: Terraform удалил старую машину и создал новую вместо того, чтобы переименовать.
Как правильно: использовать terraform state mv для переименования ресурса в состоянии, а потом менять имя в конфиге.
7. Выбор count там, где нужен for_each
Что сделали: для создания нескольких похожих ресурсов использовали count.
Что произошло: при удалении одного элемента из середины списка все последующие сдвинулись и пересоздались.
Как правильно: для множества ресурсов с уникальными ключами использовать for_each — он работает с map и не пересоздаёт ресурсы при изменении порядка.
8. Применение с локальным состоянием в командной работе
Что сделали: двое инженеров одновременно запустили terraform apply с локальным состоянием в одной директории.
Что произошло: состояние рассинхронизировалось, часть ресурсов потерялась из управления.
Как правильно: вынести состояние в удалённый бэкенд с блокировкой.
Чек-лист перед первым применением в проде
Девять пунктов, которые стоит проверить перед тем, как запускать Terraform в продакшене:
- Версии Terraform и провайдеров закреплены в
required_versionиrequired_providers. - Состояние вынесено в удалённый бэкенд с блокировкой.
- Доступ к хранилищу состояния ограничен — только нужные люди и сервисные аккаунты.
- Секреты передаются через переменные с пометкой
sensitiveи не лежат в коде. - План прочитан и согласован с командой (или проверен в пайплайне).
- Критичные ресурсы защищены от случайного удаления через
prevent_destroy. - Окружения разведены — dev/stage/prod работают изолированно.
- Все изменения проходят через пайплайн, а не с ноутбука.
- Проработан план отката — как вернуться к предыдущей версии инфраструктуры.
Частые вопросы
Чем Terraform отличается от Ansible?
Terraform создаёт и управляет ресурсами у провайдера — виртуальные машины, сети, базы данных. Ansible настраивает то, что уже создано — устанавливает ПО, копирует конфиги, разворачивает приложения. Они дополняют друг друга: Terraform поднимает инфраструктуру, а Ansible её настраивает.
Что выбрать в 2026 году: Terraform или OpenTofu?
В 2026 году оба инструмента — зрелые и production-ready. OpenTofu — форк Terraform под лицензией MPL, управляется Linux Foundation и имеет функции, которых пока нет в Terraform: нативное шифрование состояния и планов, for_each на провайдерах. Terraform остаётся самым распространённым инструментом и имеет более широкую экосистему.
Для большинства команд выбор сводится к лицензионным предпочтениям и доверию к вендору. OpenTofu даёт открытую лицензию и независимое управление, Terraform — привычный workflow и интеграцию с HCP Terraform. Конфиги на HCL работают на обоих инструментах без изменений.
Как поставить провайдер, если реестр недоступен?
Настройте зеркало реестра через файл .terraformrc (инструкция в разделе установки) или используйте провайдеры из собственных реестров российских облачных провайдеров.
Можно ли подхватить инфраструктуру, созданную руками?
Да, через terraform import. В современных версиях (Terraform 1.5+ и OpenTofu 1.6+) используйте декларативный импорт через блок import {}. Нужно знать идентификатор ресурса в облаке и иметь соответствующий resource блок в конфигурации.
Что будет, если удалить файл состояния?
Без состояния Terraform потеряет связь с реальными ресурсами. Сами ресурсы в облаке останутся, но управлять ими через Terraform станет невозможно. Восстановить состояние можно через terraform import для каждого ресурса по отдельности — долго и муторно. Поэтому состояние хранят в удалённом бэкенде с бэкапами.
Terraform для начинающих кажется сложным инструментом. На деле порог входа держится на трёх вещах: рабочем доступе к реестру провайдеров, привычке читать план и правильно вынесенном состоянии. Остальное наращивается по мере роста проекта.
Начните с малого — опишите одну виртуальную машину в конфиге, примените, посмотрите, что получилось, удалите. Потом добавьте сеть, группу безопасности, хранилище. Вынесите переменные. Переложите состояние в бэкенд. Соберите повторяющиеся части в модули. Подключите пайплайн.
Каждый следующий шаг делает инфраструктуру прозрачнее и надёжнее. А когда вся инфраструктура описана кодом, исчезает страх что-то сломать — откатиться всегда можно через Git. И помните — бэкенд-разработчику всегда есть куда расти.
Советуем дополнительно почитать
git pull и git fetch: что делает каждая команда — разница между двумя похожими командами, которая пригодится, когда несколько человек одновременно работают с одним Terraform-репозиторием.
Как клонировать репозиторий на GitHub: пошаговое руководство — первый шаг перед тем, как открывать main.tf: как забрать чужой проект с инфраструктурой к себе.
Что такое SSH и почему админы его любят — протокол, через который в примере статьи Terraform подключается к виртуальной машине по SSH-ключу.
Что такое End-to-End-тестирование: инструменты и примеры сквозного тестирования — как проверить не только план Terraform, но и то, что развёрнутая по нему инфраструктура действительно работает как задумано.
Деплой: что это такое и зачем он нужен — что происходит после terraform apply, когда инфраструктура готова принимать приложение.
Бонус для читателей
Если вам интересно погрузиться в мир IT и при этом немного сэкономить, держите наш промокод на курсы Практикума. Он даст вам скидку при оплате, поможет с льготной ипотекой или безлимитом на маркетплейсах. Ладно, окей, это просто скидка, без остального, но хорошая.
