-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New resources azurerm_capacity_reservation_group
and azurerm_capacity_reservation
#16464
Conversation
myc2h6o
commented
Apr 20, 2022
•
edited
Loading
edited
- Implementing On-demand Capacity Reservation
- VM resources also need an additional property capacityReservationGroup Id to specify the CapacityReserviceGroup to put the VM, I'll add it in a separate pr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hi @myc2h6o
Thanks for opening this PR - I've taken a look through and left some comments inline, if we can fix those up then we should be able to take another look here.
Thanks!
"resource_group_name": azure.SchemaResourceGroupName(), | ||
|
||
"location": azure.SchemaLocation(), | ||
|
||
"capacity_reservation_group_name": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be passing the Capacity Reservation Group ID and parsing these values instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed these three and added capacity_reservation_group_id
, including location
which must be same with the capacity reservation group.
if v, ok := d.GetOk("zone"); ok { | ||
zones := []string{v.(string)} | ||
parameters.Zones = &zones | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be using the common Expand/Flatten functions for Zones: https://github.com/hashicorp/go-azure-helpers/blob/main/resourcemanager/zones/expand.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The API exposes zones
, however, it can only accept one zone
, so used the non-common way to expand/flatten this. Similar to managed_disk.zone
. Updated a little bit in the new commit though to make it more consistent
terraform-provider-azurerm/internal/services/compute/managed_disk_resource.go
Lines 472 to 476 in 7c27c45
if zone, ok := d.GetOk("zone"); ok { | |
createDisk.Zones = &[]string{ | |
zone.(string), | |
} | |
} |
resp, err := client.Get(ctx, id.ResourceGroup, id.CapacityReservationGroupName, id.Name, "") | ||
if err != nil { | ||
if utils.ResponseWasNotFound(resp.Response) { | ||
log.Printf("[INFO] Capacity Reservation %q does not exist - removing from state", d.Id()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.Printf("[INFO] Capacity Reservation %q does not exist - removing from state", d.Id()) | |
log.Printf("[INFO] %s was not found - removing from state", *id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing out, updated
if zones := resp.Zones; zones != nil && len(*zones) > 0 { | ||
d.Set("zone", (*zones)[0]) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be using the common Expand/Flatten functions for Zones: https://github.com/hashicorp/go-azure-helpers/blob/main/resourcemanager/zones/flatten.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The API exposes zones
, however, it can only accept one zone
, so used the non-common way to expand/flatten this. Similar to managed_disk.zone
. Updated a little bit in the new commit though to make it more consistent
terraform-provider-azurerm/internal/services/compute/managed_disk_resource.go
Lines 825 to 830 in 7c27c45
zone := "" | |
if resp.Zones != nil && len(*resp.Zones) > 0 { | |
z := *resp.Zones | |
zone = z[0] | |
} | |
d.Set("zone", zone) |
future, err := client.Delete(ctx, id.ResourceGroup, id.CapacityReservationGroupName, id.Name) | ||
if err != nil { | ||
return fmt.Errorf("deleting %s: %+v", id, err) | ||
} | ||
|
||
if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { | ||
return fmt.Errorf("waiting for deletion of %s: %+v", id, err) | ||
} | ||
|
||
// API has bug, which appears to be eventually consistent. | ||
log.Printf("[DEBUG] Waiting for %s to be fully deleted..", *id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where's the Swagger bug for this? There's no point using the WaitForCompletion if this API is broken
future, err := client.Delete(ctx, id.ResourceGroup, id.CapacityReservationGroupName, id.Name) | |
if err != nil { | |
return fmt.Errorf("deleting %s: %+v", id, err) | |
} | |
if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { | |
return fmt.Errorf("waiting for deletion of %s: %+v", id, err) | |
} | |
// API has bug, which appears to be eventually consistent. | |
log.Printf("[DEBUG] Waiting for %s to be fully deleted..", *id) | |
if _, err := client.Delete(ctx, id.ResourceGroup, id.CapacityReservationGroupName, id.Name); err != nil { | |
return fmt.Errorf("deleting %s: %+v", id, err) | |
} | |
// API has bug, which appears to be eventually consistent. | |
log.Printf("[DEBUG] Waiting for %s to be fully deleted..", *id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have opened an issue within Azure spec repo, updated in code comment as well
Azure/azure-rest-api-specs#18767
"name": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ForceNew: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should validate the name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have added the validation for name
zones := zones.Expand(d.Get("zones").(*schema.Set).List()) | ||
if len(zones) > 0 { | ||
parameters.Zones = &zones | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be using the standard Expand functions for Zones
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
different from the other resource in this change, in line 87 (before the new commit), already used the standard zones.Expand
resp, err := client.Get(ctx, id.ResourceGroup, id.Name, "") | ||
if err != nil { | ||
if utils.ResponseWasNotFound(resp.Response) { | ||
log.Printf("[INFO] Capacity Reservation Group %q does not exist - removing from state", d.Id()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.Printf("[INFO] Capacity Reservation Group %q does not exist - removing from state", d.Id()) | |
log.Printf("[INFO] %s was not found - removing from state", *id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
if _, err := client.Delete(ctx, id.ResourceGroup, id.Name); err != nil { | ||
return fmt.Errorf("deleting %s: %+v", id, err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this is gone straight away? given the other API has issues, are there any API errors when deleting multiple reservations within a parent group here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This api only has the non-future version: https://github.com/Azure/azure-sdk-for-go/blob/bf144f61fde04d2f29dd52d84f25e931cea67fd8/services/compute/mgmt/2021-11-01/compute/capacityreservationgroups.go#L120.
The api issue is that, although capacity reservation is deleted and not present in the Get response, capacity reservation group still needs some additional wait (about 5 seconds) to realize that, so added the wait in the capacity reservation deletion. Have put the detail in spec repo Azure/azure-rest-api-specs#18767
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't see any wait? we souldn't be waiting and instead poll to check until its finished
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @katbyte The deletion for this resource capacity_reservation_group is synchrounous per sdk.
And the wait and poll is for the other resource capaicty_reservation below in this change, where the asynchronous sdk has bug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just took another thought. The actual issue Azure/azure-rest-api-specs#18767 happens within deleting the parent resource capacity_reservation_group
due to cache refresh issue. So instead of adding a wait on capacity_reservation
, probably it's better to add a retry logic on the parent resource here itself. I'll update the pr and let you know once it's ready to be reviewed again
Hi @tombuildsstuff Thanks for reviewing the pr! I've updated the pr to resolve the comments, please take a look. Thanks! |
if _, err := client.Delete(ctx, id.ResourceGroup, id.Name); err != nil { | ||
return fmt.Errorf("deleting %s: %+v", id, err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't see any wait? we souldn't be waiting and instead poll to check until its finished
Hi @katbyte I've updated the delete operation of |
21ac0e5
to
2eee0b7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @myc2h6o - LGTM 🌻
// It takes several seconds to sync the cache of reservations list in Capacity Reservation Group. Delete operation requires the list to be empty, and fails before the cache sync is completed. | ||
// Retry the delete operation after a minute as a workaround. Issue is tracked by: https://github.com/Azure/azure-rest-api-specs/issues/18767 | ||
if _, err := client.Delete(ctx, id.ResourceGroup, id.Name); err != nil { | ||
time.Sleep(1 * time.Minute) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i just noticed this - we should not be sleeping. is there something you can check/poll on instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@katbyte I tried get the reservations list in the reservation group but unfortunately it changes to empty very soon after the reservation is deleted. However, even if it's empty, the deletion still needs some additional seconds to work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw the deletion in resource_group
waits for 30 seconds in each polling, maybe we can wait for 30 seconds instead here as well? The internal cache is invisible from api but it shall be sync in less than 10 seconds
terraform-provider-azurerm/internal/services/resource/resource_group_resource.go
Lines 151 to 153 in 82de9ae
if len(nestedResourceIds) > 0 { | |
time.Sleep(30 * time.Second) | |
return pluginsdk.RetryableError(resourceGroupContainsItemsError(id.ResourceGroup, nestedResourceIds)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that is inside a retry function and acts as a delay between checking, it was a quick hack that was put in post 3.0 in 3.0.1 very quickly and should likely be changed/fixed to a state wait.
Could we instead put this inside a statewait where the retry and sleep logic is handled correctly? thanksa
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@katbyte yes it's better to use the common way. I've moved the deletion workaround into a stateRefresh function, can you take a look? Thanks!
ab6c6f6
to
9d1de89
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @myc2h6o - LGTM 👍
capacity_reservation_group
and capacity_reservation
azurerm_capacity_reservation_group
and azurerm_capacity_reservation
This functionality has been released in v3.10.0 of the Terraform Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you! |
I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions. |