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-garden-05-rotten-module

lesson ── terraform-garden ── ~20 мин ── 4 шагов

Troubleshooting Garden: модуль протух, провайдер обновился

Root-модуль обновили до AWS provider v5. Child-модуль legacy-bucket/ написан в стиле v3, acl, versioning {}, server_side_encryption_* внутри ресурса aws_s3_bucket. В v4 эти inline-блоки удалили: всё превратилось в отдельные ресурсы.

terraform init свалится с конфликтом version-constraints (>= 3.0, < 4.0 и ~> 5.0, несовместимы). Даже если разрешишь, plan упадёт на inline-блоках.

Реши: либо переписать модуль в современный стиль, либо явно зафиксировать старый провайдер для модуля. Правильный путь, первый.

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

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

запустить sandbox →

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

Шаги

  1. 01

    Запусти init, поймай конфликт версий

    bash
    cd /home/student/tf-garden
    terraform init 2>&1 | tee /tmp/init.log

    В логе будет сообщение типа:

    Error: Failed to query available provider packages
    ...
    no available releases match the given constraints
    >= 3.0, < 4.0, ~> 5.0

    Root просит v5, child, v3. Эти диапазоны не пересекаются.

    ✓ Конфликт виден. Теперь, модернизация модуля.

  2. 02

    Разрешим current AWS-provider в модуле

    Замени версионный диапазон в модуле, пусть принимает v5+:

    bash
    sed -i 's|version = ">= 3.0, < 4.0"|version = ">= 5.0"|' modules/legacy-bucket/main.tf

    После, init должен пройти:

    bash
    terraform init -upgrade 2>&1 | tee /tmp/init2.log

    Но plan всё равно упадёт, inline-блоки acl, versioning {}, server_side_encryption_* в v5 не существуют.

    ✓ Version-constraint обновлён. init проходит, но HCL ещё legacy.

  3. 03

    Перепиши модуль под provider v5

    Замени содержимое modules/legacy-bucket/main.tf на современный стиль:

    bash
    cat > modules/legacy-bucket/main.tf <<'EOF'
    terraform {
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = ">= 5.0"
        }
      }
    }
    variable "name" {
      type = string
    }
    resource "aws_s3_bucket" "this" {
      bucket = var.name
    }
    resource "aws_s3_bucket_ownership_controls" "this" {
      bucket = aws_s3_bucket.this.id
      rule {
        object_ownership = "BucketOwnerEnforced"
      }
    }
    resource "aws_s3_bucket_versioning" "this" {
      bucket = aws_s3_bucket.this.id
      versioning_configuration {
        status = "Enabled"
      }
    }
    resource "aws_s3_bucket_server_side_encryption_configuration" "this" {
      bucket = aws_s3_bucket.this.id
      rule {
        apply_server_side_encryption_by_default {
          sse_algorithm = "AES256"
        }
      }
    }
    output "arn" {
      value = aws_s3_bucket.this.arn
    }
    EOF

    Главное отличие: вместо acl = "private", aws_s3_bucket_ownership_controls с BucketOwnerEnforced (в v4+ ACL'и официально deprecated). versioning и encryption, отдельные ресурсы.

    Подробнее про разнесение, tf-refactor-patterns и tf-resource-block.

    подсказка

    Если оставишь хотя бы один inline-блок (versioning {} внутри aws_s3_bucket), плана не будет. v5 их не принимает совсем.

    ✓ Модуль переписан под v5. Теперь, plan.

  4. 04

    Plan и apply: модуль работает

    bash
    cd /home/student/tf-garden
    terraform init -upgrade
    terraform plan -out=plan.tfplan
    terraform apply plan.tfplan

    Plan должен показать «Plan: 4 to add» (бакет + ownership + versioning

    • encryption). Apply пройдёт без ошибок, бакет будет в state с адресом module.logs.aws_s3_bucket.this.

    ✓ Модуль модернизирован, ресурсы в state. Pipeline зелёный.

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

    OpenTofu тоже поддерживает AWS provider v5, фактически это тот же бинарь от HashiCorp под другой лицензией не пересобирается, они переиспользуют официальные релизы провайдеров. Поэтому миграция этого модуля валидна как для terraform 1.9, так и для tofu 1.8+. См. tf-opentofu-parity для полного списка различий.

    • → Паттерны рефакторинга
    • → Версионирование модулей
    • → OpenTofu parity

Что ты узнал

Major-version провайдера ломает inline-конфиги ресурсов: aws_s3_bucket в v4+, это голый бакет, всё остальное (acl, versioning, encryption, lifecycle, public access block), отдельные ресурсы. Это паттерн на весь провайдер, не разовая поломка.

команды

  • terraform init -upgradeперечитать модули и провайдеры; нужно после изменения version в required_providers
  • terraform providersпосмотреть какие провайдеры запрошены и из каких файлов
  • terraform state replace-provider OLD NEWсменить провайдера у существующих ресурсов в state без destroy

концепции

  • · Inline-конфиги ресурсов, v3 паттерн; v4+ требует разнесения по ресурсам
  • · Version-constraint в child-модуле должен учитывать root'овую версию провайдера
  • · Когда модуль legacy, либо обновлять, либо документировать pin и срок жизни

← предыдущий

Update: меняем атрибут, видим diff

следующий →

templatefile: рендерим конфиги из HCL

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