Skip to content
Merged
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
31 changes: 31 additions & 0 deletions docs/data-sources/availability_zones.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
subcategory: "Account"
page_title: "Scaleway: scaleway_availability_zones"
---

# scaleway_availability_zones

Use this data source to get the available zones information based on its Region.

For technical and legal reasons, some products are split by Region or by Availability Zones. When using such product,
you can choose the location that better fits your need (country, latency, …).

## Example Usage

```hcl
# Get info by Region key
data scaleway_availability_zones main {
region = "nl-ams"
}
```

## Argument Reference

- `region` - Region is represented as a Geographical area such as France. Defaults: `fr-par`.

## Attributes Reference

In addition to all above arguments, the following attributes are exported:

- `id` - The Region ID
- `zones` - List of availability zones by regions
53 changes: 53 additions & 0 deletions scaleway/data_source_availability_zones.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package scaleway

import (
"context"
"fmt"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/scaleway/scaleway-sdk-go/scw"
"github.com/scaleway/scaleway-sdk-go/validation"
)

func DataSourceAvailabilityZones() *schema.Resource {
return &schema.Resource{
ReadWithoutTimeout: dataSourceAvailabilityZonesRead,

Timeouts: &schema.ResourceTimeout{
Read: schema.DefaultTimeout(20 * time.Minute),
},

Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Optional: true,
Description: "Region is represented as a Geographical area such as France",
Default: scw.RegionFrPar,
},
"zones": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Computed: true,
Description: "Availability Zones (AZ)",
},
},
}
}

func dataSourceAvailabilityZonesRead(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics {
regionStr := d.Get("region").(string)

if !validation.IsRegion(regionStr) {
return diag.FromErr(SingularDataSourceFindError("Availability Zone", fmt.Errorf("not a supported region %s", regionStr)))
}

region := scw.Region(regionStr)
d.SetId(regionStr)
_ = d.Set("zones", region.GetZones())

return nil
}
46 changes: 46 additions & 0 deletions scaleway/data_source_availability_zones_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package scaleway

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccScalewayDataSourceAvailabilityZones_Basic(t *testing.T) {
tt := NewTestTools(t)
defer tt.Cleanup()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: testAccCheckScalewayDomainRecordDestroy(tt),
Steps: []resource.TestStep{
{
Config: `
data scaleway_availability_zones main {
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"data.scaleway_availability_zones.main", "region", "fr-par"),
resource.TestCheckResourceAttr(
"data.scaleway_availability_zones.main", "zones.0", "fr-par-1"),
),
},
{
Config: `
data scaleway_availability_zones main {
region = "nl-ams"
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"data.scaleway_availability_zones.main", "region", "nl-ams"),
resource.TestCheckResourceAttr(
"data.scaleway_availability_zones.main", "zones.0", "nl-ams-1"),
resource.TestCheckResourceAttr(
"data.scaleway_availability_zones.main", "zones.1", "nl-ams-2"),
),
},
},
})
}
52 changes: 52 additions & 0 deletions scaleway/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/scaleway/scaleway-sdk-go/namegenerator"
Expand Down Expand Up @@ -954,3 +955,54 @@ func customizeDiffLocalityCheck(keys ...string) schema.CustomizeDiffFunc {
return nil
}
}

type TooManyResultsError struct {
Count int
LastRequest interface{}
}

func (e *TooManyResultsError) Error() string {
return fmt.Sprintf("too many results: wanted 1, got %d", e.Count)
}

func (e *TooManyResultsError) Is(err error) bool {
_, ok := err.(*TooManyResultsError) //nolint:errorlint // Explicitly does *not* match down the error tree
return ok
}

func (e *TooManyResultsError) As(target interface{}) bool {
t, ok := target.(**retry.NotFoundError)
if !ok {
return false
}

*t = &retry.NotFoundError{
Message: e.Error(),
LastRequest: e.LastRequest,
}

return true
}

var ErrTooManyResults = &TooManyResultsError{}

// SingularDataSourceFindError returns a standard error message for a singular data source's non-nil resource find error.
func SingularDataSourceFindError(resourceType string, err error) error {
if NotFound(err) {
if errors.Is(err, &TooManyResultsError{}) {
return fmt.Errorf("multiple %[1]ss matched; use additional constraints to reduce matches to a single %[1]s", resourceType)
}

return fmt.Errorf("no matching %[1]s found", resourceType)
}

return fmt.Errorf("reading %s: %w", resourceType, err)
}

// NotFound returns true if the error represents a "resource not found" condition.
// Specifically, NotFound returns true if the error or a wrapped error is of type
// retry.NotFoundError.
func NotFound(err error) bool {
var e *retry.NotFoundError // nosemgrep:ci.is-not-found-error
return errors.As(err, &e)
}
1 change: 1 addition & 0 deletions scaleway/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
DataSourcesMap: map[string]*schema.Resource{
"scaleway_account_project": dataSourceScalewayAccountProject(),
"scaleway_account_ssh_key": dataSourceScalewayAccountSSHKey(),
"scaleway_availability_zones": DataSourceAvailabilityZones(),
"scaleway_baremetal_offer": dataSourceScalewayBaremetalOffer(),
"scaleway_baremetal_option": dataSourceScalewayBaremetalOption(),
"scaleway_baremetal_os": dataSourceScalewayBaremetalOs(),
Expand Down