Skip to content

Commit a653a0c

Browse files
authored
Merge branch 'master' into instance_server_type_data_source
2 parents 471a987 + 1ea7ad4 commit a653a0c

24 files changed

+22425
-3582
lines changed

docs/data-sources/instance_servers.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ In addition to all above arguments, the following attributes are exported:
4646
- `tags` - The tags associated with the server.
4747
- `public_ip` - The public IP address of the server.
4848
- `private_ip` - The Scaleway internal IP address of the server.
49+
- `private_ips` - The list of private IPv4 and IPv6 addresses associated with the server.
50+
- `id` - The ID of the IP address resource.
51+
- `address` - The private IP address.
4952
- `public_ips` - The list of public IPs of the server
5053
- `id` - The ID of the IP
5154
- `address` - The address of the IP

docs/guides/backend_guide.md

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
page_title: "Using Backend Guide"
33
---
4+
# Configuring Terraform Backends: PostgreSQL vs Object Storage
45

5-
# Terraform Backend
6+
## Configuring a Terraform Backend with PostgreSQL and State Locking
67

7-
This page describes how to configure a backend by adding the backend block to your configuration with the Terraform Scaleway Provider.
8+
This guide explains how to configure a remote backend using the Terraform Scaleway Provider with PostgreSQL, enabling remote state management with locking.
89

910
Terraform provides the option to set up a [“backend”](https://developer.hashicorp.com/terraform/language/backend) of the `state` data files.
1011

@@ -13,7 +14,7 @@ This option allows you to handle the state and the way certain operations are ex
1314
Backends can store the state remotely and protect it with locks to prevent corruption;
1415
it makes it possible for a team to work with ease, or, for instance, to run Terraform within a pipeline.
1516

16-
## Create your database
17+
### Create your database
1718

1819
You can create your database resource using terraform itself .
1920

@@ -60,19 +61,19 @@ and deploy it:
6061
terraform plan -out "planfile" ; terraform apply -input=false -auto-approve "planfile"
6162
```
6263

63-
## Configuring the PostgreSQL Connection String
64+
#### Configuring the PostgreSQL Connection String
6465

6566
We choose to set our environment variable for the connection string for this guide. Please check the [secret section](#secrets) for more details.
6667

6768
```shell
6869
export PG_CONN_STR=postgres://<user>:<pass>@localhost:<port>/terraform_backend?sslmode=disable
6970
```
7071

71-
## Secrets
72+
#### Secrets
7273

7374
Hashicorp offers several methods to keep your secrets. Please check the Terraform [partial configuration](https://developer.hashicorp.com/terraform/language/backend#partial-configuration) for this topic.
7475

75-
## Create your infrastructure with the Scaleway provider
76+
#### Create your infrastructure with the Scaleway provider
7677

7778
```hcl
7879
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -126,7 +127,7 @@ AND TABLE_NAME = 'states';
126127
....
127128
```
128129

129-
## Multiple Workplaces
130+
### Multiple Workplaces
130131

131132
You can configure several `states` on your database using a different `schema_name`.
132133

@@ -145,7 +146,7 @@ terraform {
145146
}
146147
```
147148

148-
## Migrating the state
149+
### Migrating the state
149150

150151
Considering you have already running infrastructure you want to use the `backend` option.
151152

@@ -159,15 +160,15 @@ Answer the prompt `yes`, and your state will migrate.
159160
$ terraform init -backend-config="conn_str=${PG_CONN_STR}" -migrate-state
160161
```
161162

162-
## What about locking?
163+
### What about locking?
163164

164165
Most of the remote [backends](https://developer.hashicorp.com/terraform/language/backend#backend-types) natively support locking. To run terraform apply, Terraform will automatically acquire a lock;
165166
if someone else is already running apply, they will already have the lock, and you will have to wait.
166167
You can run apply with the `-lock-timeout=<TIME>` parameter to tell Terraform to wait up to TIME for a lock to be released (e.g., `-lock-timeout=10m` will wait for 10 minutes).
167168

168169
The Lock method prevents opening the state file while already in use.
169170

170-
## Share configuration
171+
### Share configuration
171172

172173
You can also share the configuration using the different [data sources](https://www.terraform.io/language/state/remote-state-data).
173174
This is useful when working on the same infrastructure or the same team.
@@ -177,3 +178,68 @@ data "scaleway_rdb_instance" "mybackend" {
177178
name = "your-database-name"
178179
}
179180
```
181+
182+
## Alternative: Store Terraform State in Scaleway Object Storage (Without Locking)
183+
184+
[Scaleway object storage](https://www.scaleway.com/en/object-storage/) can be used to store your Terraform state.
185+
However, this backend does not support state locking, which is critical when multiple users or automated processes might access the same state concurrently.
186+
Configure your backend as:
187+
188+
```
189+
terraform {
190+
backend "s3" {
191+
bucket = "terraform-state"
192+
key = "my_state.tfstate"
193+
region = "fr-par"
194+
endpoint = "https://s3.fr-par.scw.cloud"
195+
access_key = "my-access-key"
196+
secret_key = "my-secret-key"
197+
skip_credentials_validation = true
198+
force_path_style = true
199+
skip_region_validation = true
200+
# Need terraform>=1.6.1
201+
skip_requesting_account_id = true
202+
}
203+
}
204+
```
205+
206+
Warning: This backend does not offer locking. If you're working in a team or running Terraform in CI/CD pipelines, using object storage without locking can lead to state corruption.
207+
208+
### Securing credentials
209+
210+
To avoid hardcoding secrets in your Terraform configuration, use one of the following secure methods:
211+
212+
#### Environment Variables
213+
214+
Set the credentials in your shell environment using the AWS-compatible variable names:
215+
216+
```shell
217+
export AWS_ACCESS_KEY_ID=$SCW_ACCESS_KEY
218+
export AWS_SECRET_ACCESS_KEY=$SCW_SECRET_KEY
219+
```
220+
221+
This approach is simple and works well for scripts, local development, and CI pipelines.
222+
223+
#### AWS Credentials Files
224+
225+
Store your credentials in:
226+
227+
- `~/.aws/credentials` – for secrets
228+
- `~/.aws/config` – for configuration like profiles or regions
229+
230+
Example ~/.aws/credentials file:
231+
232+
```
233+
[default]
234+
aws_access_key_id = YOUR_SCW_ACCESS_KEY
235+
aws_secret_access_key = YOUR_SCW_SECRET_KEY
236+
```
237+
238+
This method is ideal for managing multiple profiles or persisting configuration across sessions.
239+
240+
Both methods are compatible with Terraform’s S3 backend, which also works with Scaleway Object Storage.
241+
242+
For full details, see the official [Terraform S3 backend documentation](https://developer.hashicorp.com/terraform/language/backend/s3#access_key)
243+
244+
For example configuration files, refer to the [Object Storage documentation](https://www.scaleway.com/en/docs/object-storage/api-cli/object-storage-aws-cli/)
245+

docs/index.md

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -221,38 +221,9 @@ In addition to [generic provider arguments](https://www.terraform.io/docs/config
221221
| `region` | `SCW_DEFAULT_REGION` | The [region](./guides/regions_and_zones.md#regions) that will be used as default value for all resources. (`fr-par` if none specified) | |
222222
| `zone` | `SCW_DEFAULT_ZONE` | The [zone](./guides/regions_and_zones.md#zones) that will be used as default value for all resources. (`fr-par-1` if none specified) | |
223223

224-
## Store terraform state on Scaleway S3-compatible object storage
224+
## Store terraform state
225225

226-
[Scaleway object storage](https://www.scaleway.com/en/object-storage/) can be used to store your Terraform state.
227-
Configure your backend as:
228-
229-
```
230-
terraform {
231-
backend "s3" {
232-
bucket = "terraform-state"
233-
key = "my_state.tfstate"
234-
region = "fr-par"
235-
endpoint = "https://s3.fr-par.scw.cloud"
236-
access_key = "my-access-key"
237-
secret_key = "my-secret-key"
238-
skip_credentials_validation = true
239-
skip_region_validation = true
240-
# Need terraform>=1.6.1
241-
skip_requesting_account_id = true
242-
}
243-
}
244-
```
245-
246-
Be careful as no locking mechanism are yet supported.
247-
Using scaleway object storage as terraform backend is not suitable if you work in a team with a risk of simultaneous access to the same plan.
248-
249-
Note: For security reason it's not recommended to store secrets in terraform files.
250-
If you want to configure the backend with environment var, you need to use `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` [source](https://www.terraform.io/docs/backends/types/s3.html#access_key).
251-
252-
```bash
253-
export AWS_ACCESS_KEY_ID=$SCW_ACCESS_KEY
254-
export AWS_SECRET_ACCESS_KEY=$SCW_SECRET_KEY
255-
```
226+
For detailed instructions and best practices, see the full [Backend guide](guides/backend_guide.md)
256227

257228
## Custom User-Agent Information
258229

docs/resources/instance_security_group.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ resource "scaleway_instance_security_group" "web" {
2121
inbound_rule {
2222
action = "accept"
2323
port = 22
24-
ip = "212.47.225.64"
24+
ip_range = "212.47.225.64/32"
2525
}
2626
2727
inbound_rule {
@@ -46,13 +46,13 @@ resource "scaleway_instance_security_group" "web" {
4646
4747
inbound_rule {
4848
action = "drop"
49-
ip = "1.1.1.1" # Banned IP
49+
ip_range = "1.1.1.1/32" # Banned IP range
5050
}
5151
5252
inbound_rule {
5353
action = "accept"
5454
port = 22
55-
ip = "212.47.225.64"
55+
ip_range = "212.47.225.64/32"
5656
}
5757
5858
inbound_rule {
@@ -62,7 +62,7 @@ resource "scaleway_instance_security_group" "web" {
6262
6363
outbound_rule {
6464
action = "accept"
65-
ip = "8.8.8.8" # Only allow outgoing connection to this IP.
65+
ip_range = "8.8.8.8/32" # Only allow outgoing connection to this IP range.
6666
}
6767
}
6868
```
@@ -86,7 +86,7 @@ resource "scaleway_instance_security_group" "dummy" {
8686
content {
8787
action = "accept"
8888
port = 22
89-
ip = inbound_rule.value
89+
ip_range = inbound_rule.value
9090
}
9191
}
9292
}
@@ -132,7 +132,7 @@ The `inbound_rule` and `outbound_rule` block supports:
132132
If no `port` nor `port_range` are specified, rule will apply to all port.
133133
Only one of `port` and `port_range` should be specified.
134134

135-
- `ip`- (Optional) The ip this rule apply to. If no `ip` nor `ip_range` are specified, rule will apply to all ip. Only one of `ip` and `ip_range` should be specified.
135+
- `ip`- (Deprecated) The ip this rule apply to. If no `ip` nor `ip_range` are specified, rule will apply to all ip. Only one of `ip` and `ip_range` should be specified.
136136

137137
- `ip_range`- (Optional) The ip range (e.g `192.168.1.0/24`) this rule applies to. If no `ip` nor `ip_range` are specified, rule will apply to all ip. Only one of `ip` and `ip_range` should be specified.
138138

docs/resources/instance_security_group_rules.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ resource "scaleway_instance_security_group" "main" {
4646
4747
locals {
4848
trusted = [
49-
"1.2.3.4",
50-
"4.5.6.7",
51-
"7.8.9.10"
49+
"1.2.3.4/32",
50+
"4.5.6.7/32",
51+
"7.8.9.10/24"
5252
]
5353
}
5454
@@ -59,7 +59,7 @@ resource "scaleway_instance_security_group_rules" "main" {
5959
for_each = local.trusted
6060
content {
6161
action = "accept"
62-
ip = inbound_rule.value
62+
ip_range = inbound_rule.value
6363
port = 80
6464
}
6565
}
@@ -79,9 +79,9 @@ resource "scaleway_instance_security_group" "main" {
7979
8080
locals {
8181
trusted = [
82-
{ ip = "1.2.3.4", port = "80" },
83-
{ ip = "5.6.7.8", port = "81" },
84-
{ ip = "9.10.11.12", port = "81" },
82+
{ ip_range = "1.2.3.4/32", port = "80" },
83+
{ ip_range = "5.6.7.8/32", port = "81" },
84+
{ ip_range = "9.10.11.12/32", port = "81" },
8585
]
8686
}
8787
@@ -92,7 +92,7 @@ resource "scaleway_instance_security_group_rules" "main" {
9292
for_each = local.trusted
9393
content {
9494
action = "accept"
95-
ip = inbound_rule.value.ip
95+
ip_range = inbound_rule.value.ip_range
9696
port = inbound_rule.value.port
9797
}
9898
}
@@ -122,7 +122,7 @@ The `inbound_rule` and `outbound_rule` block supports:
122122
If no `port` nor `port_range` are specified, rule will apply to all port.
123123
Only one of `port` and `port_range` should be specified.
124124

125-
- `ip`- (Optional) The ip this rule apply to. If no `ip` nor `ip_range` are specified, rule will apply to all ip. Only one of `ip` and `ip_range` should be specified.
125+
- `ip`- (Deprecated) The ip this rule apply to. If no `ip` nor `ip_range` are specified, rule will apply to all ip. Only one of `ip` and `ip_range` should be specified.
126126

127127
- `ip_range`- (Optional) The ip range (e.g `192.168.1.0/24`) this rule applies to. If no `ip` nor `ip_range` are specified, rule will apply to all ip. Only one of `ip` and `ip_range` should be specified.
128128

docs/resources/instance_snapshot.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ resource "scaleway_instance_server" "main" {
4040
4141
resource "scaleway_instance_snapshot" "main" {
4242
volume_id = scaleway_instance_volume.main.id
43-
type = "unified"
4443
depends_on = [scaleway_instance_server.main]
4544
}
4645
```
@@ -59,7 +58,6 @@ resource "scaleway_object" "qcow" {
5958
}
6059
6160
resource "scaleway_instance_snapshot" "snapshot" {
62-
type = "unified"
6361
import {
6462
bucket = scaleway_object.qcow.bucket
6563
key = scaleway_object.qcow.key
@@ -72,11 +70,12 @@ resource "scaleway_instance_snapshot" "snapshot" {
7270
The following arguments are supported:
7371

7472
- `volume_id` - (Optional) The ID of the volume to take a snapshot from.
75-
- `type` - (Optional) The snapshot's volume type. The possible values are: `l_ssd` (Local SSD) and `unified`.
73+
- `type` - (Default to `l_ssd`) The snapshot's volume type. The possible values are: `l_ssd` (Local SSD).
7674
Updates to this field will recreate a new resource.
7775

7876
~> **Important:** Snapshots of volumes with type `b_ssd` (Block SSD) are deprecated and cannot be managed using the `scaleway_instance_snapshot` resource anymore. Please use the `scaleway_block_snapshot` resource instead.
7977
If you want to migrate existing snapshots, you can visit [this page](https://www.scaleway.com/en/docs/instances/how-to/migrate-volumes-snapshots-to-sbs/) for more information.
78+
~> **Important:** Snapshots of volumes with type `unified` (can be used with both Block and Local SSD) are deprecated since the migration to SBS.
8079

8180
- `name` - (Optional) The name of the snapshot. If not provided it will be randomly generated.
8281
- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which
@@ -88,8 +87,6 @@ If you want to migrate existing snapshots, you can visit [this page](https://www
8887
- `bucket` - Bucket name containing [qcow2](https://en.wikipedia.org/wiki/Qcow) to import
8988
- `key` - Key of the object to import
9089

91-
-> **Note:** The type `unified` could be instantiated on both `l_ssd` and `b_ssd` volumes.
92-
9390
## Attributes Reference
9491

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

internal/services/block/helpers_block.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99
block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1"
1010
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
1111
"github.com/scaleway/scaleway-sdk-go/scw"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/dsf"
1213
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
14+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
1315
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
1416
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
1517
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/instance/instancehelpers"
@@ -56,6 +58,32 @@ func customDiffCannotShrink(key string) schema.CustomizeDiffFunc {
5658
})
5759
}
5860

61+
func customDiffSnapshot(key string) schema.CustomizeDiffFunc {
62+
return func(ctx context.Context, diff *schema.ResourceDiff, i any) error {
63+
if !diff.HasChange(key) {
64+
return nil
65+
}
66+
67+
oldValue, newValue := diff.GetChange(key)
68+
if dsf.Locality(key, oldValue.(string), newValue.(string), nil) {
69+
return nil
70+
}
71+
72+
blockAPI := block.NewAPI(meta.ExtractScwClient(i))
73+
zone, id, _ := locality.ParseLocalizedID(oldValue.(string))
74+
75+
_, err := blockAPI.GetSnapshot(&block.GetSnapshotRequest{
76+
SnapshotID: id,
77+
Zone: scw.Zone(zone),
78+
})
79+
if (httperrors.Is403(err) || httperrors.Is404(err)) && newValue == "" {
80+
return nil
81+
}
82+
83+
return diff.ForceNew(key)
84+
}
85+
}
86+
5987
func migrateInstanceToBlockVolume(ctx context.Context, api *instancehelpers.BlockAndInstanceAPI, zone scw.Zone, volumeID string, timeout time.Duration) (*block.Volume, error) {
6088
instanceVolumeResp, err := api.GetVolume(&instance.GetVolumeRequest{
6189
Zone: zone,

0 commit comments

Comments
 (0)