linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Knowledge base
  • Cheat sheet
  • Capstone
  • Interview prep
home/terraform/kb/Resources & data sources/tf-depends-on

kb/resources ── Resources & data sources ── beginner

Resource dependencies: explicit and implicit

Terraform automatically computes the creation order of resources from references in HCL (implicit dependencies). When no such reference exists but order matters, use depends_on. Use it rarely; it is usually a signal that the architecture needs reconsideration.

view as markdown

How Terraform determines order

When you write:

hcl
resource "aws_iam_role" "task" {
  name = "ecs-task-role"
  # ...
}
resource "aws_iam_role_policy" "task" {
  role = aws_iam_role.task.id   # ← reference
  # ...
}

Terraform sees the reference aws_iam_role.task.id and concludes that the policy depends on the role. It creates the role first, then the policy. This is called an implicit dependency. Terraform derived it from HCL automatically.

The dependency graph is built for the entire project. Resources that have no dependency on each other are created in parallel (up to 10 at a time by default).

When depends_on is needed

Sometimes a dependency exists but Terraform cannot see it. For example:

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   # reference to role, but NOT to policy_attachment
  # Without depends_on, Lambda can be created before the attachment
  # and fail with access denied on the first invocation.
  depends_on = [aws_iam_role_policy_attachment.lambda_logs]
}

The Lambda references the role directly, not the attachment. Terraform has no way to know that Lambda needs those specific log permissions. Without depends_on, Lambda can be created before the permissions are attached and will fail on first execution.

Syntax

depends_on takes a list of resource addresses:

hcl
depends_on = [
  aws_iam_role_policy_attachment.lambda_logs,
  aws_iam_role_policy_attachment.lambda_sqs,
]

Addresses have no .id or .arn suffix; you reference the resource itself. No attributes after the name.

Can you use it in a data source?

Yes:

hcl
data "aws_iam_role" "existing" {
  name = "shared-role"
  depends_on = [aws_iam_role.shared]
}

This is rare; a data source normally reads what already exists. But if a data source depends on a resource that Terraform must create first, depends_on helps.

Can you use it in a module?

Yes:

hcl
module "app" {
  source = "./modules/app"
  # ...
  depends_on = [aws_iam_role.app_runtime]
}

This applies when a module consumes a resource through a data source rather than through an input variable.

Pitfalls

  • depends_on is the last resort. If you can express the dependency through a reference, do that. A reference is more precise (Terraform understands not just the order but which attribute is used) and it shows up in the plan output.

  • depends_on does not pass a value. It controls order only. If you need an attribute from a dependency, use a regular reference.

  • depends_on can hide an architectural problem. If nothing works without it, your resources may be too tightly coupled and the structure is worth revisiting.

  • Too many depends_on entries are a warning sign. One or two per project is normal. Twenty is a reason to pause. It often means too many unrelated things are bundled inside one apply.

  • depends_on cannot reference a specific attribute. Only the whole resource: aws_iam_role.lambda, not aws_iam_role.lambda.arn. This is by design; depends_on is about order, not about values.

  • Terraform cannot influence cloud-side async behavior. If AWS creates a resource asynchronously internally (for example, an IAM role can take 5-10 seconds to propagate across a region), Terraform does not see that. It considers the role ready as soon as the API returns 200. A time_sleep resource is sometimes added to work around this.

§ команды

bash
terraform graph

Prints the dependency graph in DOT format. You can render it with graphviz: terraform graph | dot -Tsvg > graph.svg

bash
terraform plan

The plan output shows the order in which Terraform will create or modify resources (grouped by dependency).

§ см. также

  • tf-resource-blockResource block: the main building block of TerraformA resource block tells Terraform "create this thing in the cloud." It has three parts: the resource type (what it is), the name (how you refer to it internally), and the arguments (how to configure it). Writing these blocks is what you spend 90% of your time doing in Terraform.
  • tf-referencesReferences in HCL: how to read aws_s3_bucket.demo.bucketAny value in HCL is reachable through an address: var.x, local.x, aws_s3_bucket.demo.arn, module.net.vpc_id, data.aws_region.current.name. Knowing this syntax is half of your productivity in Terraform.
  • tf-applyterraform apply: apply a plan to a real cloudapply takes the result of plan and actually calls the cloud API: it creates, changes, and deletes resources. After apply, the state is updated. This is the command that turns money into infrastructure.
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies