Как Terraform узнаёт порядок
Когда вы пишете:
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 её не видит. Например:
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, список адресов ресурсов:
depends_on = [
aws_iam_role_policy_attachment.lambda_logs,
aws_iam_role_policy_attachment.lambda_sqs,
]
Адреса без .id или .arn, указываем сам ресурс целиком. Никаких атрибутов после имени.
Можно ли в data?
Да:
data "aws_iam_role" "existing" {name = "shared-role"
depends_on = [aws_iam_role.shared]
}
Это редкий случай, обычно data сразу читает то, что уже есть. Но если data зависит от ресурса, который должен быть создан Terraform'ом первым, depends_on помогает.
Можно ли в module?
Да:
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ресурс.