You are using terraform to deploy AWS instances and EMR clusters and you want to randomly spread them across your subnets.
You are using terraform to deploy AWS instances and EMR clusters, and you want to spread them across your subnets randomly.
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.
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.
I’m going to walk through the Terraform segments, and you can find the full source here.
data aws_vpc default {
default = true
}
data aws_subnet_ids current {
vpc_id = data.aws_vpc.default.id
}
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
}
Create a random number for the index:
resource random_id index {
byte_length = 2
}
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]
}
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!