简体   繁体   中英

How to for_each through a list(objects) in Terraform

i am trying to do for_each in a map(object) type for creating a vsphere vm using terraform. below is the codes that I have written.

instances.tf

resource "vsphere_virtual_machine" "vm" {
  for_each = var.virtual_machines
  # vm-name
  name             = each.key
  resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
  tags             = [data.vsphere_tag.tag[each.key].id]

  guest_id  = data.vsphere_virtual_machine.template.guest_id
  scsi_type = data.vsphere_virtual_machine.template.scsi_type
  # guest_id  = data.vsphere_virtual_machine.template[each.key].guest_id
  # scsi_type = data.vsphere_virtual_machine.template[each.key].scsi_type

  num_cpus = each.value.system_cores

  memory = each.value.system_memory

  wait_for_guest_ip_timeout  = 0
  wait_for_guest_net_timeout = 0

  #Network
  network_interface {
    network_id   = data.vsphere_network.network.id
    adapter_type = data.vsphere_virtual_machine.template.network_interface_types[0]
    # adapter_type = data.vsphere_virtual_machine.template[each.key].network_interface_types[0]
  }

  #Storage
  disk {
    label            = each.value.disk_label[0]
    size             = each.value.system_disk_size
    thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
    # thin_provisioned = data.vsphere_virtual_machine.template[each.key].disks.0.thin_provisioned
  }

  disk {
    label            = each.value.disk_label[1]
    size             = each.value.system_disk_size
    unit_number = 1
    thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
    # thin_provisioned = data.vsphere_virtual_machine.template[each.key].disks.0.thin_provisioned
  }

  #cloning from template
  clone {
    template_uuid = data.vsphere_virtual_machine.template.id
    # template_uuid = data.vsphere_virtual_machine.template[each.key].id

    customize {
      linux_options {

        host_name = each.value.system_name
        domain    = each.value.system_domain

      }

      network_interface {
        ipv4_address = each.value.system_ipv4_address
        ipv4_netmask = each.value.system_ipv4_netmask
      }

      ipv4_gateway = each.value.system_ipv4_gateway
    }

  }

}

i have declared other values and there is the map(object) i have in variables.tf


variable "virtual_machines" {
  type = map(object({
    system_disk_size     = number
    system_cores         = number
    system_memory        = number
    system_ipv4_address  = string
    system_name          = string
    system_domain        = string
    vsphere_tag_category = string
    vsphere_tag          = string
    disk_label           = list(string)
    system_ipv4_address  = list(string)
  }))

terraform.tfvars

virtual_machines = {
  server-1 = {
    system_cores         = 2
    system_memory        = 2048
    system_ipv4_address  = ""
    system_disk_size     = 140
    system_name          = "terraformvm"
    system_domain        = "example.com"
    vsphere_tag_category = "test_category"
    vsphere_tag          = "test_tag"
    disk_label           = ["disk0", "disk1"]
    system_ipv4_address  = ["ip1", "1p2"]
  }

But i am getting the below error.

│ Error: Incorrect attribute value type
│ 
│   on Instances.tf line 57, in resource "vsphere_virtual_machine" "vm":
│   57:         ipv4_address = each.value.system_ipv4_address
│     ├────────────────
│     │ each.value.system_ipv4_address is list of string with 2 elements
│ 
│ Inappropriate value for attribute "ipv4_address": string required.

can anyone tell me how to access each value in system_ipv4_address? Thanks in advance

If you need the whole list

each.value.system_ipv4_gateway[*]

If you need the first element for example

each.value.system_ipv4_gateway[0]

This attribute requires a string, so if you need to use both the ip addresses you need to define multiple interfaces. And apply one element to each one

the error is in terraform.tfvars, the correct way is written multiples VM stack into statement, this is works for me

virtual_machines = {
  server-1 = {
    system_cores         = 2
    system_memory        = 2048
    system_ipv4_address  = "10.10.10.1"
    system_disk_size     = 140
    system_name          = "terraformvm-1"
    system_domain        = "example.com"
    vsphere_tag_category = "test_category"
    vsphere_tag          = "test_tag"
    disk_label           = ["disk0", "disk1"]
  }
server-2 = {
    system_cores         = 2
    system_memory        = 2048
    system_ipv4_address  = "10.10.10.2"
    system_disk_size     = 140
    system_name          = "terraformvm-2"
    system_domain        = "example.com"
    vsphere_tag_category = "test_category"
    vsphere_tag          = "test_tag"
    disk_label           = ["disk0", "disk1"]
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM