Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions docs/data-sources/instance_server_type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
subcategory: "Instances"
page_title: "Scaleway: scaleway_instance_server_type"
---

# scaleway_instance_server_type

Gets information about a server type.

## Example Usage

```hcl
data "scaleway_instance_server_type" "pro2-s" {
name = "PRO2-S"
zone = "nl-ams-1"
}
```

## Argument Reference

To select the server type which information should be fetched, the following arguments can be used:

- `name` - (Required) The name of the server type.
Only one of `name` and `snapshot_id` should be specified.

- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) of the server type (to check the availability of the server type for example).

## Attributes Reference

The following attributes will be available:

- `arch` - The architecture of the server type.

- `cpu` - The number of CPU cores of the server type.

- `ram` - The amount of RAM of the server type (in bytes).

- `gpu` - The number of GPUs of the server type.

- `volumes` - The specifications of volumes allowed for the server type.

-> The `volumes` block contains:
- `min_size_total` - The minimum total size in bytes of volumes allowed on the server type.
- `max_size_total` - The maximum total size in bytes of volumes allowed on the server type.
- `min_size_per_local_volume` - The minimum size in bytes per local volume allowed on the server type.
- `max_size_per_local_volume` - The maximum size in bytes per local volume allowed on the server type.
- `scratch_storage_max_size` - The maximum size in bytes of the scratch volume allowed on the server type.
- `block_storage` - Whether block storage is allowed on the server type.

- `capabilities` - The specific capabilities of the server type.

-> The `capabilities` block contains:
- `boot_types` - The boot types allowed for the server type.
- `max_file_systems` - The maximum number of file systems that can be attached on the server type.

- `network` - The network specifications of the server type.

-> The `network` block contains:
- `internal_bandwidth` - The internal bandwidth of the server type (in bytes/second).
- `public_bandwidth` - The public bandwidth of the server type (in bytes/second).
- `block_bandwidth` - The block bandwidth of the server type (in bytes/second).

- `hourly_price` - The hourly price of the server type (in euros).

- `monthly_price` - The monthly price of the server type (in euros).

- `end_of_service` - Whether the server type will soon reach End Of Service.

- `availability` - Whether the server type is available in the zone.
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ func Provider(config *Config) plugin.ProviderFunc {
"scaleway_instance_security_group": instance.DataSourceSecurityGroup(),
"scaleway_instance_server": instance.DataSourceServer(),
"scaleway_instance_servers": instance.DataSourceServers(),
"scaleway_instance_server_type": instance.DataSourceServerType(),
"scaleway_instance_snapshot": instance.DataSourceSnapshot(),
"scaleway_instance_volume": instance.DataSourceVolume(),
"scaleway_iot_device": iot.DataSourceDevice(),
Expand Down
282 changes: 282 additions & 0 deletions internal/services/instance/server_type_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
package instance

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
product_catalog "github.com/scaleway/scaleway-sdk-go/api/product_catalog/v2alpha1"
"github.com/scaleway/scaleway-sdk-go/scw"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
)

func DataSourceServerType() *schema.Resource {
return &schema.Resource{
ReadContext: DataSourceInstanceServerTypeRead,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "The name of the server type",
},
"arch": {
Type: schema.TypeString,
Computed: true,
Description: "The architecture of the server type",
},
"cpu": {
Type: schema.TypeInt,
Computed: true,
Description: "The number of CPU cores of the server type",
},
"ram": {
Type: schema.TypeInt,
Computed: true,
Description: "The number of bytes of RAM of the server type",
},
"gpu": {
Type: schema.TypeInt,
Computed: true,
Description: "The number of GPUs of the server type",
},
"volumes": {
Type: schema.TypeList,
Computed: true,
Description: "The specifications of volumes allowed for the server type",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"min_size_total": {
Type: schema.TypeInt,
Computed: true,
Description: "The minimum total size in bytes of volumes allowed on the server type",
},
"max_size_total": {
Type: schema.TypeInt,
Computed: true,
Description: "The maximum total size in bytes of volumes allowed on the server type",
},
"min_size_per_local_volume": {
Type: schema.TypeInt,
Computed: true,
Description: "The minimum size in bytes per local volume allowed on the server type",
},
"max_size_per_local_volume": {
Type: schema.TypeInt,
Computed: true,
Description: "The maximum size in bytes per local volume allowed on the server type",
},
"scratch_storage_max_size": {
Type: schema.TypeInt,
Computed: true,
Description: "The maximum size in bytes of the scratch volume allowed on the server type",
},
"block_storage": {
Type: schema.TypeBool,
Computed: true,
Description: "Whether block storage is allowed on the server type",
},
},
},
},
"capabilities": {
Type: schema.TypeList,
Computed: true,
Description: "The specific capabilities of the server type",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"boot_types": {
Type: schema.TypeList,
Computed: true,
Description: "The list of boot types allowed for the server type",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"max_file_systems": {
Type: schema.TypeInt,
Computed: true,
Description: "The maximum number of file systems that can be attached to the server type",
},
},
},
},
"network": {
Type: schema.TypeList,
Computed: true,
Description: "The network specifications of the server type",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"internal_bandwidth": {
Type: schema.TypeInt,
Computed: true,
Description: "The internal bandwidth of the server type",
},
"public_bandwidth": {
Type: schema.TypeInt,
Computed: true,
Description: "The public bandwidth of the server type",
},
"block_bandwidth": {
Type: schema.TypeInt,
Computed: true,
Description: "The block bandwidth of the server type",
},
},
},
},
"hourly_price": {
Type: schema.TypeFloat,
Computed: true,
Description: "The hourly price of the server type in euro",
},
"end_of_service": {
Type: schema.TypeBool,
Computed: true,
Description: "Whether the server type will soon reach End Of Service",
},
"availability": {
Type: schema.TypeString,
Computed: true,
Description: "Whether the server type is available in the zone",
},
"zone": zonal.Schema(),
},
}
}

func DataSourceInstanceServerTypeRead(ctx context.Context, d *schema.ResourceData, i any) diag.Diagnostics {
instanceAPI, zone, err := newAPIWithZone(d, i)
if err != nil {
return diag.FromErr(err)
}

serverTypes, err := instanceAPI.ListServersTypes(&instance.ListServersTypesRequest{
Zone: zone,
}, scw.WithAllPages(), scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

name := d.Get("name").(string)

serverType, ok := serverTypes.Servers[name]
if !ok {
return diag.Errorf("server type %s not found", name)
}

d.SetId(name)
_ = d.Set("name", name)
_ = d.Set("zone", zone)
_ = d.Set("arch", serverType.Arch)
_ = d.Set("cpu", int(serverType.Ncpus))
_ = d.Set("ram", int(serverType.RAM))
_ = d.Set("volumes", flattenVolumeConstraints(serverType))
_ = d.Set("capabilities", flattenCapabilities(serverType.Capabilities))
_ = d.Set("network", flattenNetwork(serverType))
_ = d.Set("end_of_service", serverType.EndOfService)

if serverType.Gpu != nil {
_ = d.Set("gpu", int(*serverType.Gpu))
}

// Price (needs to be fetched from the Product Catalog)
pcuAPI := product_catalog.NewPublicCatalogAPI(meta.ExtractScwClient(i))

pcuInstances, err := pcuAPI.ListPublicCatalogProducts(&product_catalog.PublicCatalogAPIListPublicCatalogProductsRequest{
ProductTypes: []product_catalog.ListPublicCatalogProductsRequestProductType{
product_catalog.ListPublicCatalogProductsRequestProductTypeInstance,
},
Zone: &zone,
}, scw.WithAllPages(), scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

for _, pcuInstance := range pcuInstances.Products {
if pcuInstance.Properties.Instance.OfferID != name {
continue
}

_ = d.Set("hourly_price", pcuInstance.Price.RetailPrice.ToFloat())
}

// Availability
availabilitiesResponse, err := instanceAPI.GetServerTypesAvailability(&instance.GetServerTypesAvailabilityRequest{
Zone: zone,
}, scw.WithAllPages(), scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

if availability, exists := availabilitiesResponse.Servers[name]; exists {
_ = d.Set("availability", availability.Availability.String())
}

return nil
}

func flattenVolumeConstraints(serverType *instance.ServerType) []map[string]any {
flattened := map[string]any{}

if serverType.VolumesConstraint != nil {
flattened["min_size_total"] = serverType.VolumesConstraint.MinSize
flattened["max_size_total"] = serverType.VolumesConstraint.MaxSize
}

if serverType.PerVolumeConstraint != nil && serverType.PerVolumeConstraint.LSSD != nil {
flattened["min_size_per_local_volume"] = serverType.PerVolumeConstraint.LSSD.MinSize
flattened["max_size_per_local_volume"] = serverType.PerVolumeConstraint.LSSD.MaxSize
}

if serverType.ScratchStorageMaxSize != nil {
flattened["scratch_storage_max_size"] = serverType.ScratchStorageMaxSize
}

if serverType.Capabilities != nil && serverType.Capabilities.BlockStorage != nil {
flattened["block_storage"] = *serverType.Capabilities.BlockStorage
}

return []map[string]any{flattened}
}

func flattenCapabilities(capabilities *instance.ServerTypeCapabilities) []map[string]any {
if capabilities == nil {
return nil
}

bootTypes := []string(nil)
for _, bootType := range capabilities.BootTypes {
bootTypes = append(bootTypes, bootType.String())
}

flattened := map[string]any{
"max_file_systems": capabilities.MaxFileSystems,
"boot_types": bootTypes,
}

return []map[string]any{flattened}
}

func flattenNetwork(serverType *instance.ServerType) []map[string]any {
if serverType.Network == nil {
return nil
}

flattened := map[string]any{}

if serverType.Network.SumInternalBandwidth != nil {
flattened["internal_bandwidth"] = *serverType.Network.SumInternalBandwidth
}

if serverType.Network.SumInternetBandwidth != nil {
flattened["public_bandwidth"] = *serverType.Network.SumInternetBandwidth
}

if serverType.BlockBandwidth != nil {
flattened["block_bandwidth"] = *serverType.BlockBandwidth
}

return []map[string]any{flattened}
}
Loading
Loading