@@ -54,10 +54,23 @@ func ResourceInstance() *schema.Resource {
5454 },
5555 "engine" : {
5656 Type : schema .TypeString ,
57- Required : true ,
57+ Optional : true ,
58+ Computed : true ,
5859 ForceNew : true ,
5960 Description : "Database's engine version id" ,
6061 DiffSuppressFunc : dsf .IgnoreCase ,
62+ ConflictsWith : []string {
63+ "snapshot_id" ,
64+ },
65+ },
66+ "snapshot_id" : {
67+ Type : schema .TypeString ,
68+ Optional : true ,
69+ ForceNew : true ,
70+ Description : "ID of an existing snapshot to create a new instance from. This allows restoring a database instance to the state captured in the specified snapshot. Conflicts with the `engine` attribute." ,
71+ ConflictsWith : []string {
72+ "engine" ,
73+ },
6174 },
6275 "is_ha_cluster" : {
6376 Type : schema .TypeBool ,
@@ -323,66 +336,110 @@ func ResourceRdbInstanceCreate(ctx context.Context, d *schema.ResourceData, m in
323336 if err != nil {
324337 return diag .FromErr (err )
325338 }
339+ id := ""
326340
327- createReq := & rdb.CreateInstanceRequest {
328- Region : region ,
329- ProjectID : types .ExpandStringPtr (d .Get ("project_id" )),
330- Name : types .ExpandOrGenerateString (d .Get ("name" ), "rdb" ),
331- NodeType : d .Get ("node_type" ).(string ),
332- Engine : d .Get ("engine" ).(string ),
333- IsHaCluster : d .Get ("is_ha_cluster" ).(bool ),
334- DisableBackup : d .Get ("disable_backup" ).(bool ),
335- UserName : d .Get ("user_name" ).(string ),
336- Password : d .Get ("password" ).(string ),
337- VolumeType : rdb .VolumeType (d .Get ("volume_type" ).(string )),
338- Encryption : & rdb.EncryptionAtRest {
339- Enabled : d .Get ("encryption_at_rest" ).(bool ),
340- },
341- }
341+ if regionalSnapshotID , ok := d .GetOk ("snapshot_id" ); ok {
342+ haCluster := d .Get ("is_ha_cluster" ).(bool )
343+ nodeType := d .Get ("node_type" ).(string )
344+ _ , snapshotID , err := regional .ParseID (regionalSnapshotID .(string ))
345+ if err != nil {
346+ return diag .FromErr (err )
347+ }
348+ createReqFromSnapshot := & rdb.CreateInstanceFromSnapshotRequest {
349+ SnapshotID : snapshotID ,
350+ Region : region ,
351+ InstanceName : types .ExpandOrGenerateString (d .Get ("name" ), "rdb" ),
352+ IsHaCluster : & haCluster ,
353+ NodeType : & nodeType ,
354+ }
355+ res , err := rdbAPI .CreateInstanceFromSnapshot (createReqFromSnapshot , scw .WithContext (ctx ))
356+ if err != nil {
357+ return diag .FromErr (err )
358+ }
359+ _ , err = waitForRDBInstance (ctx , rdbAPI , region , res .ID , d .Timeout (schema .TimeoutCreate ))
360+ if err != nil {
361+ return diag .FromErr (err )
362+ }
342363
343- if initSettings , ok := d .GetOk ("init_settings" ); ok {
344- createReq .InitSettings = expandInstanceSettings (initSettings )
345- }
364+ rawTag , tagExist := d .GetOk ("tags" )
365+ if tagExist {
366+ updateReq := & rdb.UpdateInstanceRequest {
367+ Region : region ,
368+ InstanceID : res .ID ,
369+ }
370+ tags := types .ExpandStrings (rawTag )
371+ updateReq .Tags = & tags
372+ _ , err = rdbAPI .UpdateInstance (updateReq , scw .WithContext (ctx ))
373+ if err != nil {
374+ return diag .FromErr (err )
375+ }
376+ }
377+ d .SetId (regional .NewIDString (region , res .ID ))
378+ id = res .ID
346379
347- rawTag , tagExist := d .GetOk ("tags" )
348- if tagExist {
349- createReq .Tags = types .ExpandStrings (rawTag )
350- }
380+ } else {
351381
352- // Init Endpoints
353- if pn , pnExist := d .GetOk ("private_network" ); pnExist {
354- ipamConfig , staticConfig := getIPConfigCreate (d , "ip_net" )
355- var diags diag.Diagnostics
356- createReq .InitEndpoints , diags = expandPrivateNetwork (pn , pnExist , ipamConfig , staticConfig )
357- if diags .HasError () {
358- return diags
382+ createReq := & rdb.CreateInstanceRequest {
383+ Region : region ,
384+ ProjectID : types .ExpandStringPtr (d .Get ("project_id" )),
385+ Name : types .ExpandOrGenerateString (d .Get ("name" ), "rdb" ),
386+ NodeType : d .Get ("node_type" ).(string ),
387+ Engine : d .Get ("engine" ).(string ),
388+ IsHaCluster : d .Get ("is_ha_cluster" ).(bool ),
389+ DisableBackup : d .Get ("disable_backup" ).(bool ),
390+ UserName : d .Get ("user_name" ).(string ),
391+ Password : d .Get ("password" ).(string ),
392+ VolumeType : rdb .VolumeType (d .Get ("volume_type" ).(string )),
393+ Encryption : & rdb.EncryptionAtRest {
394+ Enabled : d .Get ("encryption_at_rest" ).(bool ),
395+ },
359396 }
360- for _ , warning := range diags {
361- tflog .Warn (ctx , warning .Detail )
397+
398+ if initSettings , ok := d .GetOk ("init_settings" ); ok {
399+ createReq .InitSettings = expandInstanceSettings (initSettings )
362400 }
363- }
364- if _ , lbExists := d .GetOk ("load_balancer" ); lbExists {
365- createReq .InitEndpoints = append (createReq .InitEndpoints , expandLoadBalancer ())
366- }
367401
368- if size , ok := d .GetOk ("volume_size_in_gb" ); ok {
369- if createReq . VolumeType == rdb . VolumeTypeLssd {
370- return diag . FromErr ( fmt . Errorf ( "volume_size_in_gb should not be used with volume_type %s" , rdb . VolumeTypeLssd . String ()) )
402+ rawTag , tagExist := d .GetOk ("tags" )
403+ if tagExist {
404+ createReq . Tags = types . ExpandStrings ( rawTag )
371405 }
372- createReq .VolumeSize = scw .Size (uint64 (size .(int )) * uint64 (scw .GB ))
373- }
374406
375- res , err := rdbAPI .CreateInstance (createReq , scw .WithContext (ctx ))
376- if err != nil {
377- return diag .FromErr (err )
378- }
407+ // Init Endpoints
408+ if pn , pnExist := d .GetOk ("private_network" ); pnExist {
409+ ipamConfig , staticConfig := getIPConfigCreate (d , "ip_net" )
410+ var diags diag.Diagnostics
411+ createReq .InitEndpoints , diags = expandPrivateNetwork (pn , pnExist , ipamConfig , staticConfig )
412+ if diags .HasError () {
413+ return diags
414+ }
415+ for _ , warning := range diags {
416+ tflog .Warn (ctx , warning .Detail )
417+ }
418+ }
419+ if _ , lbExists := d .GetOk ("load_balancer" ); lbExists {
420+ createReq .InitEndpoints = append (createReq .InitEndpoints , expandLoadBalancer ())
421+ }
422+
423+ if size , ok := d .GetOk ("volume_size_in_gb" ); ok {
424+ if createReq .VolumeType == rdb .VolumeTypeLssd {
425+ return diag .FromErr (fmt .Errorf ("volume_size_in_gb should not be used with volume_type %s" , rdb .VolumeTypeLssd .String ()))
426+ }
427+ createReq .VolumeSize = scw .Size (uint64 (size .(int )) * uint64 (scw .GB ))
428+ }
429+
430+ res , err := rdbAPI .CreateInstance (createReq , scw .WithContext (ctx ))
431+ if err != nil {
432+ return diag .FromErr (err )
433+ }
379434
380- d .SetId (regional .NewIDString (region , res .ID ))
435+ d .SetId (regional .NewIDString (region , res .ID ))
436+ id = res .ID
437+ }
381438
382439 mustUpdate := false
383440 updateReq := & rdb.UpdateInstanceRequest {
384441 Region : region ,
385- InstanceID : res . ID ,
442+ InstanceID : id ,
386443 }
387444 // Configure Schedule Backup
388445 // BackupScheduleFrequency and BackupScheduleRetention can only configure after instance creation
@@ -403,9 +460,8 @@ func ResourceRdbInstanceCreate(ctx context.Context, d *schema.ResourceData, m in
403460 updateReq .LogsPolicy = expandInstanceLogsPolicy (policyRaw )
404461 mustUpdate = true
405462 }
406-
407463 if mustUpdate {
408- _ , err = waitForRDBInstance (ctx , rdbAPI , region , res . ID , d .Timeout (schema .TimeoutCreate ))
464+ _ , err = waitForRDBInstance (ctx , rdbAPI , region , id , d .Timeout (schema .TimeoutCreate ))
409465 if err != nil {
410466 return diag .FromErr (err )
411467 }
@@ -416,12 +472,12 @@ func ResourceRdbInstanceCreate(ctx context.Context, d *schema.ResourceData, m in
416472 }
417473 // Configure Instance settings
418474 if settings , ok := d .GetOk ("settings" ); ok {
419- res , err = waitForRDBInstance (ctx , rdbAPI , region , res . ID , d .Timeout (schema .TimeoutCreate ))
475+ res , err : = waitForRDBInstance (ctx , rdbAPI , region , id , d .Timeout (schema .TimeoutCreate ))
420476 if err != nil {
421477 return diag .FromErr (err )
422478 }
423479
424- _ , err : = rdbAPI .SetInstanceSettings (& rdb.SetInstanceSettingsRequest {
480+ _ , err = rdbAPI .SetInstanceSettings (& rdb.SetInstanceSettingsRequest {
425481 InstanceID : res .ID ,
426482 Region : region ,
427483 Settings : expandInstanceSettings (settings ),
@@ -430,7 +486,6 @@ func ResourceRdbInstanceCreate(ctx context.Context, d *schema.ResourceData, m in
430486 return diag .FromErr (err )
431487 }
432488 }
433-
434489 return ResourceRdbInstanceRead (ctx , d , m )
435490}
436491
0 commit comments