Search code examples
terraformterraform-provider-aws

How to filter aws subnets in terraform


I am porting a custom made deployment infrastructure to terraform. In that custom codebase there is something that says - fetch all available subnets from default region vpc but only those that have 20 or more available IPv4 addresses.

So I was experimenting with this code

data "aws_vpc" "main" {
  default = true
}

data "aws_subnets" "vpcsubnets" {
  filter {
    name   = "vpc-id"
    values = [data.aws_vpc.main.id]
  }
  filter {
    name   = "default-for-az"
    values = [true]
  }
  filter {
    name   = "state"
    values = ["available"]
  }
}

output "ids2" {
  value = {
    for k, v in data.aws_subnets.vpcsubnets : k => v if v.available_ip_address_count > 20
  }
}

But I get errors like these

 Error: Invalid reference
│ 
│   on main.tf line 51, in output "ids2":
│   51:     for k, vid in data.aws_subnets.vpcsubnets : k => v if v.available_ip_address_count > 20
│ 
│ A reference to a resource type must be followed by at least one attribute access, specifying the resource name.

Using Terraform 1.0.8 and aws provider 3.62


Solution

  • You need an extra intermediary step here. The full list of available subnets is available in the attribute data.aws_subnets.vpcsubnets.ids, but the attribute available_ip_address_count will only be available from the aws_subnet data. You need to retrieve that information for each available subnet in an intermediary data:

    data "aws_subnet" "vpcsubnet" {
      for_each = toset(data.aws_subnets.vpcsubnets.ids)
    
      id = each.value
    }
    

    Now the attribute is available in the namespace data.aws_subnet.vpcsubnet["<id>"].available_ip_address_count. You can easily make a small update to your output for this:

    output "ids2" {
      value = {
        for id, attributes in data.aws_subnet.vpcsubnet : id => attributes if attributes.available_ip_address_count > 20
      }
    }
    

    where I also renamed the temporary lambda variables for clarity.