amazon-web-servicesamazon-ec2terraformterraform-provider-awsaws-security-group

Terraform: How to pass multiple values as output and map to another module's variables


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 module output:

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.


Solution

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