Xtigyro
Xtigyro

Reputation: 411

Define Module Dependencies in Terraform

How can we ensure that the first module “frontend_1” is executed before the rest?

module "frontend_1" {
  source = "/modules/frontend-app"
}
module "frontend_2" {
  source = "/modules/frontend-app"
}
module "frontend_3" {
  source = "/modules/frontend-app"
}

Also - there're a couple of recorded Gitissues re this problem but a good workaround has not been presented in any of them. As a start - you can check this one so that you can get familiar with the essence of my question - https://github.com/hashicorp/terraform/issues/10462

And how to make an external for a module resource be built before the module gets executed - so that the "count" can be computed if it depends on a value which is calculated from such an external resource? For example - if you need to use the ID of a newly created VPC in the "count" in a module which creates multiple AWS Security Groups within that VPC?

Upvotes: 10

Views: 17693

Answers (2)

Kishor Unnikrishnan
Kishor Unnikrishnan

Reputation: 2579

As mentioned in the question, I was able to make a workaround for you using the depends on variable.

Refer to this for Terraform dependencies.

Assume we have 2 modules, one which defines the vpc and subnets, the second to define the various range of security groups to be used in the Infrastructure.

Since we have the dependency such that all security groups are to be made only after the successful creation of vpc in the VPC module, it can be met by the following strategy.

variable "vpc_arn" {
   description = "The ARN of the VPC which is created in the VPC module"
}

resource "null_resource" "vpc_found" {
  triggers = {
    vpc_name = "${var.vpc_arn}"
  }
}

resource "aws_security_group" "allow_all" {

  depends_on = ["null_resource.vpc_found"]

  name        = "allow_all"
  description = "Allow all inbound traffic"
  vpc_id      = "${var.vpc_arn}"
  ......
}

Refer to this for null resources.

Upvotes: 11

Modules are not a bundle of resources that are all created or all destroyed as a single unit, so there is no sense in which one module is run before or after another. If you look at the output of terraform graph, you'll see that the individual resources within a module appear as nodes in the plan graph which the execution engine traverses concurrently. This means that it's entirely possible to have bidirectional dependence between two modules (module A takes inputs from module B output, and also provides outputs which are used for module B input), as long as the plan graph does not contain a cycle.

One thing to observe with Terraform is that the plan graph is constructed by looking at which resource attributes, variables, inputs outputs, etc depend on which other ones via interpolation, in combination with any explicitly declared dependencies using depends_on (which is not available for modules). The consequence of this for your above example is that if there are no interpolation references which link values from the output of one module to the input of another, then there can be no paths constructed in the plan graph which indicate any dependency between the resources.

Upvotes: 7

Related Questions