Understanding Explicit Dependencies between Resources or modules in Terraform
Tags: terraform, ec2, cloud9, cli
Published: 2023-01-21 00:32:47

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](https://github.com/awsmine/Terraform_projects)** 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](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami).***

***[data source for pulling in an AMI ID](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance).***

***[sqs queue](https://registry.terraform.io/modules/terraform-aws-modules/sqs/aws/latest).***



# Steps for implementation to this project:

## 1. Create infrastructure for Explicit dependencies

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




![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/heazy6nl5egxqecjg8gv.png)





- 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}"
}

```
- 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nl1gete79xlqdanu5866.png)



- Run ***`terraform apply`*** to apply the configuration and type ***`yes`*** when prompted. 

- The output will be similar to the following.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0q7f8ezxw979sgk65m6u.png)


***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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/137cadj6jqjnwevq0frt.png)


# 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.