Bootstrap FreeKB - Amazon Web Services (AWS) - List Subnets using Terraform
Amazon Web Services (AWS) - List Subnets using Terraform


Let's say you have two Amazon Web Services (AWS) Virtual Private Clouds (VPC), one named default, the other named my-vpc.

 

And let's say my-vpc contains a handful of subnets.

 

This assumes you have setup Terraform as described in Amazon Web Services (AWS) - Getting Started with Terraform. Let's say you have the following files on your Terraform server.

├── required_providers.tf
├── virtual_private_clouds (directory)
│   ├── data.tf
│   ├── outputs.tf
│   ├── provider.tf
│   ├── resources.tf

 

data.tf in your virtual_private_clouds module could have something like this. Notice this uses both aws_subnet (not plural) and aws_subnets (plural).

data "aws_vpc" "my_aws_vpc" {
  filter {
    name   = "tag:Name"
    values = ["my-vpc"]
  }
}

data "aws_subnet" "my_aws_subnet" {
  filter {
    name = "tag:Name"
    values = ["us-east-1a"]
  }
}

data "aws_subnets" "my_aws_subnets" {
  filter {
    name = "vpc-id"
    values = [data.aws_vpc.my_aws_vpc.id]
  }
}

 

outputs.tf in your vpcs module could have something like this.

output "my_aws_subnet" {
  value = data.aws_subnets.my_aws_subnet
}

output "my_aws_subnets" {
  value = data.aws_subnets.my_aws_subnets
}

 

And outputs.tf in the same directory as your main root module (main.tf) could have something like this.

output "my-vpc-id" {
  value = module.vpc.my_vpc.id
}

output "my-subnets" {
  value = module.vpc.my_aws_subnets
}

 

The terraform refresh should now return something like this.

my_aws_subnets = {
  "filter" = toset([
    {
      "name" = "vpc-id"
      "values" = tolist([
        "vpc-014d2fcfa335d3c01",
      ])
    },
  ])
  "id" = "us-east-1"
  "ids" = tolist([
    "subnet-03f11417780f6cdbc",
    "subnet-09b70fa463fcd4a19",
    "subnet-0f35c3586e5090314",
    "subnet-03c64e403dc5bf18f",
    "subnet-0316e4d9fcd4efccc",
    "subnet-05727079637285f90",
  ])
  "tags" = tomap(null) /* of string */
  "timeouts" = null /* object */
}

my_aws_subnet = {
  "arn" = "arn:aws:ec2:us-east-1:123456789012:subnet/subnet-0c2f19a4bb023437c"
  "assign_ipv6_address_on_creation" = false
  "availability_zone" = "us-east-1a"
  "availability_zone_id" = "use1-az1"
  "available_ip_address_count" = 4091
  "cidr_block" = "10.0.1.0/24"
  "customer_owned_ipv4_pool" = ""
  "default_for_az" = false
  "enable_dns64" = false
  "enable_resource_name_dns_a_record_on_launch" = false
  "enable_resource_name_dns_aaaa_record_on_launch" = false
  "filter" = toset([
    {
      "name" = "tag:Name"
      "values" = toset([
        "us-east-1a-subnet",
      ])
    },
  ])
  "id" = "subnet-0c2f19a4bb023437c"
  "ipv6_cidr_block" = ""
  "ipv6_cidr_block_association_id" = ""
  "ipv6_native" = false
  "map_customer_owned_ip_on_launch" = false
  "map_public_ip_on_launch" = false
  "outpost_arn" = ""
  "owner_id" = "123456789012"
  "private_dns_hostname_type_on_launch" = "ip-name"
  "state" = "available"
  "tags" = tomap({
    "Name" = "us-east-1a-subnet"
  })
  "timeouts" = null /* object */
  "vpc_id" = "vpc-014d2fcfa335d3c01"
}

 

And here is how you can output just the value of a certain key, the "ids" key in this example.

output "subnets-ids" {
  value = module.vpc.my_aws_subnets.ids
}

 

Which should return the following.

subnets-ids = tolist([
  "subnet-03f11417780f6cdbc",
  "subnet-09b70fa463fcd4a19",
  "subnet-0f35c3586e5090314",
  "subnet-03c64e403dc5bf18f",
  "subnet-0316e4d9fcd4efccc",
  "subnet-05727079637285f90",
])

 

Here is how you would return the first item from the tolist (the item with index 0).

output "subnet-0-id" {
  value = tolist(module.vpc.my_aws_subnets.ids)[0]
}

 

Which should return the following.

subnet-0-id = subnet-03f11417780f6cdbc

 

Let's say you want to get a the CIDR of a subnet. You could use something like this.

data "aws_subnet" "my_aws_subnet" {
  filter {
    name = "tag:Name"
    values = ["us-east-1a-subnet"]
  }
}

output "subnet" {
  value = data.aws_subnet.my_aws_subnet
}

 

Which should return the following.

subnet = {
  "arn" = "arn:aws:ec2:us-east-1:123456789012:subnet/subnet-0c2f19a4bb023437c"
  "assign_ipv6_address_on_creation" = false
  "availability_zone" = "us-east-1a"
  "availability_zone_id" = "use1-az1"
  "available_ip_address_count" = 4091
  "cidr_block" = "10.0.1.0/24"
  "customer_owned_ipv4_pool" = ""
  "default_for_az" = false
  "enable_dns64" = false
  "enable_resource_name_dns_a_record_on_launch" = false
  "enable_resource_name_dns_aaaa_record_on_launch" = false
  "filter" = toset([
    {
      "name" = "tag:Name"
      "values" = toset([
        "us-east-1a-subnet",
      ])
    },
  ])
  "id" = "subnet-0c2f19a4bb023437c"
  "ipv6_cidr_block" = ""
  "ipv6_cidr_block_association_id" = ""
  "ipv6_native" = false
  "map_customer_owned_ip_on_launch" = false
  "map_public_ip_on_launch" = false
  "outpost_arn" = ""
  "owner_id" = "123456789012"
  "private_dns_hostname_type_on_launch" = "ip-name"
  "state" = "available"
  "tags" = tomap({
    "Name" = "us-east-1a-subnet"
  })
  "timeouts" = null /* object */
  "vpc_id" = "vpc-014d2fcfa335d3c01"
}

 

And then this to just output the CIDR.

output "subnet_cidr" {
  value = data.aws_subnet.my_aws_subnet.cidr_block
}

 

Which should now just output the CIDR.

subnet_cidr = 10.0.1.0/24

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter a79d77 in the box below so that we can be sure you are a human.