# Зависимости ресурсов: явные и неявные _Ресурсы и data-источники · TerraformLab Knowledge Base_ **TL;DR:** Terraform автоматически вычисляет порядок создания ресурсов из ссылок в HCL (неявные зависимости). Когда такой ссылки нет, но порядок важен: есть depends_on. Использовать редко: чаще это сигнал что архитектура спорная. ## Как Terraform узнаёт порядок Когда вы пишете: ```hcl resource "aws_iam_role" "task" { name = "ecs-task-role" # ... } resource "aws_iam_role_policy" "task" { role = aws_iam_role.task.id # ← ссылка # ... } ``` Terraform видит ссылку `aws_iam_role.task.id` и понимает: «policy зависит от role». Создаёт сначала role, потом policy. Это называется **неявная зависимость (implicit dependency)**. Terraform вычислил её из HCL автоматически. Граф зависимостей строится для всего проекта. Все ресурсы без зависимостей друг от друга, создаются параллельно (по умолчанию до 10 одновременно). ## Когда `depends_on` нужен Иногда зависимость есть, но Terraform её не видит. Например: ```hcl resource "aws_iam_role_policy_attachment" "lambda_logs" { role = aws_iam_role.lambda.name policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" } resource "aws_lambda_function" "my_func" { function_name = "my-function" role = aws_iam_role.lambda.arn # ссылка на role, но НЕ на policy_attachment # Без depends_on Lambda может создаться раньше attachment'а # и при первом вызове упасть с access denied. depends_on = [aws_iam_role_policy_attachment.lambda_logs] } ``` Лямбда ссылается на role напрямую, но не на attachment. Terraform не знает, что лямбде нужны эти конкретные права для логов. Без `depends_on` Lambda может создаться раньше, чем permissions прикрепятся, и при первом запуске упадёт. ## Синтаксис `depends_on`, список адресов ресурсов: ```hcl depends_on = [ aws_iam_role_policy_attachment.lambda_logs, aws_iam_role_policy_attachment.lambda_sqs, ] ``` Адреса без `.id` или `.arn`, указываем сам ресурс целиком. Никаких атрибутов после имени. ## Можно ли в data? Да: ```hcl data "aws_iam_role" "existing" { name = "shared-role" depends_on = [aws_iam_role.shared] } ``` Это редкий случай, обычно data сразу читает то, что уже есть. Но если data зависит от ресурса, который должен быть создан Terraform'ом первым, depends_on помогает. ## Можно ли в module? Да: ```hcl module "app" { source = "./modules/app" # ... depends_on = [aws_iam_role.app_runtime] } ``` Применимо когда модуль использует ресурс через data, а не через input. ## Подводные камни - **`depends_on`. Это последняя инстанция.** Если можете выразить зависимость через ссылку, сделайте это. Ссылка точнее (Terraform понимает не только порядок, но и какой именно атрибут используется) и видна в plan'е. - **`depends_on` не передаёт значение.** Это только «порядок». Если нужен атрибут зависимости, используйте обычную ссылку. - **`depends_on` может скрывать архитектурный косяк.** Если без него ничего не работает, может быть, ваши ресурсы слишком связаны и стоит подумать о структуре. - **Слишком много depends_on = плохо.** 1-2 на проект, норма. 20, повод задуматься. Часто это означает, что внутри одного `apply` смешано слишком много несвязанных вещей. - **`depends_on` нельзя ссылаться на конкретный атрибут.** Только на ресурс целиком: `aws_iam_role.lambda`, не `aws_iam_role.lambda.arn`. Это не bug, это by design, depends_on про порядок, а не про значение. - **На сloud-side зависимости Terraform не повлияет.** Если AWS внутри себя создаёт ресурс асинхронно (например, IAM-роль 5-10 секунд «применяется» по всему региону). Terraform этого не видит. Считает, что роль готова, как только API вернул 200. Для лечения иногда добавляют `time_sleep` ресурс. ## Команды ```bash terraform graph ``` Выводит граф зависимостей в формате DOT. Можно отрендерить через graphviz: terraform graph | dot -Tsvg > graph.svg ```bash terraform plan ``` В выводе plan видно, в каком порядке Terraform будет создавать/менять ресурсы (по группам зависимостей). ## См. также - [Блок resource: главный кирпич Terraform](/terraform/kb/tf-resource-block.md) - [Ссылки в HCL: как читать aws_s3_bucket.demo.bucket](/terraform/kb/tf-references.md) - [terraform apply: применить план в реальном облаке](/terraform/kb/tf-apply.md)