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
countmeta-argument in the EFS resource but change the output of the VPC module - Use
for_eachwith 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."
}
