Skip to content

Commit c004b55

Browse files
authored
Ignore 404 when removing instance membership from anti-affinity group (#449)
If the anti-affinity group has already been removed, the instance resource shouldn't care about a 404 when removing membership from it. Also, this commit changes the error messages to make it clearer that we're not actually trying to delete the anti-affinity group. Just removing the instance's membership. Tested against the colo rack with @askfongjojo's HCL config from #446. Applying first: ```hcl resource "oxide_anti_affinity_group" "peers" { project_id = data.oxide_project.proj.id description = "another anti-affinity group" name = "related-peers" policy = "allow" } resource "oxide_instance" "test" { project_id = data.oxide_project.proj.id description = "a test instance" name = "test" host_name = "terraform-acc-myhost" memory = 1073741824 ncpus = 1 start_on_create = true anti_affinity_groups = [ oxide_anti_affinity_group.peers.id ] } ``` And then: ```hcl #resource "oxide_anti_affinity_group" "peers" { # project_id = data.oxide_project.proj.id # description = "another anti-affinity group" # name = "related-peers" # policy = "allow" #} resource "oxide_instance" "test" { project_id = data.oxide_project.proj.id description = "a test instance" name = "test" host_name = "terraform-acc-myhost" memory = 1073741824 ncpus = 1 start_on_create = true #anti_affinity_groups = [ # oxide_anti_affinity_group.peers.id #] } ``` Results: ```console $ terraform init && terraform apply Initializing the backend... Initializing provider plugins... <...> data.oxide_project.proj: Reading... data.oxide_project.proj: Read complete after 1s [id=5f9eebcc-19de-4e91-9bd9-92cac61b446c] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # oxide_anti_affinity_group.peers will be created + resource "oxide_anti_affinity_group" "peers" { + description = "another anti-affinity group" + failure_domain = (known after apply) + id = (known after apply) + name = "related-peers" + policy = "allow" + project_id = "5f9eebcc-19de-4e91-9bd9-92cac61b446c" + time_created = (known after apply) + time_modified = (known after apply) } # oxide_instance.test will be created + resource "oxide_instance" "test" { + anti_affinity_groups = [ + (known after apply), ] + description = "a test instance" + host_name = "terraform-acc-myhost" + id = (known after apply) + memory = 1073741824 + name = "test" + ncpus = 1 + project_id = "5f9eebcc-19de-4e91-9bd9-92cac61b446c" + start_on_create = true + time_created = (known after apply) + time_modified = (known after apply) } Plan: 2 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes oxide_anti_affinity_group.peers: Creating... oxide_anti_affinity_group.peers: Creation complete after 4s [id=aea02b00-c2f2-470e-924f-4c85a3b5b0e9] oxide_instance.test: Creating... oxide_instance.test: Creation complete after 4s [id=be2b9d99-8492-435b-ba1f-97acce7cdca8] Apply complete! Resources: 2 added, 0 changed, 0 destroyed. $ terraform apply data.oxide_project.proj: Reading... oxide_anti_affinity_group.peers: Refreshing state... [id=aea02b00-c2f2-470e-924f-4c85a3b5b0e9] data.oxide_project.proj: Read complete after 1s [id=5f9eebcc-19de-4e91-9bd9-92cac61b446c] oxide_instance.test: Refreshing state... [id=be2b9d99-8492-435b-ba1f-97acce7cdca8] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: ~ update in-place - destroy Terraform will perform the following actions: # oxide_anti_affinity_group.peers will be destroyed # (because oxide_anti_affinity_group.peers is not in configuration) - resource "oxide_anti_affinity_group" "peers" { - description = "another anti-affinity group" -> null - failure_domain = "sled" -> null - id = "aea02b00-c2f2-470e-924f-4c85a3b5b0e9" -> null - name = "related-peers" -> null - policy = "allow" -> null - project_id = "5f9eebcc-19de-4e91-9bd9-92cac61b446c" -> null - time_created = "2025-06-11 06:37:37.535487 +0000 UTC" -> null - time_modified = "2025-06-11 06:37:37.535487 +0000 UTC" -> null } # oxide_instance.test will be updated in-place ~ resource "oxide_instance" "test" { - anti_affinity_groups = [ - "aea02b00-c2f2-470e-924f-4c85a3b5b0e9", ] -> null ~ id = "be2b9d99-8492-435b-ba1f-97acce7cdca8" -> (known after apply) name = "test" ~ time_created = "2025-06-11 06:37:37.996253 +0000 UTC" -> (known after apply) ~ time_modified = "2025-06-11 06:37:37.996253 +0000 UTC" -> (known after apply) # (6 unchanged attributes hidden) } Plan: 0 to add, 1 to change, 1 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes oxide_anti_affinity_group.peers: Destroying... [id=aea02b00-c2f2-470e-924f-4c85a3b5b0e9] oxide_anti_affinity_group.peers: Destruction complete after 1s oxide_instance.test: Modifying... [id=be2b9d99-8492-435b-ba1f-97acce7cdca8] oxide_instance.test: Modifications complete after 8s [id=be2b9d99-8492-435b-ba1f-97acce7cdca8] Apply complete! Resources: 0 added, 1 changed, 1 destroyed. ``` Fixes: #446
1 parent bb71de5 commit c004b55

1 file changed

Lines changed: 11 additions & 6 deletions

File tree

internal/provider/resource_instance.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,7 +1460,7 @@ func addAntiAffinityGroups(
14601460
id, err := strconv.Unquote(v.String())
14611461
if err != nil {
14621462
diags.AddError(
1463-
"Error adding anti-affinity group",
1463+
"Error adding anti-affinity group to instance",
14641464
"anti-affinity group ID parse error: "+err.Error(),
14651465
)
14661466
return diags
@@ -1473,12 +1473,12 @@ func addAntiAffinityGroups(
14731473
_, err = client.AntiAffinityGroupMemberInstanceAdd(ctx, params)
14741474
if err != nil {
14751475
diags.AddError(
1476-
"Error adding anti-affinity group",
1476+
"Error adding anti-affinity group to instance",
14771477
"API error: "+err.Error(),
14781478
)
14791479
return diags
14801480
}
1481-
tflog.Trace(ctx, fmt.Sprintf("added anti-affinity group with ID: %v", v), map[string]any{"success": true})
1481+
tflog.Trace(ctx, fmt.Sprintf("added anti-affinity group with ID: %v to instance with ID: %v", id, instanceID), map[string]any{"success": true})
14821482
}
14831483

14841484
return nil
@@ -1492,7 +1492,7 @@ func removeAntiAffinityGroups(
14921492
id, err := strconv.Unquote(v.String())
14931493
if err != nil {
14941494
diags.AddError(
1495-
"Error removing anti-affinity group",
1495+
"Error removing anti-affinity group from instance",
14961496
"anti-affinity group ID parse error: "+err.Error(),
14971497
)
14981498
return diags
@@ -1504,13 +1504,18 @@ func removeAntiAffinityGroups(
15041504
}
15051505
err = client.AntiAffinityGroupMemberInstanceDelete(ctx, params)
15061506
if err != nil {
1507+
// If the anti-affinity group doesn't exist anymore, it means
1508+
// the instance isn't part of it. We can just return.
1509+
if is404(err) {
1510+
return nil
1511+
}
15071512
diags.AddError(
1508-
"Error removing anti-affinity group",
1513+
"Error removing anti-affinity group from instance",
15091514
"API error: "+err.Error(),
15101515
)
15111516
return diags
15121517
}
1513-
tflog.Trace(ctx, fmt.Sprintf("removed anit-affinity group with ID: %v", v), map[string]any{"success": true})
1518+
tflog.Trace(ctx, fmt.Sprintf("removed anti-affinity group with ID %v to instance with ID %v", id, instanceID), map[string]any{"success": true})
15141519
}
15151520

15161521
return nil

0 commit comments

Comments
 (0)