I'm trying to generate a ip list from within a yaml cloud init but keep failing.
Here is what I'd like to do
- path: /etc/hosts
owner: root:root
permissions: '0644'
defer: true
append: true
content: |
%{for i in range(10,19) ~}10.0.10.${i} compute-${i-9}%{endfor ~}
But I get the error:
Call to unknown function; There is no function named "range".
I also tried to pass a list of string and do
%{for str in ${iplst} ~} ${str} %{endfor ~}
But in this case I get
Error: Incorrect attribute value type
│
│ on modules/nfsdbs/nfsdb.tf line 19, in data "template_file" "config":
│ 19: vars = {
│ 20: ...
│ 30: iplst = "${var.ip_list}"
│ 31: ...
│ 33: }
│ ├────────────────
│ │ count.index is a number
│ │ var.aws_access_key_id is a string
│ │ var.aws_region is a string
│ │ var.aws_secret_access_key is a string
│ │ var.aws_session_token is a string
│ │ var.hostname_prefix is a string
│ │ var.ip_list is a list of string
│ │ var.slurmdb_password is a string
│ │ var.ssh_private_key is a string
│ │ var.ssh_public_key is a string
│ │ var.username is a string
│
│ Inappropriate value for attribute "vars": element "iplst": string required.
Based on the requirements in the question, this can be achieved by using the templatefile
built-in function [1]. The templated file should look like this:
- path: /etc/hosts
owner: root:root
permissions: '0644'
defer: true
append: true
content: |
%{for i in range(10,19) ~}
10.0.10.${i} ${format("compute-%d", i - 9)}
%{endfor ~}
Then, for demonstration purposes, using a local_file
resource, this is how the output of plan looks like:
Terraform will perform the following actions:
# local_file.cloud_init will be created
+ resource "local_file" "cloud_init" {
+ content = <<-EOT
- path: /etc/hosts
owner: root:root
permissions: '0644'
defer: true
append: true
content: |
10.0.10.10 compute-1
10.0.10.11 compute-2
10.0.10.12 compute-3
10.0.10.13 compute-4
10.0.10.14 compute-5
10.0.10.15 compute-6
10.0.10.16 compute-7
10.0.10.17 compute-8
10.0.10.18 compute-9
EOT
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "./cloud.init.yml"
+ id = (known after apply)
}
Finally, if you want to use the local_file
resource, here's the code that yields above output:
resource "local_file" "cloud_init" {
content = templatefile("${path.root}/cloud.init.yml.tpl", {})
filename = "${path.module}/cloud.init.yml"
}
Of course, since the question does not show all the variables you are trying to pass to the template_file
data source, the above call to the templatefile
function works without adding any variables, but you would have to adjust that to use all the necessary variables.
[1] https://developer.hashicorp.com/terraform/language/functions/templatefile