This is a short tutorial on how to sort a list of Terraform objects by a specific attribute, which isn’t built-in to Terraform. This example will sort AWS VPC subnets based on their amount of available IP addresses.
Unfortunately (as of this writing), Terraform has no way of sorting a list of objects by a given attribute of the object, which can be problematic at times. Say that you wanted to sort some AWS subnets in descending order based on how many IP addresses were available in each subnet. This could be because you’d want to always place EC2 VMs in the subnet with the highest amount of IPs left, so that no subnet is overloaded with VMs. This is currently impossible in Terraform, so below is a workaround to this problem.
The Workaround#
|
|
How it Works#
Objects aren’t sortable, but usually their attributes are (strings, numbers, etc.). This workaround creates a list containing the values of a given attribute, each value coming from each object in the object list. The attribute list is sorted, and from here, we can place the objects in the same order as their values appear in the attribute list. A few notes on the above code:
reverse
is used to sort in descending order, assort
goes in ascending order by default.1distinct
is used to remove any duplicate attribute values.2format
is used to left-pad the strings with zero, so that numbers can be sorted. Terraform casts numbers to strings first before sorting, which results in incorrect ordering.3tonumber
is used to convert the attribute value back into a number, sincesort
type casts its contents into strings.4compact
is used to remove any empty string elements from the list.5flatten
is used to ensure the resulting list is 1-dimensional.6
General Workaround#
Below is a generalization of the above, to work with generally any object/attribute combo. Just substitute in the names of the actual resource types being used.
|
|
HashiCorp Developer | Terraform: sort Function. https://developer.hashicorp.com/terraform/language/functions/sort ↩︎
HashiCorp Developer | Terraform: distinct Function. https://developer.hashicorp.com/terraform/language/functions/distinct ↩︎
Jonathan Share’s Blog: Sorting numerically in Terraform. https://blog.sharebear.co.uk/2022/01/sorting-numerically-in-terraform/ ↩︎
HashiCorp Developer | Terraform: tonumber Function. https://developer.hashicorp.com/terraform/language/functions/tonumber ↩︎
HashiCorp Developer | Terraform: compact Function. https://developer.hashicorp.com/terraform/language/functions/compact ↩︎
HashiCorp Developer | Terraform: flatten Function. https://developer.hashicorp.com/terraform/language/functions/flatten ↩︎