'AWS Terraform: Filter specific subnets by matching substring in tag name

I have 6 subnets, I want to filter 3 subnets from them matching substring internal and use in rds.

Tag name has internal word and want to filter based on that.

Could anyone please help me?

data "aws_vpc" "vpc_nonprod-sctransportationops-vpc" {
  tags {
    Name = "vpc_nonprod-sctransportationops-vpc"
  }
}
    
data "aws_subnet_ids" "all" {
  vpc_id = "${data.aws_vpc.vpc_nonprod-sctransportationops-vpc.id}"
}
    
output "aws_subnet_ids" {
  value = "${data.aws_subnet_ids.all.ids}"
}
# 6 subnets
# Now look up details for each subnet
     

data "aws_subnet" "filtered_subnets" {
  count = "${length(data.aws_subnet_ids.all.ids)}"
  id    = "${data.aws_subnet_ids.all.ids[count.index]}"

  filter {
    name   = "tag:Name"
    values = ["*internal*"]
  }
}

Some tag name has internal substring

Need to grab all subnet id whose tag name has internal substring

values = ["*"] return 6 ids, however, values = ["any word not work"] or values = ["*internal*"] doesn't work.

Following are error:

Error: Error refreshing state: 1 error(s) occurred:

* data.aws_subnet.publicb: 3 error(s) occurred:

* data.aws_subnet.publicb[1]: data.aws_subnet.publicb.1: no matching subnet found
* data.aws_subnet.publicb[4]: data.aws_subnet.publicb.4: no matching subnet found
* data.aws_subnet.publicb[0]: data.aws_subnet.publicb.0: no matching subnet found

There should be 6 but I am getting only 3, that means there should be partially good things and partially bad things.

These 3 subnets doesn't have internal substring in tag name.

It means it's parsing. aws_subnet_ids doesn't have filter option.

There should be instead. For one match, it will be simple, however, I need multiple matches.

In my guess now the error is because of loops which runs for 6 times.

Here is same output without filter:

                  "data.aws_subnet.filtered_subnets.2": {
                    "type": "aws_subnet",
                    "depends_on": [
                        "data.aws_subnet_ids.all"
                    ],
                    "primary": {
                        "id": "subnet-14058972",
                        "attributes": {
                            "assign_ipv6_address_on_creation": "false",
                            "availability_zone": "us-west-2a",
                            "cidr_block": "172.18.201.0/29",
                            "default_for_az": "false",
                            "id": "subnet-14038772",
                            "map_public_ip_on_launch": "false",
                            "state": "available",
                            "tags.%": "4",
                            "tags.Designation": "internal",
                            "tags.Name": "subnet_nonprod-sctransportationops-vpc_internal_az2",
                            "tags.Permissions": "f00000",
                            "tags.PhysicalLocation": "us-west-2a",
                            "vpc_id": "vpc-a47k07c2"
                        },
                        "meta": {},
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": "provider.aws"
                }


Solution 1:[1]

aws_subnet_ids has this feature, however, different way. Here it solved my problem:

data "aws_subnet_ids" "all" {
  vpc_id = "${data.aws_vpc.vpc_nonprod-sctransportationops-vpc.id}"

  tags = {
    Name = "*internal*"
  }
}

Thanks for reviewing :D

Solution 2:[2]

According to the Terraform documentation aws_subnet_ids data source has been deprecated and will be removed in a future version (https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet_ids).

You can use aws_subnets instead.

Example:

    # Private Subnets (db_subnet) 
    data "aws_subnets" "private_db_subnet" {

      filter {
        name   = "vpc-id"
        values = [data.aws_vpc.main_vpc.id]
      }

      tags = {
        Name = "{YOUR_FILTER}"
      }
    }

Its output is a list of subnets: data.aws_subnets.private_db_subnet.ids

Use case example:

    resource "aws_lambda_function" "lambda_json_documentdb" {
        ...
        vpc_config {
            subnet_ids             = data.aws_subnets.private_db_subnet.ids
            security_group_ids     = [aws_security_group.lambda_sg.id]
        }
        ...
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Adan Rehtla
Solution 2 dp6000