Как начать работать с Terraform: инфраструктура как код на практике

Один репозиторий для любого окружения

Как начать работать с Terraform: инфраструктура как код на практике

Инфраструктура в облаке — удобный и полезный инструмент. Кликнул пару раз в панели, создал виртуальную машину, настроил сеть, добавил группу безопасности — и всё заработало. Проблемы начинаются, когда нужно повторить эту же конфигурацию для тестового окружения. Или когда через месяц кто-то пытается понять, почему продакшен отличается от стейджинга. Или когда единственный человек, который помнит все ручные правки, уходит в отпуск.

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"
}

Значения переменным можно передавать разными способами. Приоритет источников (от высшего к низшему):

  1. флаг командной строки -var или -var-file;
  2. файл terraform.tfvars или terraform.tfvars.json;
  3. переменные окружения с префиксом TF_VAR_;
  4. значение по умолчанию в объявлении переменной.

Файл 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+). При параллельных применениях один получит блокировку, остальные подождут.

Пять правил работы с состоянием:

  1. Никогда не редактируйте файл состояния вручную. Для правок есть команды terraform state и terraform import.
  2. Не храните состояние в репозитории. Добавьте *.tfstate* в .gitignore.
  3. Шифруйте хранилище состояния — в нём лежат секреты в открытом виде.
  4. Ограничьте доступ к бэкенду. Только те, кто применяет изменения, должны иметь доступ.
  5. Регулярно делайте бэкапы состояния — в облачных хранилищах включите версионирование.

Чтобы подтянуть в управление ресурсы, созданные вручную, используйте 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:

  1. Разработчик создаёт пул-реквест с изменениями в Terraform-конфигах.
  2. Пайплайн запускает проверки: terraform fmt -check, terraform validate, terraform plan.
  3. План публикуется в комментарии к пул-реквесту для ревью.
  4. После ревью и мержа в основную ветку пайплайн выполняет terraform apply автоматически.
  5. Доступ к облаку выдаётся через короткоживущие токены — никаких ключей в переменных окружения пайплайна.

Блокировка состояния защищает от параллельных применений. Если два пайплайна запустятся одновременно, один получит блокировку, второй — ошибку и будет ждать. 

Фрагмент конфигурации для 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 в продакшене:

  1. Версии Terraform и провайдеров закреплены в required_version и required_providers.
  2. Состояние вынесено в удалённый бэкенд с блокировкой.
  3. Доступ к хранилищу состояния ограничен — только нужные люди и сервисные аккаунты.
  4. Секреты передаются через переменные с пометкой sensitive и не лежат в коде.
  5. План прочитан и согласован с командой (или проверен в пайплайне).
  6. Критичные ресурсы защищены от случайного удаления через prevent_destroy.
  7. Окружения разведены — dev/stage/prod работают изолированно.
  8. Все изменения проходят через пайплайн, а не с ноутбука.
  9. Проработан план отката — как вернуться к предыдущей версии инфраструктуры.

Частые вопросы

Чем 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 и при этом немного сэкономить, держите наш промокод на курсы Практикума. Он даст вам скидку при оплате, поможет с льготной ипотекой или безлимитом на маркетплейсах. Ладно, окей, это просто скидка, без остального, но хорошая.

Вам может быть интересно
medium
[anycomment]
Exit mobile version