Comparision of numeric values with two variables in Terraform templatefile template

464 views Asked by At

I'm trying to create a rendered file with Terraform's templatefile function.

Here is my code:

variable "prefix" {
  default = "k8s"
}

variable "masters_count" {
  default = 2
}

resource "google_compute_address" "k8s-static-ips" {
  name = "${var.prefix}-${count.index}"
  count = var.num_k8s_nodes
}

locals {
  ips = {
    for k in google_compute_address.k8s-static-ips : k.name => k.address
  }
}

resource "local_file" "AnsibleInventory" {

  content = templatefile("inventory.ini.tmpl",
  {
    private = local.ips
    prefix = var.prefix
    masters_count = var.masters_count
  }
  )
  filename = "inventory.ini"
}
[all]
%{ for index, ip in private ~}
${prefix}-${index} ansible_host=${ip} 
%{ endfor ~}

[kube-master]
%{ for index, ip in private ~}
%{ if index < masters_count ~}${prefix}-${index}%{ endif ~}
%{ endfor ~}

[calico-rr]

[k8s-cluster:children]
kube-master
kube-node
calico-rr

I have the problem that the %{ if index < masters_count ~} condition does not work, I am getting the Terraform error:

Call to function "templatefile" failed: inventory.ini.tmpl:11,7-12: Invalid
operand; Unsuitable value for left operand: a number is required., and 4 other
diagnostic(s).

Looks like it doesn't know the index variable in the if block. How can I make the comparision of that line possible accessing the index variable?

2

There are 2 answers

0
Ronny Forberger On BEST ANSWER

I solved it differently now.

[kube-master]
%{ for index, ip in private ~}
%{ if tonumber(element(split("-",index),1)) < masters_count ~}${index}
%{ endif ~}
%{ endfor ~}
0
Marcin On

Your local.ips will be a map of the form:

{
  "addressname1" = "ip1"
  "addressname2" = "ip2"
}

Therefore, in your template when you write %{ for index, ip in private ~}, index will be string (e.g. addressname1 and addressname2), not a number. This means that you can't use index in the if expression.

It is not clear what do you want to achieve with local.ips and the for loop in the template. But if you use the following in AnsibleInventory, it will at least work:

private = values(local.ips)