@@ -17,6 +17,7 @@ import (
17
17
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
18
18
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
19
19
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
20
+ block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1"
20
21
instanceSDK "github.com/scaleway/scaleway-sdk-go/api/instance/v1"
21
22
"github.com/scaleway/scaleway-sdk-go/api/marketplace/v2"
22
23
"github.com/scaleway/scaleway-sdk-go/scw"
@@ -150,6 +151,12 @@ func ResourceServer() *schema.Resource {
150
151
Description : "Volume ID of the root volume" ,
151
152
ExactlyOneOf : []string {"image" , "root_volume.0.volume_id" },
152
153
},
154
+ "sbs_iops" : {
155
+ Type : schema .TypeInt ,
156
+ Computed : true ,
157
+ Optional : true ,
158
+ Description : "SBS Volume IOPS, only with volume_type as sbs_volume" ,
159
+ },
153
160
},
154
161
},
155
162
},
@@ -374,7 +381,7 @@ func ResourceInstanceServerCreate(ctx context.Context, d *schema.ResourceData, m
374
381
CommercialType : commercialType ,
375
382
Zone : zone ,
376
383
ImageLabel : imageLabel ,
377
- Type : marketplace . LocalImageTypeInstanceLocal ,
384
+ Type : volumeTypeToMarketplaceFilter ( d . Get ( "root_volume.0.volume_type" )) ,
378
385
})
379
386
if err != nil {
380
387
return diag .FromErr (fmt .Errorf ("could not get image '%s': %s" , zonal .NewID (zone , imageLabel ), err ))
@@ -466,6 +473,18 @@ func ResourceInstanceServerCreate(ctx context.Context, d *schema.ResourceData, m
466
473
return diag .FromErr (err )
467
474
}
468
475
476
+ ////
477
+ // Configure Block Volume
478
+ ////
479
+ var diags diag.Diagnostics
480
+
481
+ if iops , ok := d .GetOk ("root_volume.0.sbs_iops" ); ok {
482
+ updateDiags := ResourceInstanceServerUpdateRootVolumeIOPS (ctx , api , zone , res .Server .ID , types .ExpandUint32Ptr (iops ))
483
+ if len (updateDiags ) > 0 {
484
+ diags = append (diags , updateDiags ... )
485
+ }
486
+ }
487
+
469
488
////
470
489
// Set user data
471
490
////
@@ -544,7 +563,7 @@ func ResourceInstanceServerCreate(ctx context.Context, d *schema.ResourceData, m
544
563
}
545
564
}
546
565
547
- return ResourceInstanceServerRead (ctx , d , m )
566
+ return append ( diags , ResourceInstanceServerRead (ctx , d , m ) ... )
548
567
}
549
568
550
569
func errorCheck (err error , message string ) bool {
@@ -553,12 +572,12 @@ func errorCheck(err error, message string) bool {
553
572
554
573
//gocyclo:ignore
555
574
func ResourceInstanceServerRead (ctx context.Context , d * schema.ResourceData , m interface {}) diag.Diagnostics {
556
- instanceAPI , zone , id , err := NewAPIWithZoneAndID (m , d .Id ())
575
+ api , zone , id , err := instanceAndBlockAPIWithZoneAndID (m , d .Id ())
557
576
if err != nil {
558
577
return diag .FromErr (err )
559
578
}
560
579
561
- server , err := waitForServer (ctx , instanceAPI , zone , id , d .Timeout (schema .TimeoutRead ))
580
+ server , err := waitForServer (ctx , api . API , zone , id , d .Timeout (schema .TimeoutRead ))
562
581
if err != nil {
563
582
if errorCheck (err , "is not found" ) {
564
583
log .Printf ("[WARN] instance %s not found droping from state" , d .Id ())
@@ -670,8 +689,23 @@ func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m i
670
689
rootVolume = vs [0 ]
671
690
}
672
691
673
- rootVolume ["volume_id" ] = zonal .NewID (zone , volume .ID ).String ()
674
- rootVolume ["size_in_gb" ] = int (uint64 (volume .Size ) / gb )
692
+ vol , err := api .GetUnknownVolume (& GetUnknownVolumeRequest {
693
+ VolumeID : volume .ID ,
694
+ Zone : volume .Zone ,
695
+ })
696
+ if err != nil {
697
+ return diag .FromErr (fmt .Errorf ("failed to read instance volume %s: %w" , volume .ID , err ))
698
+ }
699
+
700
+ rootVolume ["volume_id" ] = zonal .NewID (zone , vol .ID ).String ()
701
+ if vol .Size != nil {
702
+ rootVolume ["size_in_gb" ] = int (uint64 (* vol .Size ) / gb )
703
+ } else {
704
+ rootVolume ["size_in_gb" ] = int (uint64 (volume .Size ) / gb )
705
+ }
706
+ if vol .IsBlockVolume () {
707
+ rootVolume ["sbs_iops" ] = types .FlattenUint32Ptr (vol .Iops )
708
+ }
675
709
_ , rootVolumeAttributeSet := d .GetOk ("root_volume" ) // Related to https://github.com/hashicorp/terraform-plugin-sdk/issues/142
676
710
rootVolume ["delete_on_termination" ] = d .Get ("root_volume.0.delete_on_termination" ).(bool ) || ! rootVolumeAttributeSet
677
711
rootVolume ["volume_type" ] = volume .VolumeType
@@ -691,7 +725,7 @@ func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m i
691
725
////
692
726
// Read server user data
693
727
////
694
- allUserData , _ := instanceAPI .GetAllServerUserData (& instanceSDK.GetAllServerUserDataRequest {
728
+ allUserData , _ := api .GetAllServerUserData (& instanceSDK.GetAllServerUserDataRequest {
695
729
Zone : zone ,
696
730
ServerID : id ,
697
731
}, scw .WithContext (ctx ))
@@ -713,7 +747,7 @@ func ResourceInstanceServerRead(ctx context.Context, d *schema.ResourceData, m i
713
747
////
714
748
// Read server private networks
715
749
////
716
- ph , err := newPrivateNICHandler (instanceAPI , id , zone )
750
+ ph , err := newPrivateNICHandler (api . API , id , zone )
717
751
if err != nil {
718
752
return diag .FromErr (err )
719
753
}
@@ -1034,6 +1068,10 @@ func ResourceInstanceServerUpdate(ctx context.Context, d *schema.ResourceData, m
1034
1068
}
1035
1069
}
1036
1070
1071
+ if d .HasChanges ("root_volume.0.sbs_iops" ) {
1072
+ warnings = append (warnings , ResourceInstanceServerUpdateRootVolumeIOPS (ctx , api , zone , id , types .ExpandUint32Ptr (d .Get ("root_volume.0.sbs_iops" )))... )
1073
+ }
1074
+
1037
1075
return append (warnings , ResourceInstanceServerRead (ctx , d , m )... )
1038
1076
}
1039
1077
@@ -1346,3 +1384,39 @@ func ResourceInstanceServerUpdateIPs(ctx context.Context, d *schema.ResourceData
1346
1384
1347
1385
return nil
1348
1386
}
1387
+
1388
+ func ResourceInstanceServerUpdateRootVolumeIOPS (ctx context.Context , api * BlockAndInstanceAPI , zone scw.Zone , serverID string , iops * uint32 ) diag.Diagnostics {
1389
+ res , err := api .GetServer (& instanceSDK.GetServerRequest {
1390
+ Zone : zone ,
1391
+ ServerID : serverID ,
1392
+ }, scw .WithContext (ctx ))
1393
+ if err != nil {
1394
+ return diag .FromErr (err )
1395
+ }
1396
+
1397
+ rootVolume , exists := res .Server .Volumes ["0" ]
1398
+ if exists {
1399
+ _ , err := api .blockAPI .UpdateVolume (& block.UpdateVolumeRequest {
1400
+ Zone : zone ,
1401
+ VolumeID : rootVolume .ID ,
1402
+ PerfIops : iops ,
1403
+ }, scw .WithContext (ctx ))
1404
+ if err != nil {
1405
+ return diag.Diagnostics {{
1406
+ Severity : diag .Warning ,
1407
+ Summary : "Failed to update root_volume iops" ,
1408
+ Detail : err .Error (),
1409
+ AttributePath : cty .GetAttrPath ("root_volume.0.sbs_iops" ),
1410
+ }}
1411
+ }
1412
+ } else {
1413
+ return diag.Diagnostics {{
1414
+ Severity : diag .Warning ,
1415
+ Summary : "Failed to find root_volume" ,
1416
+ Detail : "Failed to update root_volume IOPS" ,
1417
+ AttributePath : cty .GetAttrPath ("root_volume.0.sbs_iops" ),
1418
+ }}
1419
+ }
1420
+
1421
+ return nil
1422
+ }
0 commit comments