Skip to content

Commit 090ddde

Browse files
authored
fix(instance): remove volume name when using image (#1390)
changed image to optional as it should not be used when using a volume id
1 parent 28b5b4b commit 090ddde

27 files changed

+63186
-69844
lines changed

docs/resources/instance_server.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ The following arguments are supported:
137137
You find all the available types on the [pricing page](https://www.scaleway.com/en/pricing/).
138138
Updates to this field will recreate a new resource.
139139

140-
- `image` - (Required) The UUID or the label of the base image used by the server. You can use [this endpoint](https://api-marketplace.scaleway.com/images?page=1&per_page=100)
141-
to find either the right `label` or the right local image `ID` for a given `type`.
140+
- `image` - (Optional) The UUID or the label of the base image used by the server. You can use [this endpoint](https://api-marketplace.scaleway.com/images?page=1&per_page=100)
141+
to find either the right `label` or the right local image `ID` for a given `type`. Optional when creating an instance with an existing root volume.
142142

143143
You can check the available labels with our [CLI](https://www.scaleway.com/en/docs/compute/instances/api-cli/creating-managing-instances-with-cliv2/). ```scw marketplace image list```
144144

@@ -156,7 +156,7 @@ To retrieve more information by label please use: ```scw marketplace image get l
156156
~> **Important:** When updating `placement_group_id` the `state` must be set to `stopped`, otherwise it will fail.
157157

158158
- `root_volume` - (Optional) Root [volume](https://developers.scaleway.com/en/products/instance/api/#volumes-7e8a39) attached to the server on creation.
159-
- `volume_id` - (Optional) The volume ID of the root volume of the server, allows you to create server with an existing volume. If empty, will be computed to a created volume ID
159+
- `volume_id` - (Optional) The volume ID of the root volume of the server, allows you to create server with an existing volume. If empty, will be computed to a created volume ID.
160160
- `size_in_gb` - (Required) Size of the root volume in gigabytes.
161161
To find the right size use [this endpoint](https://api.scaleway.com/instance/v1/zones/fr-par-1/products/servers) and
162162
check the `volumes_constraint.{min|max}_size` (in bytes) for your `commercial_type`.

scaleway/resource_instance_server.go

+15-4
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func resourceScalewayInstanceServer() *schema.Resource {
4646
},
4747
"image": {
4848
Type: schema.TypeString,
49-
Required: true,
49+
Optional: true,
5050
ForceNew: true,
5151
Description: "The UUID or the label of the base image used by the server",
5252
DiffSuppressFunc: diffSuppressFuncLocality,
@@ -92,6 +92,11 @@ func resourceScalewayInstanceServer() *schema.Resource {
9292
Description: "Root volume attached to the server on creation",
9393
Elem: &schema.Resource{
9494
Schema: map[string]*schema.Schema{
95+
"name": {
96+
Type: schema.TypeString,
97+
Computed: true,
98+
Description: "Name of the root volume",
99+
},
95100
"size_in_gb": {
96101
Type: schema.TypeInt,
97102
Optional: true,
@@ -278,8 +283,8 @@ func resourceScalewayInstanceServerCreate(ctx context.Context, d *schema.Resourc
278283

279284
commercialType := d.Get("type").(string)
280285

281-
imageUUID := expandZonedID(d.Get("image")).ID
282-
if !scwvalidation.IsUUID(imageUUID) {
286+
imageUUID := expandID(d.Get("image"))
287+
if imageUUID != "" && !scwvalidation.IsUUID(imageUUID) {
283288
marketPlaceAPI := marketplace.NewAPI(meta.(*Meta).scwClient)
284289
imageUUID, err = marketPlaceAPI.GetLocalImageIDByLabel(&marketplace.GetLocalImageIDByLabelRequest{
285290
CommercialType: commercialType,
@@ -356,8 +361,13 @@ func resourceScalewayInstanceServerCreate(ctx context.Context, d *schema.Resourc
356361
size = scw.Size(uint64(sizeInput) * gb)
357362
}
358363

364+
rootVolumeName := newRandomName("vol")
365+
if req.Image != "" {
366+
rootVolumeName = ""
367+
}
368+
359369
req.Volumes["0"] = &instance.VolumeServerTemplate{
360-
Name: newRandomName("vol"), // name is ignored by the API, any name will work here
370+
Name: rootVolumeName,
361371
ID: rootVolumeID,
362372
VolumeType: instance.VolumeVolumeType(volumeType),
363373
Size: size,
@@ -583,6 +593,7 @@ func resourceScalewayInstanceServerRead(ctx context.Context, d *schema.ResourceD
583593
rootVolume["delete_on_termination"] = d.Get("root_volume.0.delete_on_termination").(bool) || !rootVolumeAttributeSet
584594
rootVolume["volume_type"] = volume.VolumeType
585595
rootVolume["boot"] = volume.Boot
596+
rootVolume["name"] = volume.Name
586597

587598
_ = d.Set("root_volume", []map[string]interface{}{rootVolume})
588599
} else {

scaleway/resource_instance_server_test.go

+27-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func TestAccScalewayInstanceServer_Minimal1(t *testing.T) {
7676
resource.TestCheckResourceAttr("scaleway_instance_server.base", "root_volume.0.delete_on_termination", "true"),
7777
resource.TestCheckResourceAttr("scaleway_instance_server.base", "root_volume.0.size_in_gb", "20"),
7878
resource.TestCheckResourceAttrSet("scaleway_instance_server.base", "root_volume.0.volume_id"),
79+
testAccCheckScalewayInstanceServerHasNewVolume(tt, "scaleway_instance_server.base"),
7980
resource.TestCheckResourceAttr("scaleway_instance_server.base", "enable_dynamic_ip", "false"),
8081
resource.TestCheckResourceAttr("scaleway_instance_server.base", "tags.0", "terraform-test"),
8182
resource.TestCheckResourceAttr("scaleway_instance_server.base", "tags.1", "scaleway_instance_server"),
@@ -98,6 +99,7 @@ func TestAccScalewayInstanceServer_Minimal1(t *testing.T) {
9899
resource.TestCheckResourceAttr("scaleway_instance_server.base", "root_volume.0.delete_on_termination", "true"),
99100
resource.TestCheckResourceAttr("scaleway_instance_server.base", "root_volume.0.size_in_gb", "20"),
100101
resource.TestCheckResourceAttrSet("scaleway_instance_server.base", "root_volume.0.volume_id"),
102+
testAccCheckScalewayInstanceServerHasNewVolume(tt, "scaleway_instance_server.base"),
101103
resource.TestCheckResourceAttr("scaleway_instance_server.base", "tags.0", "terraform-test"),
102104
resource.TestCheckResourceAttr("scaleway_instance_server.base", "tags.1", "scaleway_instance_server"),
103105
resource.TestCheckResourceAttr("scaleway_instance_server.base", "tags.2", "minimal"),
@@ -198,6 +200,7 @@ func TestAccScalewayInstanceServer_RootVolume1(t *testing.T) {
198200
}`,
199201
Check: resource.ComposeTestCheckFunc(
200202
testAccCheckScalewayInstanceServerExists(tt, "scaleway_instance_server.base"),
203+
testAccCheckScalewayInstanceServerHasNewVolume(tt, "scaleway_instance_server.base"),
201204
),
202205
},
203206
},
@@ -227,6 +230,7 @@ func TestAccScalewayInstanceServer_RootVolume_Boot(t *testing.T) {
227230
Check: resource.ComposeTestCheckFunc(
228231
testAccCheckScalewayInstanceServerExists(tt, "scaleway_instance_server.base"),
229232
resource.TestCheckResourceAttr("scaleway_instance_server.base", "root_volume.0.boot", "true"),
233+
testAccCheckScalewayInstanceServerHasNewVolume(tt, "scaleway_instance_server.base"),
230234
),
231235
},
232236
{
@@ -244,6 +248,7 @@ func TestAccScalewayInstanceServer_RootVolume_Boot(t *testing.T) {
244248
Check: resource.ComposeTestCheckFunc(
245249
testAccCheckScalewayInstanceServerExists(tt, "scaleway_instance_server.base"),
246250
resource.TestCheckResourceAttr("scaleway_instance_server.base", "root_volume.0.boot", "false"),
251+
testAccCheckScalewayInstanceServerHasNewVolume(tt, "scaleway_instance_server.base"),
247252
),
248253
},
249254
},
@@ -267,7 +272,6 @@ func TestAccScalewayInstanceServer_RootVolume_ID(t *testing.T) {
267272
}
268273
269274
resource "scaleway_instance_server" "base" {
270-
image = "ubuntu_focal"
271275
type = "DEV1-S"
272276
state = "stopped"
273277
root_volume {
@@ -978,6 +982,28 @@ func testAccCheckScalewayInstanceServerDestroy(tt *TestTools) resource.TestCheck
978982
}
979983
}
980984

985+
// testAccCheckScalewayInstanceServerHasNewVolume tests if volume name is generated by terraform
986+
// It is useful as volume should not be set in request when creating an instance from an image
987+
func testAccCheckScalewayInstanceServerHasNewVolume(tt *TestTools, n string) resource.TestCheckFunc {
988+
return func(s *terraform.State) error {
989+
rs, ok := s.RootModule().Resources[n]
990+
if !ok {
991+
return fmt.Errorf("resource not found: %s", n)
992+
}
993+
994+
rootVolumeName, ok := rs.Primary.Attributes["root_volume.0.name"]
995+
if !ok {
996+
return fmt.Errorf("instance root_volume has no name")
997+
}
998+
999+
if strings.HasPrefix(rootVolumeName, "tf") {
1000+
return fmt.Errorf("root volume name is generated by provider, should be generated by api (%s)", rootVolumeName)
1001+
}
1002+
1003+
return nil
1004+
}
1005+
}
1006+
9811007
func TestAccScalewayInstanceServer_Bootscript(t *testing.T) {
9821008
tt := NewTestTools(t)
9831009
defer tt.Cleanup()

0 commit comments

Comments
 (0)