Templatefile with count

The template_file provider is both deprecated, and not available for ARM machines. We are replacing it everywhere with calls to the templatefile function. However, in some places we use template_file with count and reference the resources later, and we can’t find a straightforward way to do that with templatefile.

Example:

data "template_file" "node_json" {
     count = var.brokers
     vars = {
     ...
     }
}

and then

module "..." {
     nodes              = data.template_file.node_json.*.rendered
}

or

resource "..." {
   count = var.brokers
   data = element(  data.template_file.node_json.*.rendered, count.index)

I have found a way to do something similar using instead the null_resource :

data "null_data_source" "node_json" {
  count = var.brokers
  inputs = {
    node = templatefile("${path.module}/kitchen/nodes/broker.json", {...})
  }
}

and then

module "..." {
  nodes              = data.null_data_source.node_json.*.outputs.node
}

This works fine, but I get a warning:

│ Warning: Deprecated Resource
│
│ The null_data_source was historically used to construct intermediate values to re-use elsewhere in configuration, the same can now be achieved using locals

As far as I know, I can’t use count with locals…

Any suggestions will be welcome. TF version 1.2.7, by the way.

Thanks!

Hi @schapirama,

You can use a for expression to apply templatefile multiple times. In your case, you can use the range function to get a similar effect as count, of using different integers to distinguish the different calls:

locals {
  nodes = [
    for n in range(var.brokers) : templatefile("${path.module}/kitchen/nodes/broker.json", {
      index = n
    })
  ]
}

You didn’t mention in your examples what arguments you were previously passing in vars to the template_file data source, and so I just included index = n as an example here which will make ${index} in the template insert the current index. In practice though you can use this n symbol in any place where you would’ve used count.index inside the vars mapping, so you should be able to preserve exactly the same arguments you were using before as far as the template itself is concerned.

1 Like

Thanks, Martin! This works (I didn’t know you could use for inside of locals).

Much appreciated.

Great!

A for expression is just a normal expression, so syntactically it’s valid anywhere value expressions are expected.

Though of course not all situations allow tuple or object types, so in some cases it can fail type checking even though the syntax is allowed.

1 Like

Makes perfect sense. Thanks a lot!