Less complexity, greater impact

How to Select 1 Random AWS Subnet in terraform

You are using terraform to deploy AWS instances and EMR clusters and you want to randomly spread them across your subnets.

Picking a name out of bowl

Use Case

You are using terraform to deploy AWS instances and EMR clusters, and you want to spread them across your subnets randomly.

The Issue

The AWS provider doesn’t provide a direct way to say “give me a random subnet.” Instead, you can get a set of subnet IDs or a specific subnet—neither of which helps distribute your workload evenly.

The Solution

Use the random_id resource and some basic modulo math to select a subnet at random. To ensure we get a nice distribution across all subnets, I ran some tests:

"x=0", occurred 208 times for 20%
"x=1", occurred 205 times for 20%
"x=2", occurred 194 times for 19%
"x=3", occurred 192 times for 19%
"x=4", occurred 201 times for 20%

You can find my test code and run the numbers yourself in my terraform-tips-and-workarounds GitHub repo.

Implementation

I’m going to walk through the Terraform segments, and you can find the full source here.

List of Subnets

  1. Query the default VPC. If you don’t want to use the default VPC, use filters or tags.
  2. Get subnet IDs for that VPC. Again, filters or tags can limit which subnets you want.
data aws_vpc default {
  default = true
}

data aws_subnet_ids current {
  vpc_id = data.aws_vpc.default.id
}

AMI

We need an AMI to launch an EC2 instance. This query grabs the most recent Amazon Linux 2 AMI.

data aws_ami current {
  most_recent = true

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  name_regex = "^amzn2-ami-hvm-.*x86_64-gp2"
  owners     = ["137112412989"] # Amazon
}

Random Time

Create a random number for the index:

resource random_id index {
  byte_length = 2
}

The Math

locals {
  subnet_ids_list = tolist(data.aws_subnet_ids.current.ids)

  subnet_ids_random_index = random_id.index.dec % length(data.aws_subnet_ids.current.ids)

  instance_subnet_id = local.subnet_ids_list[local.subnet_ids_random_index]
}

Using It

Now use the selected subnet in your EC2 instance. The ignore_changes ensures that Terraform doesn’t replace the instance if a new subnet is added to the VPC later.

resource aws_instance instance {
  ami           = data.aws_ami.current.id
  instance_type = "t3.micro"

  subnet_id = local.instance_subnet_id

  lifecycle {
    ignore_changes = [subnet_id]
  }

  tags = {
    Name = "random_subnet_test"
  }
}

And poof, there’s your magic. Enjoy your randomly distributed AWS infrastructure!

Website TechnologyDaring Way: Technology Simplified. Strategy Delivered., © 2025