Terraform 0.13.4 : Using a splat for outputs containing multiple modules

I have two modules which can be declared with an optional count.
The first is as follows:

module "dns-c2" {
  source = "./modules/aws/dns-c2"
  count = var.amount
}

The output for it looks like this:

output "ips" {
  value = aws_instance.dns-c2[*].private_ip
}

The “ips” output is fed into the second module:

module "dns_rdir" {
  source = "./modules/aws/dns-rdir"
  depends_on = [module.dns-c2]
  count = var.amount
  redirect_to = module.dns-c2.ips
}

With the second module’s variable as follows

variable "redirect_to" {
  type = list(string)
  description = "The back-end to redirect to"
}

Running terraform plan, it seems that my splat operation in the first module’s output is incorrect:

ubuntu@box:~/terraform$ terraform plan

Error: Unsupported attribute

  on aws_c2_dns.tf line 76, in module "dns_rdir":
  76:   redirect_to = module.dns-c2.ips

This value does not have any attributes.

The terminal output underlines .ips as the source of the error. What is the correct way to provide a splat as an output, which can subsequently be used as an input to another module? I also tried the old way, as well as explicit type declarations and couldn’t get it to work still:

  value = aws_instance.dns-c2*.private_ip
  list(aws_instance.dns-c2[*].private_ip)

The logs are as follows:

020/10/09 21:12:31 [TRACE] EvalWriteOutput: Removing module.dns-c2.output.ips from state (it is now null)
2020/10/09 21:12:31 [TRACE] EvalWriteOutput: Saving Create change for module.dns-c2.output.ips in changeset
2020/10/09 21:12:31 [TRACE] [walkValidate] Exiting eval tree: module.dns-c2.output.ips
2020/10/09 21:12:31 [TRACE] vertex "module.dns-c2.output.ips": visit complete
2020/10/09 21:12:31 [TRACE] vertex "module.dns-c2.output.ips (expand)": dynamic subgraph completed successfully
2020/10/09 21:12:31 [TRACE] vertex "module.dns-c2.output.ips (expand)": visit complete
2020/10/09 21:12:31 [TRACE] dag/walk: visiting "module.dns_rdir.var.redirect_to (expand)"
2020/10/09 21:12:31 [TRACE] vertex "module.dns_rdir.var.redirect_to (expand)": starting visit (*terraform.nodeExpandModuleVariable)
2020/10/09 21:12:31 [TRACE] vertex "module.dns_rdir.var.redirect_to (expand)": expanding dynamic subgraph
2020/10/09 21:12:31 [TRACE] vertex "module.dns_rdir.var.redirect_to (expand)": entering dynamic subgraph
2020/10/09 21:12:31 [TRACE] dag/walk: visiting "module.dns_rdir.var.redirect_to"
2020/10/09 21:12:31 [TRACE] vertex "module.dns_rdir.var.redirect_to": starting visit (*terraform.nodeModuleVariable)
2020/10/09 21:12:31 [TRACE] vertex "module.dns_rdir.var.redirect_to": evaluating
2020/10/09 21:12:31 [TRACE] [walkValidate] Entering eval tree: module.dns_rdir.var.redirect_to
2020/10/09 21:12:31 [TRACE] eval: *terraform.EvalSequence
2020/10/09 21:12:31 [TRACE] eval: terraform.EvalNoop
2020/10/09 21:12:31 [TRACE] eval: *terraform.EvalOpFilter
2020/10/09 21:12:31 [TRACE] eval: *terraform.EvalModuleCallArgument
2020/10/09 21:12:31 [ERROR] eval: *terraform.EvalModuleCallArgument, err: Unsupported attribute: This value does not have any attributes.
2020/10/09 21:12:31 [ERROR] eval: *terraform.EvalOpFilter, err: Unsupported attribute: This value does not have any attributes.
2020/10/09 21:12:31 [ERROR] eval: *terraform.EvalSequence, err: Unsupported attribute: This value does not have any attributes.
2020/10/09 21:12:31 [TRACE] [walkValidate] Exiting eval tree: module.dns_rdir.var.redirect_to
2020/10/09 21:12:31 [TRACE] vertex "module.dns_rdir.var.redirect_to": visit complete
2020/10/09 21:12:31 [TRACE] vertex "module.dns_rdir.var.redirect_to (expand)": dynamic subgraph encountered errors
2020/10/09 21:12:31 [TRACE] vertex "module.dns_rdir.var.redirect_to (expand)": visit complete

Thank you,
Joe

Hi @joeminicucci,

I think the problem here is that your module "dns-c2" block has count set and so therefore module.dns-c2 is itself a list of objects representing the multiple instances of the module.

It looks like your intent is to have the same number of instances of each of your two modules and to correlate them by index, in which case you could write that like this:

module "dns_rdir" {
  source = "./modules/aws/dns-rdir"
  count  = var.amount

  redirect_to = module.dns-c2[count.index].ips
}

By using count.index above this expression selects the object representing the module.dns-c2 instance that has the same index as the current instance of module.dns_rdir.

This solved my issue, thank you so much @apparentlymart!