Using local_file and directives to dynamically build Ansible hosts file

Hola.

I’m new on my Terraform journey, so please feel free to critique my code as a whole if you see anything that doesn’t make sense or adhere to best practices.

I have two questions which I’ll split between two posts. The first one is as follows:

I’m trying to build an Ansible hosts file with local_file data source. I need it to have a dynamically updating hostname/IP address line for each of my instances.

I’ve been mildly successful with this kind of statically entered variable:

web01 ${vultr_instance.static_ip_instances["web01"].main_ip}

However, this doesn’t scale well and I’m trying to find a way to iterate over all the instances.

I’ve unsuccessfully tried many different variations of for_each and variable interpolations, finally zeroing in on these type of directives:

%{ for each ip in local.static_ip_instances.*.main_ip ~}
${ip}
%{ endfor ~}

Unfortunately, I always end up getting these errors:

This object does not have an attribute named "main_ip".

I’ve tried other attributes like hostname and that throws the same error as well.

Any help would be very appreciated!



locals {
 reserved_ip_instances = {
   "web01" = { plan = var.plan region = var.region, os_id = var.os, script_id = var.script, firewall_group_id = var.firewall, reserved_ip = var.reserved_ip },
   }
 static_ip_instances = {
   "web02" = { plan = var.plan, region = var.region, os_id = var.os, script_id = var.script, firewall_group_id = var.firewall },
   "web03" = { plan = var.plan_id_basic, region = var.region, os_id = var.os, script_id = var.script, firewall_group_id = var.firewall },
 
   }
   }

resource "my_cloud" "reserved_ip_instances" {
  for_each = local.reserved_ip_instances
  plan = each.value.plan
  region = each.value.region
  os_id = each.value.os
  label = "${each.key}"
  firewall_group_id = each.value.firewall
  script_id = each.value.script
  reserved_ip_id = each.value.reserved_ip
  hostname = "${each.key}"
}

resource "my_cloud" "static_ip_instances" {
  for_each = local.static_ip_instances 
  plan = each.value.plan
  region = each.value.region
  os_id = each.value.os
  label = "${each.key}"
  firewall_group_id = each.value.firewall
  script_id = each.value.script
  hostname = "${each.key}"
}

# Generate Ansible Inventory
resource "local_file" "inventory" {
 #for_each = local.static_ip_instances
 filename = "/home/ansible/hosts"
 content = <<EOF
[all:vars]
ansible_connection=ssh
ansible_user=ansible_user
#ansible_ssh_pass=password

[web]
web01 ansible_port=22 ansible_host=${vultr_instance.static_ip_instances["web01"].main_ip}

#{ for each, ip in local.static_ip_instances[each.key].main_ip ~}
#{ for each, ip in local.static_ip_instances[*].main_ip ~}

%{ for each, ip in local.static_ip_instances[each.key] ~}
${ip}
%{ endfor ~}

%{ for each, ip in local.static_ip_instances.*.main_ip ~}
${ip}
%{ endfor ~}

  EOF
}