terraform-provider-ovh icon indicating copy to clipboard operation
terraform-provider-ovh copied to clipboard

Feature Request: private network region_openstackId

Open rienafairefr opened this issue 3 years ago • 10 comments

for private networks resources ovh_cloud_project_network_private, the openstackId of the network in a given region is given by the API, but not exposed by the terraform provider.

https://eu.api.ovh.com/console/#/cloud/project/%7BserviceName%7D/network/private#GET regions is a list of objects, returning region_name/status/openstackId, and ovh_cloud_project_network_private.regions only gives the name of the region

rienafairefr avatar May 17 '21 13:05 rienafairefr

Is any workaround available for terraform? I would like to create an ovh_cloud_project_kube resource with a private network, but it requires the openstackId of the network.

viktorgt avatar Sep 14 '21 06:09 viktorgt

on the ovh_cloud_project_network_private there is a regions_attributes openstackid attribute available. So you can create the private_network with ovh_cloud_project_network_private, add a subnet with ovh_cloud_project_network_private_subnet, and it works.

resource "ovh_cloud_project_network_private" "network_prod" {
  service_name = var.ovh_project
  name         = "network-prod"

  vlan_id = 0
  regions = [var.ovh_region]
}

resource "ovh_cloud_project_network_private_subnet" "network_prod_subnet" {
  service_name = var.ovh_project
  network_id   = ovh_cloud_project_network_private.network_prod.id
  region       = var.ovh_region

  start      = "192.168.168.100"
  end        = "192.168.168.200"
  network    = "192.168.168.0/24"
  dhcp       = true
  no_gateway = true
}

resource "ovh_cloud_project_kube" "cluster-prod" {
  service_name       = var.ovh_project
  name               = "kube-cluster-prod"
  region             = var.ovh_region
  version            = "1.20"
  private_network_id = ovh_cloud_project_network_private.network_prod.regions_attributes.0.openstackid
}

rienafairefr avatar Sep 14 '21 07:09 rienafairefr

In which version of the provider is the workaround available?

From code in https://github.com/ovh/terraform-provider-ovh/blob/master/ovh/resource_cloud_project_network_private.go it seems it is no longer included in schema. and from https://github.com/ovh/terraform-provider-ovh/blob/master/ovh/types_cloud.go its clear that openstackId is not unmarshalled from the response from api:

type CloudProjectNetworkPrivateResponse struct {
	Id      string                              `json:"id"`
	Status  string                              `json:"status"`
	Vlanid  int                                 `json:"vlanId"`
	Name    string                              `json:"name"`
	Type    string                              `json:"type"`
	Regions []*CloudProjectNetworkPrivateRegion `json:"regions"`
}

type CloudProjectNetworkPrivateRegion struct {
	Status string `json:"status"`
	Region string `json:"region"`
}

Adding a OpenStackId string `json:"openstackId"` property to CloudProjectNetworkPrivateRegion and map it to a new schema element in func resourceCloudProjectNetworkPrivateRead in https://github.com/ovh/terraform-provider-ovh/blob/master/ovh/resource_cloud_project_network_private.go should do the trick.

Meanwhile, does anyone know of a workaround, is there perhaps a way to use openstack provider to do the private network creation?

eirikbell avatar Oct 07 '21 05:10 eirikbell

on the ovh_cloud_project_network_private there is a regions_attributes openstackid attribute available. So you can create the private_network with ovh_cloud_project_network_private, add a subnet with ovh_cloud_project_network_private_subnet, and it works.


resource "ovh_cloud_project_kube" "cluster-prod" {
  service_name       = var.ovh_project
  name               = "kube-cluster-prod"
  region             = var.ovh_region
  version            = "1.20"
  private_network_id = ovh_cloud_project_network_private.network_prod.regions_attributes.0.openstackid
}

This works fine with a single region, the id '0' matches your region. I don't see how to do the same when several regions are used. Each region has its own attribute number (which I don't know) and openstackid

vepito avatar May 31 '22 14:05 vepito

This works fine with a single region, the id '0' matches your region. I don't see how to do the same when several regions are used. Each region has its own attribute number (which I don't know) and openstackid

That'd be trickier, but achievable with latest terraform capabilities (for loop, with an if to find the correct element in the list where region=the value you want) AFAIK. Or, alternatively, loop over the regions_attributes attribute: ! untested:

resource "ovh_cloud_project_kube" "cluster-prod" {
  count = length(ovh_cloud_project_network_private.network_prod.regions_attributes)

  service_name       = var.ovh_project
  name               = "kube-cluster-prod"
  region             = var.ovh_region
  version            = "1.20"
  private_network_id = ovh_cloud_project_network_private.network_prod.regions_attributes[count.index].openstackid
}

Would be easier to read with a local region->openstackid map and a for_each.

rienafairefr avatar May 31 '22 17:05 rienafairefr

Here a good workaround: private_network_id = tolist(ovh_cloud_project_network_private.network_prod.regions_attributes)[index(ovh_cloud_project_network_private.network_prod.regions_attributes.*.region, var.ovh_region)].openstackid

I have found the base here: https://github.com/ovh/terraform-provider-ovh/blob/3fe0ace4f032aa73dff7f0d1cb4f4c233ccbc654/website/docs/r/cloud_project_kube.html.markdown?plain=1#L30

But when I try (terraform v1.2.9 and OVH provider v0.21.0) I have this error:

Error: Invalid index
│
│   on kubernetes.tf line 15, in resource "ovh_cloud_project_kube" "mykube":
│   15:    private_network_id = ovh_cloud_project_network_private.network_prod.regions_attributes[index(ovh_cloud_project_network_private.network_prod.regions_attributes.*.region, var.ovh_region)].openstackid
│     ├────────────────
│     │ ovh_cloud_project_network_private.network_prod.regions_attributes is set of object with 1 element
│
│ Elements of a set are identified only by their value and don't have any separate index or key to select with, so it's only possible to perform operations across all elements of the set.

To fix it, I add the function tolist

albundy83 avatar Sep 20 '22 09:09 albundy83

If you want to select the first element you can also use the one(...) method like this:

  private_network_id = one(ovh_cloud_project_network_private.network.regions_attributes[*].openstackid)

scraly avatar Sep 21 '22 08:09 scraly

Ot you can simply use tolist() function and the first index:

	private_network_id = tolist(ovh_cloud_project_network_private.network.regions_attributes[*].openstackid)[0]

scraly avatar Sep 21 '22 13:09 scraly

Nice, maybe we could update doc with your tips ?

albundy83 avatar Sep 21 '22 19:09 albundy83

Yes, I added the tip and also several examples in the documentation. It will be released in the v0.22.0 :-).

scraly avatar Sep 23 '22 12:09 scraly

Seems the issue is fixed by the doc update, closing it.

amstuta avatar Mar 20 '24 13:03 amstuta