Terraform: openstack_compute_instance_v2 assign multiple networks dinamically

171 Views Asked by At

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?

2

There are 2 best solutions below

0
Marco Ferrara On BEST ANSWER

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
}
1
user2314737 On

How about creating two types of instances, one with one network and the other with two networks:

resource "openstack_compute_instance_v2" "compute_instance_onenet" {
count     = "${nr_of_instances_with_one_network}""
network {
    port  = openstack_networking_port_v2.networks[0].id
  }
}

adapting the deploy module.

resource "openstack_compute_instance_v2" "compute_instance_twonets" {
count     = "${nr_of_instances_with_two_networks}"
network {
    port  = openstack_networking_port_v2.networks[0].id
  }
network {
    port  = openstack_networking_port_v2.networks[1].id
  }
}