How to make terraform modules wait for resources to be created instead of using any computed values?

663    Asked by DelbertRauch in Salesforce , Asked on Sep 12, 2023

 I am trying to build several custom Terraform modules. I want to know how to work around dependencies within modules. But we cannot declare a module dependent on each other. Here is the code: 

# ROOT level main.tf
# -------------------------------------------------------------------
# Create NAT Gateway - Associates EIP as well
# -------------------------------------------------------------------
module "vpc_nat_gateway" {
  source = "./vpc_nat_gateway"
  vpc_id = "${ module.vpc.id }"
  public_subnet_ids = "${ module.vpc_subnets.public_subnet_ids }"
  private_cidr = "${ var.private_cidr }"
  common_tags = "${ local.common_tags }"
}
# -------------------------------------------------------------------
# Create Private Routes
# -------------------------------------------------------------------
module "vpc_private_route" {
  source = "./vpc_private_route"
  vpc_id. = "${ module.vpc.id }"
  nat_gateway_id = "${ module.vpc_nat_gateway.nat_gateway_id }"
  common_tags = "${ local.common_tags }"
}
# vpc_private_route module - main. tf
data "aws_nat_gateway" "az1" {
  vpc_id = "${ var.vpc_id }"
  tags {
    Name = "*NAT GW AZ 1"
  }
}
data "aws_nat_gateway" "az2" {
  vpc_id = "${ var.vpc_id }"
  tags {
    Name = "*NAT GW AZ 2"
  }
}
The result is: 
------ SNIP -----
module.vpc_nat_gateway.aws_nat_gateway.nat[1]: Creation complete after 1m50s (ID: nat-02a7f4279cec3a6c8)
module.vpc_nat_gateway.aws_nat_gateway.nat.0: Still creating... (2m0s elapsed)
module.vpc_nat_gateway.aws_nat_gateway.nat[0]: Creation complete after 2m0s (ID: nat-0695a12d9c0305e4c)
    Error: Error applying plan:
    3 error(s) occurred:
    * module.vpc_private_route.data.aws_subnet_ids.private: data.aws_subnet_ids.private: no matching subnet found for vpc with id vpc-0b530d1885e74067b
    * module.vpc_private_route.data.aws_nat_gateway.az2: data.aws_nat_gateway.az2: no matching NAT gateway found: {
    Filter: [{
        Name: "vpc-id",
        Values: ["vpc-0b530d1885e74067b"]
        },{
        Name: "tag:Name",
        Values: ["*NAT GW AZ 2"]
        }]
    }
    * module.vpc_private_route.data.aws_nat_gateway.az1: data.aws_nat_gateway.az1: no matching NAT gateway found: {
    Filter: [{
        Name: "vpc-id",
        Values: ["vpc-0b530d1885e74067b"]
        },{
        Name: "tag:Name",
        Values: ["*NAT GW AZ 1"]
        }]
    }

The Terraform output shows the files are perfect. The execution of a subsequent Terraform application runs without any issue. What should I do to cause the TF module to wait for resource creation before going for the resource? 

Answered by Diana Campbell

Since depends_on is called a protected variable, it is not used in any module. You can also find out the syntax differences in the codes below:

# ROOT level main.tf
# -------------------------------------------------------------------
# Create NAT Gateway - Associates EIP as well
# -------------------------------------------------------------------
module "vpc_nat_gateway" {
  source = "./vpc_nat_gateway"
  vpc_id = module.vpc.id
  public_subnet_ids = module.vpc_subnets.public_subnet_ids
  private_cidr = var.private_cidr
  common_tags = local.common_tags
}
# -------------------------------------------------------------------
# Create Private Routes
# -------------------------------------------------------------------
module "vpc_private_route" {
  source = "./vpc_private_route"
  vpc_id. = module.vpc.id
  nat_gateway_id = module.vpc_nat_gateway.nat_gateway_id
  common_tags = local.common_tags
  # Depends is a custom variable, depends_on is a reserved keyword.
  depends = [module.vpc_nat_gateway.nat_gateway_id]
}
# vpc_private_route module - main.tf
variable "depends" {
  default = []
}
resource "null_resource" "depends_on" {
  triggers = {
    depends_on = "${join("", var.depends)}"
  }
}
data "aws_nat_gateway" "az1" {
  vpc_id = var.vpc_id
  depends_on = [
    null_resource.depends_on
  ]
}
data "aws_nat_gateway" "az2" {
  vpc_id = var.vpc_id
  depends_on = [
    null_resource.depends_on
  ]
}

You need to follow a complicated method for Terraform to wait for resources or to get Terraform to do any module dependencies. You can follow the code below to force the module to become aware of the calling from Terraform.



Your Answer

Answer (1)

In Terraform, when you're using modules that create resources, you might encounter situations where you need to wait for those resources to be fully created before proceeding with further actions. Terraform provides a mechanism to handle this using the depends_on meta-argument within your module.

Here's how you can make Terraform modules wait for resources to be created:

Using depends_on: The depends_on meta-argument allows you to specify dependencies between resources. By specifying dependencies, Terraform ensures that resources are created in the correct order, and it waits for the specified dependencies to be created before proceeding. You can use depends_on within your module to define dependencies between resources.

Example:

  resource "aws_instance" "example" {  # Configuration for the AWS EC2 instance}resource "aws_security_group" "example_sg" {  # Configuration for the AWS security group}# Define dependency of the security group on the EC2 instance# This ensures that the security group is created only after the EC2 instance is created# Note: This code should be within the same module where the resources are defineddepends_on = [aws_instance.example]

Using Provisioners: If you need to wait for specific conditions before proceeding, you can also use provisioners like local-exec or remote-exec to execute arbitrary commands on the local machine or the remote resource. You can use this approach to wait for certain conditions to be met before proceeding.

Example:

  resource "aws_instance" "example" {  # Configuration for the AWS EC2 instance  provisioner "local-exec" {    command = "echo 'Instance is up and running'"  }}

By using these techniques, you can ensure that Terraform modules wait for resources to be fully created before proceeding with further actions. However, keep in mind that relying too heavily on dependencies or waiting mechanisms can lead to longer execution times and potentially less predictable behavior, so use them judiciously.








5 Months

Interviews

Parent Categories