terraformterraform0.12+vultr

Retrieve IP address from instances using for_each


I have this script which works great. It created 3 instances with the sepcified tags to identify them easily. But issue is i want to add a remote-exec provisioner (currently commented) to the code to install some packages. If i was using count, i could have looped over it to do the remote-exec over all the instances. I could not use count because i had to use for_each to loop over a local list. Since count and for_each cannot be used together, how do i loop over the instances to retrieve their IP addresses for using in the remote-exec provisioner.

On digital ocean and AWS, i was able to get it work using host = "${self.public_ip}" But it does not work on vultr and gives the Unsupported attribute error

instance.tf

resource "vultr_ssh_key" "kubernetes" {
  name       = "kubernetes"
  ssh_key = file("kubernetes.pub")
}

resource "vultr_instance" "kubernetes_instance" {
    for_each = toset(local.expanded_names)
    plan = "vc2-1c-2gb"
    region = "sgp"
    os_id = "387"
    label = each.value
    tag = each.value
    hostname = each.value
    enable_ipv6 = true
    backups = "disabled"
    ddos_protection = false
    activation_email = false
    ssh_key_ids = [vultr_ssh_key.kubernetes.id]

  /* connection {
    type        = "ssh"
    user        = "root"
    private_key = file("kubernetes")
    timeout     = "2m"
    host        = vultr_instance.kubernetes_instance[each.key].ipv4_address
  }

  provisioner "remote-exec" {
    inline = "sudo hostnamectl set-hostname ${each.value}"
  } */
}

locals {
  expanded_names = flatten([
    for name, count in var.host_name : [
      for i in range(count) : format("%s-%02d", name, i + 1)
    ]
  ])
}

provider.tf

terraform {
  required_providers {
    vultr = {
      source = "vultr/vultr"
      version = "2.3.1"
    }
  }
}
provider "vultr" {
  api_key = "***************************"
  rate_limit = 700
  retry_limit = 3
}

variables.tf

variable "host_name" {
  type = map(number)
  default = {
    "Manager" = 1
    "Worker"  = 2
  }
}

Solution

  • The property you are looking for is called main_ip instead of ip4_address or something like that. Specifically accessible via self.main_ip in your connection block.