linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
home/terraform/lessons/tf-beginner-01-hello-s3

lesson ── terraform-beginner ── ~12 мин ── 5 шагов

Hello, S3: первый ресурс в Terraform

Сейчас ты пройдёшь главный цикл Terraform за 10 минут: напишешь HCL для одного S3-бакета, проинициализируешь рабочую директорию, посмотришь план, применишь его, и проверишь что state знает про созданный ресурс.

Облако. LocalStack (см. localstack-provider). Никакого настоящего AWS, никаких счетов. Можно ломать, сносить, начинать заново.

▶ интерактивный sandbox

Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.

запустить sandbox →

stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Опиши S3-бакет в HCL

    В рабочей директории ~/tf-hello уже лежит файл provider.tf, настройки провайдера AWS, нацеленные на LocalStack (endpoints { ... }). Сейчас твоя задача, создать рядом файл main.tf с описанием одного S3-бакета.

    Создай файл ~/tf-hello/main.tf со следующим содержимым:

    hcl
    resource "aws_s3_bucket" "demo" {
      bucket = "linuxlab-hello-${random_id.suffix.hex}"
      tags = {
        Owner   = "student"
        Project = "terraform-hello"
      }
    }
    resource "random_id" "suffix" {
      byte_length = 4
    }

    Зачем random_id? S3-bucket-имена должны быть глобально уникальными. Даже в LocalStack мы соблюдаем эту дисциплину, чтобы не вырабатывать дурную привычку.

    О формате блоков resource "..." "..." { ... }, см. tf-resource-block и hcl-syntax.

    подсказка

    Можешь использовать `cat > main.tf <<EOF ... EOF` или редактор `nano main.tf`.

    ✓ HCL написан. Теперь Terraform нужно инициализировать.

  2. 02

    terraform init: скачать AWS-провайдер

    Команда init читает provider.tf и скачивает AWS-плагин из реестра Terraform. После неё появятся:

    • папка .terraform/, с плагином внутри.
    • файл .terraform.lock.hcl, с зафиксированной версией плагина.

    Без init другие команды не запустятся.

    Запусти:

    bash
    cd /home/student/tf-hello
    terraform init

    Подробнее про init и lockfile, tf-init и tf-lockfile.

    подсказка

    Не забудь `cd /home/student/tf-hello` перед `terraform init`.

    ✓ Провайдер AWS скачан, lockfile создан.

    Что внутри .terraform.lock.hcl

    Lockfile, гарантия воспроизводимости. Он фиксирует точную версию провайдера и его SHA-хеши. Если ты или коллега запустите init снова, Terraform скачает ровно эту версию. Если хеш не сошёлся, упадёт с ошибкой (защита от подмены пакета).

    • → Terraform lockfile
  3. 03

    terraform plan: посмотри, что будет создано

    plan сравнивает HCL и state. Сейчас state пустой, значит plan покажет «+ 2 to add»: один aws_s3_bucket и один random_id.

    Запусти:

    bash
    terraform plan

    Обрати внимание на строки с + resource, это создаваемые ресурсы. В конце, сводка вида Plan: 2 to add, 0 to change, 0 to destroy.

    Plan ничего не меняет в облаке. Можешь запустить сколько угодно раз. См. tf-plan.

    подсказка

    Если plan ругается «provider not initialized»: вернись и проверь что `init` прошёл.

    ✓ Plan показал план: 2 ресурса к созданию. Теперь применим.

  4. 04

    terraform apply: создай ресурс

    apply запускает план в реальном облаке. Сейчас «облако», это LocalStack: контейнер рядом, который притворяется AWS.

    Запусти с -auto-approve (без интерактивного «yes», это учебная задача):

    bash
    terraform apply -auto-approve

    После apply должны появиться строчки:

    random_id.suffix: Creation complete after Xs
    aws_s3_bucket.demo: Creation complete after Xs
    Apply complete! Resources: 2 added

    Если что-то упало, проверь, что LocalStack отвечает (init-скрипт wait-for-localstack.sh должен был дождаться его при старте сессии). См. tf-apply и localstack-provider.

    подсказка

    Если получаешь TLS-ошибку: это значит провайдер пытается ходить в настоящий AWS. Проверь что `provider.tf` содержит блок endpoints.

    ✓ Бакет создан в LocalStack. State обновился. Открой его и посмотри.

    То же самое на OpenTofu

    OpenTofu держит CLI и state совместимыми с Terraform по командам этого шага: миграция обычно проходит через mv .terraform .terraform.bak; tofu init -upgrade. Но при первом переходе сделай backup state и прогон на feature-branch - расхождения концентрируются в новых фичах (variables в backend, state-encryption, OCI registry-backed модули). См. tf-opentofu-parity для полной матрицы.

    • → OpenTofu parity
  5. 05

    Повторный plan: должен быть чистым

    Главное правило Terraform: после apply повторный plan должен показывать «No changes». Это инвариант. Если показывает изменения, значит, в state и в HCL расхождение, или drift.

    Запусти ещё раз:

    bash
    terraform plan -detailed-exitcode

    Флаг -detailed-exitcode важен: exit 0 = нет изменений, exit 2 = есть. Эта проверка пройдёт только если plan чистый.

    подсказка

    Если plan показывает изменения: посмотри `terraform show -json | jq` и сравни с HCL.

    ✓ Plan чистый: state и HCL совпадают. Terraform-инвариант соблюдён.

    Что такое drift

    Drift, это когда состояние в облаке отличается от того что Terraform записал в state. Бывает: кто-то руками удалил бакет через AWS console, auto-scaling сам подкрутил мощность. Terraform увидит drift при следующем plan/refresh. Стратегии работы с ним, в lifecycle.ignore_changes.

    • → Terraform state
    • → lifecycle блок

Что ты узнал

Ты увидел декларативный подход Terraform: описал желаемое состояние, и Terraform сам разобрался что создать. Узнал три обязательных команды (init, plan, apply) и понял что они делают.

команды

  • terraform initскачать провайдеры и создать lockfile
  • terraform planпоказать diff между HCL и state
  • terraform apply -auto-approveприменить план
  • terraform showраспечатать содержимое state

концепции

  • · HCL, это желаемое состояние, не последовательность команд
  • · init нужен один раз для проекта (и после изменения provider/backend)
  • · plan: безопасная команда, её можно запускать сколько угодно
  • · apply реально меняет облако и обновляет state

← предыдущий

Terragrunt, DRY между dev/stage/prod

следующий →

Troubleshooting Garden: распутай Cycle Error

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки