terraformopenstack

Terraform: openstack_compute_instance_v2 assign multiple networks dinamically


I'm trying to create multiple instances in terraform, some instances have only one network attached and some can have multiple networks attached. I wrote the code below and it creates correctly the instances with only one network, but when create the instance with two networks, for example test-jammy2 create two separate instances one associated with network mgmt and one associated with network be instead to create a single instance with two networks associated mgmt and be

main.tf:

locals { 
  servers = {
    test-jammy1 = {
      project_name   = "myproject"
      hostname       = "test-jammy1"
      net_ip         = ["10.0.100.10"]
      net_mac        = ["00:00:00:00:00:00"]
      net_type       = ["dv"]
      compute_flavor = "small"
      image_type     = "ipxe"
      net_secgroup   = "permit_all"
    },
    test-jammy2 = {
      project_name   = "myproject"
      hostname       = "test-jammy2"
      net_ip         = ["10.0.101.10","10.0.102.10"]
      net_mac        = ["00:00:00:00:00:02","00:00:00:00:00:03"]
      net_type       = ["mgmt","be"]
      compute_flavor = "small"
      image_type     = "ipxe"
      net_secgroup   = "permit_all"
    },
  }
}
module "deploy" {   
    source         = "./instances"

    for_each       = local.servers

    project_name   = each.value.project_name
    hostname       = each.value.hostname
    net_ip         = each.value.net_ip
    net_mac        = each.value.net_mac
    net_type       = each.value.net_type
    net_secgroup   = each.value.net_secgroup
    compute_flavor = each.value.compute_flavor
    image_type     = each.value.image_type
}

instances/main.tf:

resource "openstack_compute_instance_v2" "compute_instance" {
  count             = "${length(var.net_type)}"
  name              = "${var.hostname}.mydomain.com"
  availability_zone = "nova"
  image_id          = data.openstack_images_image_v2.image_type.id
  flavor_id         = data.openstack_compute_flavor_v2.compute_flavor.id
  
  scheduler_hints {
    group = openstack_compute_servergroup_v2.servergroup.id
  }
  
  network {
    port  = openstack_networking_port_v2.networks[count.index].id
  }
}

resource "openstack_compute_servergroup_v2" "servergroup" {
  name     = var.hostname
  policies = ["anti-affinity"]
}

resource "openstack_networking_port_v2" "networks" {
  count              = "${length(var.net_type)}"
  name               = "${var.net_type[count.index]}0.${var.hostname}.mydomain.com"
  network_id         = data.openstack_networking_network_v2.network[count.index].id
  security_group_ids = [data.openstack_networking_secgroup_v2.secgroup.id]
  mac_address        = var.net_mac[count.index]

  fixed_ip {
    subnet_id  = data.openstack_networking_subnet_v2.subnet[count.index].id
    ip_address = var.net_ip[count.index]
  }
}

How can fix it?


Solution

  • Thanks to all, I solved:

    instances/main.tf:

    resource "openstack_compute_instance_v2" "compute_instance" {
      name              = "${var.hostname}.mydomain.com"
      availability_zone = "nova"
      image_id          = data.openstack_images_image_v2.image_type.id
      flavor_id         = data.openstack_compute_flavor_v2.compute_flavor.id
    
      scheduler_hints {
        group = openstack_compute_servergroup_v2.servergroup.id
      }
      
      network {
        port  = openstack_networking_port_v2.networks[0].id
      }
    
      depends_on = [ openstack_networking_port_v2.networks ]
    }
    
    resource "openstack_compute_servergroup_v2" "servergroup" {
      name     = var.hostname
      policies = ["anti-affinity"]
    }
    
    resource "openstack_networking_port_v2" "networks" {
      count              = "${length(var.net_type)}"
      name               = "${var.net_type[count.index]}0.${var.hostname}.mydomain.com"
      network_id         = data.openstack_networking_network_v2.network[count.index].id
      security_group_ids = [data.openstack_networking_secgroup_v2.secgroup.id]
      mac_address        = var.net_mac[count.index]
    
      fixed_ip {
        subnet_id  = data.openstack_networking_subnet_v2.subnet[count.index].id
        ip_address = var.net_ip[count.index]
      }
    }
    
    # start from second index
    resource "openstack_compute_interface_attach_v2" "interface_attach" {
      for_each = {for idx, val in var.net_type : idx => val if idx > 0}
      instance_id = openstack_compute_instance_v2.compute_instance.id
      port_id     = openstack_networking_port_v2.networks[each.key].id
    }