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.

1 Like

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.