terraform-provider-ovh
terraform-provider-ovh copied to clipboard
Feature Request: private network region_openstackId
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
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.
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
}
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?
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
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
.
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
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)
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]
Nice, maybe we could update doc with your tips ?
Yes, I added the tip and also several examples in the documentation. It will be released in the v0.22.0 :-).
Seems the issue is fixed by the doc update, closing it.