terraform

Looping through a list of string terraform


I got a terraform resource input that requires a list of string input, eg 'words = list(string)'. I created a list variable in variable.tf

variable "mywords" {
  type        = list
  default = ["simple","but","lovely"]
}

on the main.tf

resource "provider_resource" "example" {
  words = var.mywords
}

I wanted to run each string in the list separately in the words input. If i run it as shows it places all the list string content in the words input.


Solution

  • Since lists are collections, in order to create a resource per a collection item, you would need to use either count or for_each. Depending on your use case, both can work. If you decide to go with count, the code should look like the following:

    resource "provider_resource" "example" {
       count = length(var.mywords)
       words = var.mywords[count.index]
    }
    

    Alternatively, if you want to use for_each, you would need either to recreate the variable as a set(string) or use the explicit type casting:

    resource "provider_resource" "example" {
       for_each = toset(var.mywords)
       words    = each.value # or each.key, since set does not have any secondary identifiers or ordering
    }
    

    If you opt to redeclare the variable as a set(string), the following should work:

    variable "mywords" {
      type    = set(string)
      default = ["simple","but","lovely"]
    }
    
    resource "provider_resource" "example" {
       for_each = var.mywords
       words    = each.value # or each.key, since set does not have any secondary identifiers or ordering
    }
    

    Last, but not the least, you should always be careful about the type that the argument expects. In this case, it looks like words should be passed a list. If that is the case, the above has to account for that, by using square brackets around the single value:

    resource "provider_resource" "example" {
       count = length(var.mywords)
       words = [var.mywords[count.index]]
    }
    

    When using for_each:

    resource "provider_resource" "example" {
       for_each = toset(var.mywords)
       words    = [each.value] # or each.key, since set does not have index numbers
    }
    
    resource "provider_resource" "example" {
       for_each = var.mywords
       words    = [each.value] # or each.key, since set does not have index numbers
    }