amazon-web-servicesterraforminfrastructure-as-codehashicorpeip

Convert multiple modules to single module terraform


Please instead of doing negative voting, kindly read complete problem first.

Hi I am new to terraform. I have 3 modules in terraform.

/module1/eip/main.tf
/module1/eip/output.tf

/module2/eip/main.tf
/module2/eip/output.tf

/module3/eip/main.tf
/module3/eip/output.tf

These all 3 modules create an eip along with showing it in outputs.

From main.tf on root level i am using these functions like this.

module "module-one-eip" {
  source   = "./modules/module1/eip/"
  instance = module.ec2-for-one-module.ec2-one-id
}

module "module-two-eip" {
  source   = "./modules/module2/eip/"
  instance = module.ec2-for-two-module.ec2-two-id
}

module "module-three-eip" {
  source   = "./modules/module3/eip/"
  instance = module.ec2-for-three-module.ec2-three-id
}

Now I want to remove repetitive files and I want to use one file for all modules, like all code from these 3 will reside in one file, and all outputs mentioned above will have in same file, but main problem here is how I will handle different instance variable data being passed and how it will be synced with right code section in same file.

/module/generic-eip/main.tf
/module/generic-eip/outputs.tf

and from main.tf I want to call it like this.

   module "module-generic-eip" {
      source   = "./modules/generic-eip/"
      instance = (how to manage different instance names for same file)
    }

I know there is for_each and count stuff of terraform, problem is internal configurations are diffrent, i mean how i can make dynamic naming as well.

inside ./modules/eip/main.tf

resource "aws_eip" "(how to manage different names here)" {
  instance = var.instance
  vpc      = true
}

Solution

  • Assuming you keep your inctance module separate, and only want to consolidate EIP module, it would be as follows:

    locals {
        instance_ids = [module.ec2-for-one-module.ec2-one-id, 
                        module.ec2-for-two-module.ec2-two-id, 
                        module.ec2-for-three-module.ec2-three-id]
    }
    
    module "module-generic-eip" {
        source   = "./modules/generic-eip/"
        count    = length(local.instance_ids)
        instance = local.instance_ids[count.index]
    }
    

    Code inside ./modules/eip/main.tf does not change, as for each iteration of count, var.instance will be a single element from local.instance_ids.

    Then you access, individual EIPs, using indieces, 0, 1, 2:

    module.module-generic-eip[0]
    module.module-generic-eip[1]
    module.module-generic-eip[2]