DEV Community

Revathi Joshi for AWS Community Builders

Posted on

Understanding Explicit Dependencies between Resources or modules in Terraform

In this article, I am going to show you how the explicit dependencies affect the behavior and order of different resources and modules created and destroyed based on their configurations. For this, you will need to define explicit dependencies between the resources and modules, using depends_on argument.

Please visit my GitHub Repository for Terraform articles on various topics being updated on constant basis.

Let’s get started!

Objectives:

1. Create infrastructure for Explicit dependencies

2. Delete (Destroy) your infrastructure

Pre-requisites:

  • AWS user account with admin access, not a root account.
  • Cloud9 IDE with AWS CLI.

Resources Used:

I have used a data source for pulling in an AMI ID instead of a hard-coded value for creating an EC2 Instance. I have used Terraform documentation for this purpose.

Terraform documentation for AMI.

data source for pulling in an AMI ID.

sqs queue.

Steps for implementation to this project:

1. Create infrastructure for Explicit dependencies

  • Let’s create the following organizational structure as shown below.

Image description

  • Explicit dependencies between resources are not visible to Terraform.

  • However, the depends_on argument is accepted by any resource or module block and accepts a list of resources to create explicit dependencies for.

  • In the following example, we will create an infrastruction with an application running on an ec2 instance "ec2_1" which depends_on an aws s3 bucket "rev_123456".

  • We will also create a sqs queue "ec2_1_sqs_queue" which depends_on aws s3 bucket "rev_123456" and an ec2 instance "ec2_1" creation.

This dependency is configured inside the application, and thus not visible to Terraform.

You can use depends_on to explicitly declare the dependency.

  • You can also specify multiple resources in the depends_on argument, and Terraform will wait until all of them have been created before creating the target resource.

  • But by adding explicit dependencies, it will increase the length of time it takes for Terraform to create your infrastructure.

  • Create a main.tf file. This will deploy 1 Linux EC2 instances "ec2_1" with a security group "ec2_sg", 1 s3 bucket "rev_123456" and a sqs module "ec2_1_sqs_queue".

# PROVIDERS BLOCK
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.23"
    }
  }
  required_version = ">= 1.2.0"
}

provider "aws" {
  region  = var.aws_region
}


resource "aws_s3_bucket" "rev_123456" { }


# EC2 BLOCK
data "aws_ami" "linux" {
   most_recent = true
   owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}


# SECURITY BLOCK 
resource "aws_security_group" "ec2_sg" {
   name        = "ec2_sg"
   description = "allow inbound HTTP traffic"

   # HTTP from vpc
   ingress {
      from_port   = 80
      to_port     = 80
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]     
   }

  # outbound rules
  # internet access to anywhere
  egress {
     from_port   = 0
     to_port     = 0
     protocol    = "-1"
     cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
     name = "ec2_sg"
  }
}


resource "aws_instance" "ec2_1" {
  ami                = data.aws_ami.linux.id
  instance_type      = "t2.micro"
  vpc_security_group_ids = [aws_security_group.ec2_sg.id]

  depends_on = [aws_s3_bucket.rev_123456]

  tags = {
    Name = "ec2_1"
  }
}


module "ec2_1_sqs_queue" {
  source  = "terraform-aws-modules/sqs/aws"
  version = "= 4.0"

  depends_on = [aws_s3_bucket.rev_123456, aws_instance.ec2_1]
}


# VARIABLES BLOCK
variable "aws_region" {
  description = "AWS region for all resources."
  type        = string
  default     = "us-east-1"
}



# OUTPUTS BLOCK
output "instance_id_1" {
  value = aws_instance.ec2_1.id
}

output "s3_bucket_id" {
  value = aws_s3_bucket.rev_123456.id
}

output "s3_bucket_name" {
  value = "${aws_s3_bucket.rev_123456.arn}"
}

Enter fullscreen mode Exit fullscreen mode
  • This configuration includes a new module, terraform-aws-modules/sqs/aws.

  • Modules must be installed before Terraform can use them.

  • Run terraform get to install the module.

Image description

  • Run terraform apply to apply the configuration and type yes when prompted.

  • The output will be similar to the following.

Image description

Since both the ec2 instance "ec2_1" and the SQS Queue Module "ec2_1_sqs_queue" are dependent upon the s3 bucket "rev_123456", Terraform waits until the bucket is created to begin creating the other two resources.

2. Delete (Destroy) your infrastructure

  • Explicit dependencies affect the order in which resources are destroyed as well as created.

  • Run terraform destroy to destroy your infrastructure. Accept the changes by typing yes when prompted.

  • Wait for 4-5 minutes to destroy your resources.

See that the SQS Queue Module "ec2_1_sqs_queue", and the ec2 instance "ec2_1" are destroyed before the resources they depend on are, i.e the s3 bucket "rev_123456".

  • The output will be similar to the following.

Image description

What we have done so far

  • We have successfully demonstrated how the explicit dependencies affect the behavior and order of different resources created and destroyed based on their configurations.

Top comments (0)