lesson ── terraform-garden ── ~16 мин ── 4 шагов
Кто-то добавил два import-блока чтобы захватить существующие ресурсы и не плодить дубли. Но в облаке ресурсы лежат под одними именами, а import.id написан с опечатками: «logs» ↔ «loggs», «ci-role» ↔ «ci-role-old». Plan падает с «Cannot import non-existent remote object».
Найди оба несоответствия, поправь и докажи что план идёт без destroy.
интерактивный sandbox
Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.
stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя
cd /home/student/tf-garden
terraform init
terraform plan 2>&1 | tee /tmp/import.log
Должны вылезти две строки с ошибками вроде:
Error: Cannot import non-existent remote object
with aws_s3_bucket.logs,
on main.tf line ...
И аналогичная, для aws_iam_role.ci. Это значит: imported
ID garden-import-loggs / garden-ci-role-old в облаке отсутствуют.
✓ Обе ошибки видны. Теперь, что в облаке на самом деле.
aws --endpoint-url=http://localstack:4566 s3 ls | tee /tmp/s3.log
aws --endpoint-url=http://localstack:4566 iam list-roles \
--query 'Roles[].RoleName' --output text | tee /tmp/iam.log
Покажет:
garden-import-logs (без второго g).garden-ci-role (без -old).Это и есть твои настоящие id. Опечатка, в HCL, в облаке всё корректно.
✓ Реальные id найдены. Теперь поправь HCL.
Открой main.tf и замени строки:
import {to = aws_s3_bucket.logs
id = "garden-import-logs" # было: garden-import-loggs
}
и
import {to = aws_iam_role.ci
id = "garden-ci-role" # было: garden-ci-role-old
}
Один симметричный способ через sed:
sed -i 's/garden-import-loggs/garden-import-logs/' main.tf
sed -i 's/garden-ci-role-old/garden-ci-role/' main.tf
Опечатка в S3, лишняя g. В IAM, лишний суффикс -old.
✓ Опечатки убраны. Проверим plan.
terraform plan -out=plan.tfplan
terraform show plan.tfplan | head -40
В плане должны появиться строки:
# aws_s3_bucket.logs will be imported
# aws_iam_role.ci will be imported
Никаких # ... will be destroyed быть не должно. Если есть destroy
это значит HCL описывает ресурс по-другому, и провайдер хочет
пересоздать. В нашем случае HCL совпадает с облаком, должен быть
чистый import.
Apply (опционально):
terraform apply plan.tfplan
✓ Bucket и role в state, без destroy. Import-блок отработал.
OpenTofu умеет import-блоки начиная с 1.6. Поведение и сообщения
идентичны. Единственное расхождение, -generate-config-out
стабильнее в OT, потому что они быстрее залатали несколько ранних
багов с unicode-именами. См. tf-opentofu-parity.
Import захватывает то, что указано в id. Если id не существует провайдер возвращает 404, terraform ругается «non-existent remote object». Лекарство, проверить id руками через провайдер CLI (aws s3 ls, aws iam list-roles), а лучше, закодить guard через data-source.
команды
aws --endpoint-url=http://localstack:4566 s3 lsпроверь имена S3-bucket перед importaws --endpoint-url=http://localstack:4566 iam list-roles --query 'Roles[].RoleName'проверь имена IAM-ролейterraform plan -generate-config-out=imported.tfсгенерировать HCL для импортируемого ресурса (TF 1.5+)концепции