All Products
Search
Document Center

Terraform:depends_on

Last Updated:Apr 10, 2025

This topic describes the scenarios and processing mechanism of the depends_on argument and provides examples on how to use this argument in Alibaba Cloud environments.

Overview

depends_on is a meta-argument of Terraform. It is used to declare the dependencies between resources or modules and process implicit resources or module dependencies that cannot be automatically inferred by Terraform .

In Terraform workflows, most dependencies are automatically inferred as implicit references. In this case, the attribute value of a resource is the attribute of another resource. However, some dependencies cannot be automatically detected by Terraform. Explicit dependencies are required only when a resource or module depends on another resource but no attributes about the resource are specified in the parameters. For example, the feature of a resource depends on the complete creation of another resource or module. However, the resource or module is not directly referenced in the code. In this case, the depends_on argument is required.

This topic describes the scenarios and processing mechanism of the depends_on argument and provides examples on how to use this argument in Alibaba Cloud environments. The depends_on argument, when properly used, can ensure that resources are created and destroyed in a specific order, preventing deployment issues caused by ambiguous dependencies.

Usage notes

The depends_on meta-argument configures Terraform to complete all operations on the dependency object, including the read and write operations, before Terraform declares the dependency object. If the dependency object is an entire module, depends_on affect the order in which Terraform processes the resources and data sources associated with the module.

Use depends_on as the last resort because it may cause Terraform to create more conservative plans which replace more resources than necessary. For example, Terraform may consider more values known after apply when Terraform cannot be certain about the changes to the upstream object. This situation is highly possible when your module uses depends_on.

We recommend that you use expressions to reference implicit dependencies, instead of using depends_on. Expressions directly inform Terraform the source value of the reference. As long as this value remains unchanged, Terraform does not change plans even if changes are made to other parts of the upstream object.

Usage

You can use the depends_on meta-argument in a module block and all resources, regardless of the resource type. This argument requires a reference list of other resources or child modules in the same module. This list cannot contain expressions. This is because Terraform must be certain about the value of depends_on before Terraform learns about the resource relationships and before Terraform learns the security assessment expression.

We recommend that you retain a comment to explain why depends_on must be used.

Examples on dependencies between resources

In the following example, depends_on is used to process the additional implicit dependency added to the Resource Access Management (RAM) role policy:

# Create a RAM role.
resource "alicloud_ram_role" "example" {
  name        = "terraform-example"
  description = "Example role for demonstrating depends_on"
  document    = <<EOF
  {
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Effect": "Allow",
        "Principal": {
          "Service": [
            "ecs.aliyuncs.com"
          ]
        }
      }
    ],
    "Version": "1"
  }
  EOF
}

# Attach a system policy to the RAM role.
resource "alicloud_ram_role_policy_attachment" "system_policy" {
  policy_name = "AliyunOSSReadOnlyAccess"
  policy_type = "System"
  role_name   = alicloud_ram_role.example.name
}

# Create a custom policy.
resource "alicloud_ram_policy" "custom_policy" {
  policy_name     = "example-custom-policy"
  description     = "Custom policy for OSS access"
  policy_document = <<EOF
  {
    "Statement": [
      {
        "Action": "oss:GetObject",
        "Effect": "Allow",
        "Resource": "acs:oss:*:*:example-bucket/*"
      }
    ],
    "Version": "1"
  }
  EOF
}

# Attach the custom policy to the RAM role.
resource "alicloud_ram_role_policy_attachment" "custom_policy_attachment" {
  policy_name = alicloud_ram_policy.custom_policy.name
  policy_type = "Custom"
  role_name   = alicloud_ram_role.example.name
}

# Create an Elastic Compute Service (ECS) instance.
resource "alicloud_instance" "example" {
  instance_name   = "tf-example"
  instance_type   = "ecs.s6-c1m2.small"
  image_id        = "aliyun_2_1903_x64_20G_alibase_20230523.vhd"
  vswitch_id      = "vsw-abc123456"

  # Terraform can infer the dependency between the ECS instance and the RAM role.
  role_name = alicloud_ram_role.example.name
  
  # However, if you need to run software on the ECS instance, you must obtain the required RAM role.
  # For example, the ECS instance needs to read startup configurations from Object Storage Service (OSS). In this case, the ECS instance uses implicit dependency on the RAM policy. 
  # Terraform does not automatically infer the dependency. Therefore, you must declare an explicit dependency, such as:
  depends_on = [
    alicloud_ram_role_policy_attachment.system_policy,
    alicloud_ram_role_policy_attachment.custom_policy_attachment
  ]
}

Examples on dependencies between modules

If the features of a module depend on the complete deployment of another module, but the output is not directly referenced:

# Deploy a basic network module.
module "network" {
  source = "./modules/network"
  
  vpc_cidr = "10.0.0.0/16"
  # Other parameters.
}

# Deploy a security module.
module "security_groups" {
  source = "./modules/security_groups"
  
  vpc_id = module.network.vpc_id
  # Terraform can infer this dependency because the output from the network module is referenced.
}

# Deploy an application module.
module "application" {
  source = "./modules/application"
  
  subnet_ids = module.network.subnet_ids
  sg_id      = module.security_groups.app_sg_id
  
  # If the deployment of applications requires complete initialization of a specific database, 
  # but no outputs of the database block are directly referenced, you must specify an explicit dependency.
  depends_on = [
    module.database
  ]
}

# Deploy a database module.
module "database" {
  source = "./modules/database"
  
  subnet_ids = module.network.database_subnet_ids
  sg_id      = module.security_groups.db_sg_id
}

Proper use of the depends_on argument ensures that resources are created in the correct order, even if the dependencies between the resources are not obvious. We strongly recommend that you preferentially use direct references to build dependencies. Use depends_on only when necessary.

This topic is developed based on the Terraform document The depends_on Meta-Argument. You can read the Terraform document for more details.