Skip to content

Commit e2805da

Browse files
committed
feat(block): support export to s3
1 parent 0bc2393 commit e2805da

File tree

4 files changed

+12737
-5
lines changed

4 files changed

+12737
-5
lines changed

docs/resources/block_snapshot.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,43 @@ resource "scaleway_block_snapshot" "block_snapshot" {
2929
}
3030
```
3131

32+
### Import from Object Storage
33+
34+
```terraform
35+
resource "scaleway_object_bucket" "my-import-bucket" {
36+
name = "snapshot-bucket-to-import"
37+
}
38+
39+
resource "scaleway_object" "qcow-object" {
40+
bucket = scaleway_object_bucket.snapshot-bucket.name
41+
key = "my-snapshot.qcow2"
42+
file = "imported-snapshot/snapshot.qcow2"
43+
}
44+
resource "scaleway_block_volume" "imported" {
45+
iops = 5000
46+
name = "imported-from-qcow"
47+
48+
import {
49+
bucket = "my-import-bucket"
50+
key = "imported-snapshot/snapshot.qcow2"
51+
}
52+
}
53+
```
54+
55+
### Export to Object Storage
56+
57+
```terraform
58+
resource "scaleway_block_volume" "to_export" {
59+
iops = 5000
60+
name = "to-export"
61+
62+
export {
63+
bucket = "my-export-bucket"
64+
key = "exports/volume.qcow2"
65+
}
66+
}
67+
```
68+
3269
## Argument Reference
3370

3471
This section lists the arguments that are supported:
@@ -38,6 +75,12 @@ This section lists the arguments that are supported:
3875
- `zone` - (Defaults to the zone specified in the [provider configuration](../index.md#zone)). The [zone](../guides/regions_and_zones.md#zones) in which the snapshot should be created.
3976
- `project_id` - (Defaults to the Project ID specified in the [provider configuration](../index.md#project_id)). The ID of the Scaleway Project the snapshot is associated with.
4077
- `tags` - (Optional) A list of tags to apply to the snapshot.
78+
- `import` - (Optional) Use this block to import a QCOW image from Object Storage to create a volume.
79+
- `bucket` – (Required) The name of the bucket containing the QCOW file.
80+
- `key` – (Required) The key of the QCOW file within the bucket.
81+
- `export` - (Optional) Use this block to export the volume as a QCOW file to Object Storage.
82+
- `bucket` – (Required) The name of the bucket where the QCOW file will be saved.
83+
- `key` – (Required) The desired key (path) for the QCOW file within the bucket.
4184

4285
## Attributes Reference
4386

internal/services/block/snapshot.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,12 @@ func ResourceSnapshot() *schema.Resource {
8686
},
8787
"export": {
8888
Type: schema.TypeList,
89-
ForceNew: true,
9089
MaxItems: 1,
9190
Elem: &schema.Resource{
9291
Schema: map[string]*schema.Schema{
9392
"bucket": {
9493
Type: schema.TypeString,
9594
Required: true,
96-
ForceNew: true,
9795
Description: "Bucket containing qcow",
9896
DiffSuppressFunc: dsf.Locality,
9997
StateFunc: func(i any) string {
@@ -103,7 +101,6 @@ func ResourceSnapshot() *schema.Resource {
103101
"key": {
104102
Type: schema.TypeString,
105103
Required: true,
106-
ForceNew: true,
107104
Description: "Key of the qcow file in the specified bucket",
108105
},
109106
},
@@ -239,7 +236,7 @@ func ResourceBlockSnapshotUpdate(ctx context.Context, d *schema.ResourceData, m
239236
return diag.FromErr(err)
240237
}
241238

242-
if _, shouldExport := d.GetOk("export"); shouldExport {
239+
if shouldExport := d.HasChange("export"); shouldExport {
243240
req := block.ExportSnapshotToObjectStorageRequest{
244241
Zone: zone,
245242
SnapshotID: snapshot.ID,

internal/services/block/snapshot_test.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,24 @@ func TestAccSnapshot_ToS3(t *testing.T) {
102102
Steps: []resource.TestStep{
103103
{
104104
Config: fmt.Sprintf(`
105+
resource scaleway_block_volume main {
106+
iops = 5000
107+
size_in_gb = 10
108+
}
109+
105110
resource "scaleway_object_bucket" "snapshot-bucket" {
106111
name = "%s"
107112
}
108113
109114
resource "scaleway_object" "qcow-object" {
110115
bucket = scaleway_object_bucket.snapshot-bucket.name
111116
key = "test-acc-export-block-snapshot-qcow2"
117+
content = "test"
112118
}
113119
114120
resource "scaleway_block_snapshot" "qcow-block-snapshot" {
115-
name = "test-acc-block-snapshot-qcow2"
121+
name = "test-acc-export-block-snapshot-qcow2"
122+
volume_id = scaleway_block_volume.main.id
116123
export {
117124
bucket = scaleway_object.qcow-object.bucket
118125
key = scaleway_object.qcow-object.key
@@ -126,6 +133,59 @@ func TestAccSnapshot_ToS3(t *testing.T) {
126133
objectchecks.TestAccCheckObjectExists(tt, "scaleway_object.qcow-object"),
127134
),
128135
},
136+
{
137+
Config: fmt.Sprintf(`
138+
resource scaleway_block_volume main {
139+
iops = 5000
140+
size_in_gb = 10
141+
}
142+
143+
resource "scaleway_object_bucket" "snapshot-bucket" {
144+
name = "%s"
145+
}
146+
147+
resource "scaleway_object" "qcow-object" {
148+
bucket = scaleway_object_bucket.snapshot-bucket.name
149+
key = "test-acc-export-block-snapshot-qcow2"
150+
content = "test"
151+
}
152+
153+
resource "scaleway_block_snapshot" "qcow-block-export-snapshot" {
154+
name = "test-acc-export-block-snapshot-qcow2"
155+
volume_id = scaleway_block_volume.main.id
156+
export {
157+
bucket = scaleway_object.qcow-object.bucket
158+
key = scaleway_object.qcow-object.key
159+
}
160+
}
161+
162+
resource "scaleway_block_snapshot" "qcow-block-import-snapshot" {
163+
name = "test-acc-block-snapshot-qcow2"
164+
import {
165+
bucket = scaleway_object.qcow-object.bucket
166+
key = scaleway_object.qcow-object.key
167+
}
168+
}
169+
170+
resource scaleway_block_volume new-volume {
171+
name = "test-block-volume-from-snapshot"
172+
iops = 5000
173+
snapshot_id = scaleway_block_snapshot.qcow-block-import-snapshot.id
174+
}
175+
176+
`, bucketName),
177+
Check: resource.ComposeTestCheckFunc(
178+
blocktestfuncs.IsSnapshotPresent(tt, "scaleway_block_snapshot.qcow-block-export-snapshot"),
179+
acctest.CheckResourceAttrUUID("scaleway_block_snapshot.qcow-block-export-snapshot", "id"),
180+
resource.TestCheckResourceAttr("scaleway_block_snapshot.qcow-block-export-snapshot", "name", "test-acc-export-block-snapshot-qcow2"),
181+
objectchecks.TestAccCheckObjectExists(tt, "scaleway_object.qcow-object"),
182+
blocktestfuncs.IsSnapshotPresent(tt, "scaleway_block_snapshot.qcow-block-import-snapshot"),
183+
acctest.CheckResourceAttrUUID("scaleway_block_snapshot.qcow-block-import-snapshot", "id"),
184+
resource.TestCheckResourceAttr("scaleway_block_volume.new-volume", "size_in_gb", "10"),
185+
resource.TestCheckResourceAttr("scaleway_block_volume.new-volume", "iops", "5000"),
186+
resource.TestCheckResourceAttrPair("scaleway_block_volume.new-volume", "snapshot_id", "scaleway_block_snapshot.qcow-block-import-snapshot", "id"),
187+
),
188+
},
129189
},
130190
})
131191
}

0 commit comments

Comments
 (0)