skip to Main Content

I’m setting up terraform modules to create my AWS resources, i need to create muliple resouces from same module templates. Created 2 sg with for_each in main.tf, and need to pass them to another module to create 2 ec2 instances and map its values.

main.tf

module "sg" {
  for_each = toset(var.Name)
  source       = "./modules/ec2_sg"
  App_Name     = "${each.value}"
}

module "ec2" {
  count         = length(var.Name)
  depends_on = [
    module.sg
  ]
  source = "./modules/ec2"

  Name          = var.Name[count.index]
  EC2_SG_ID     = module.sg.sg_id

security group output.tf

output "sg_id" {
  value = aws_security_group.sg.*.id
}

This will only work in the case of single resource.Two resouce names are passed as list of string in terraform.tfvars.I need to pass multiple values to the ec2 module and need to map 1st sg to the 1st ec2 instance and 2nd one to the 2nd ec2 intance.

2

Answers


  1. You can’t use depends_on = [module.sg] in your main.tf because depends_on only works with individual resources, not entire modules in common scenarios, generally recommend to use it in specific cases. Terraform automatically infers dependencies based on resource references, so in most cases, explicit depends_on isn’t needed.
    See depends_on description in the following document.

    You only need to explicitly specify a dependency when a resource or module relies on another resource’s behavior but does not access any of that resource’s data in its arguments

    So you need to pass multiple security group IDs to the EC2 module and map them to the corresponding EC2 instances.

    • Adjust the security group output.tf using tomap for creating a map of names and IDs:
    output "sg_map" {
      value = tomap({
        for k, v in aws_security_group.sg : k => v.id
      })
    }
    
    • Iterate over the sg_map in the EC2 module using for_each to create an EC2 instance for each entry:
    module "ec2" {
      for_each = module.sg.sg_map
      source = "./modules/ec2"
    
      Name     = each.key
      EC2_SG_ID = each.value
    }
    
    Login or Signup to reply.
  2. If we consider that you are calling the security group module using the for_each meta-argument, that means the attributes can only be accessed by using the key of a module instance to reference the attribute value. In this particular case, since how you are creating the security groups is not in the question, I would suggest doing something like the following:

    module "sg" {
      for_each     = toset(var.Name)
      source       = "./modules/ec2_sg"
      App_Name     = each.value
    }
    
    module "ec2" {
      for_each = toset(var.Name)
      source   = "./modules/ec2"
    
      Name          = each.key
      EC2_SG_ID     = module.sg[each.key].sg_id
    

    That means you should also change the output for the security group ID, as right now what you are trying to return looks like it was a list. I would suggest changing it to the following:

    output "sg_id" {
      value = aws_security_group.sg.id
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search