Is there a way to control the order a dynamic block creates its iterations?

I am using a dynamic block to define my columns within an aws_glue_catalog_table resource. I define all the table info in an object (called table_def in this case), so the columns part of it looks like this:

columns = [
      "name,string," ,
      "address,string," ,
      "city,string," ,
      "state,string," ,
      "zip,string," ,
    ]

In my table resource I have this code:

dynamic "columns" {
    for_each = toset(var.table_def.columns)
    content {
      name = split(",",columns.value)[0]
      type = split(",",columns.value)[1]
      comment = split(",",columns.value)[2]
    }
  }

This works, but it creates the columns in alphabetical order, not the order I define it in my structure. This is the schema for a table, so I want the columns to display in the order I define. Any way to tell it an order to generate them?

Hi @doug.rosen.c3fl,

A dynamic block behaves as if you wrote out a separate block for each element of the collection given in for_each, visiting each one in the normal iteration order for whatever collection type you select.

In your case, you’ve used toset to convert the value to be a set of strings. Sets don’t have any inherent order – they just represent whether each string is or is not present – and so as you’ve seen the iteration order for sets of strings is to visit the elements in a lexical sort order.

If the order of elements is important for your use-case then the more appropriate collection type to use would be a list, because that’s an ordered list of elements.

If you’ve already defined variable "table_def"'s columns attribute as being of type list(string) then you don’t need any special type conversion here and can just set for_each = var.table_def.columns.

The iteration order for a list is the inherent order of the list items, so in that case the dynamic block iteration will preserve whatever ordering was chosen by the module caller.

2 Likes

Thank you apparentlysmart. Yep - I do have that columns attribute defined as a list. I removed the toset part, and it is now creating them in the proper order.

From the given list of objects, how to use dynamic block to create multiple iterations but in order given in the module call or configuration. I know dynamic block doesn’t control the order of the iterations as per configuration for list of object, but is there any workaround we can do it please. We have some On-premise integration with Terraform for which we need to have allow blocks in order in TF plan as given in the configuration.

variable “allow” {
type = list(object({
protocol = string
ports = list(string)
}))
}

Hi @devops-rohit,

If the above posts don’t help with your situation, I would suggest starting a new topic with a complete example of the resource and configuration in question.

Thanks!