I have a VPC module which creates private subnets
resource "aws_subnet" "private" {
for_each = { for index, az_name in local.az_names : index => az_name }
vpc_id = aws_vpc.network.id
cidr_block = cidrsubnet(aws_vpc.network.cidr_block, 8, each.key 11)
availability_zone = local.az_names[each.key]
tags = {
Name = "${var.env}-private-${local.az_names[each.key]}"
Description = local.az_names[each.key]
Type = "private"
}
}
And an output
output "private_subnet" {
value = aws_subnet.private
}
Now I am trying to create an EFS module which will create a mount target for each private subnet
resource "aws_efs_mount_target" "efs-mt" {
count = length(var.private_subnet)
file_system_id = aws_efs_file_system.efs.id
subnet_id = var.private_subnet[count.index].id
security_groups = var.security_groups
}
main.tf
module "efs" {
source = "./modules/efs"
env = var.env
vpc_id = module.vpc.vpc_id
security_groups = [module.security.efs_sg_ids]
private_subnet = module.vpc.private_subnet
}
But I am getting these errors
│ Error: Invalid index
│
│ on modules/efs/main.tf line 14, in resource "aws_efs_mount_target" "efs-mt":
│ 14: subnet_id = var.private_subnet[count.index].id
│ ├────────────────
│ │ count.index is a number, known only after apply
│ │ var.private_subnet is a string, known only after apply
│
│ This value does not have any indices.
CodePudding user response:
You are mixing count
and for_each
meta-arguments which is not a good idea. To fix that, you could do the following:
- Leave the
count
meta-argument in the EFS resource but change the output of the VPC module - Use
for_each
with the EFS module as well
Even though I would suggest the second approach, I will provide both options. In the output in the VPC module, you can switch to:
output "private_subnet" {
value = values(aws_subnet.private)[*].id
}
The values
built-in function [1] will return a list of subnet IDs which you can then use as the intended input for the EFS module. In this case, you would have to change the module input variable type from string
to list(string)
:
variable "private_subnet" {
type = list(string)
description = "List of subnet IDs."
}
On the other hand, you could try switching the EFS resource to use for_each
instead of count
and passing it the output value of the VPC module the way it currently is:
resource "aws_efs_mount_target" "efs-mt" {
for_each = var.private_subnet
file_system_id = aws_efs_file_system.efs.id
subnet_id = each.value.id
security_groups = var.security_groups
}
In this case, you would have to change the module input variable type from string
to map(any)
:
variable "private_subnet" {
type = map(any)
description = "Map of all the values returned by the subnet resource."
}