diff --git a/.changelog/26151.txt b/.changelog/26151.txt new file mode 100644 index 00000000000..4caf3839245 --- /dev/null +++ b/.changelog/26151.txt @@ -0,0 +1,7 @@ +```release-note:note +resource/aws_connect_queue: The `quick_connect_ids_associated` attribute is being deprecated in favor of `quick_connect_ids` +``` + +```release-note:note +resource/aws_connect_routing_profile: The `queue_configs_associated` attribute is being deprecated in favor of `queue_configs` +``` \ No newline at end of file diff --git a/internal/service/connect/instance.go b/internal/service/connect/instance.go index be55c20819a..efe8ce90ee0 100644 --- a/internal/service/connect/instance.go +++ b/internal/service/connect/instance.go @@ -148,15 +148,12 @@ func resourceInstanceCreate(ctx context.Context, d *schema.ResourceData, meta in for att := range InstanceAttributeMapping() { rKey := InstanceAttributeMapping()[att] - - if v, ok := d.GetOk(rKey); ok { - err := resourceInstanceUpdateAttribute(ctx, conn, d.Id(), att, strconv.FormatBool(v.(bool))) - //Pre-release attribute, user/account/instance now allow-listed - if err != nil && tfawserr.ErrCodeEquals(err, ErrCodeAccessDeniedException) || tfawserr.ErrMessageContains(err, ErrCodeAccessDeniedException, "not authorized to update") { - log.Printf("[WARN] error setting Connect instance (%s) attribute (%s): %s", d.Id(), att, err) - } else if err != nil { - return diag.FromErr(fmt.Errorf("error setting Connect instance (%s) attribute (%s): %w", d.Id(), att, err)) - } + err := resourceInstanceUpdateAttribute(ctx, conn, d.Id(), att, strconv.FormatBool(d.Get(rKey).(bool))) + //Pre-release attribute, user/account/instance now allow-listed + if err != nil && tfawserr.ErrCodeEquals(err, ErrCodeAccessDeniedException) || tfawserr.ErrMessageContains(err, ErrCodeAccessDeniedException, "not authorized to update") { + log.Printf("[WARN] error setting Connect instance (%s) attribute (%s): %s", d.Id(), att, err) + } else if err != nil { + return diag.FromErr(fmt.Errorf("error setting Connect instance (%s) attribute (%s): %w", d.Id(), att, err)) } } diff --git a/internal/service/connect/queue.go b/internal/service/connect/queue.go index 141da42f72c..b9aea43420e 100644 --- a/internal/service/connect/queue.go +++ b/internal/service/connect/queue.go @@ -95,8 +95,9 @@ func ResourceQueue() *schema.Resource { }, }, "quick_connect_ids_associated": { - Type: schema.TypeSet, - Computed: true, + Deprecated: "Use the quick_connect_ids instead", + Type: schema.TypeSet, + Computed: true, Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -323,29 +324,39 @@ func resourceQueueUpdate(ctx context.Context, d *schema.ResourceData, meta inter // updates to quick_connect_ids if d.HasChange("quick_connect_ids") { - // first disassociate all existing quick connects - if v, ok := d.GetOk("quick_connect_ids_associated"); ok && v.(*schema.Set).Len() > 0 { - input := &connect.DisassociateQueueQuickConnectsInput{ - InstanceId: aws.String(instanceID), - QueueId: aws.String(queueID), - } - input.QuickConnectIds = flex.ExpandStringSet(v.(*schema.Set)) - _, err = conn.DisassociateQueueQuickConnectsWithContext(ctx, input) + o, n := d.GetChange("quick_connect_ids") + + if o == nil { + o = new(schema.Set) + } + if n == nil { + n = new(schema.Set) + } + + os := o.(*schema.Set) + ns := n.(*schema.Set) + quickConnectIdsUpdateAdd := ns.Difference(os) + quickConnectIdsUpdateRemove := os.Difference(ns) + + if len(quickConnectIdsUpdateAdd.List()) > 0 { // nosemgrep:ci.semgrep.migrate.aws-api-context + _, err = conn.AssociateQueueQuickConnectsWithContext(ctx, &connect.AssociateQueueQuickConnectsInput{ + InstanceId: aws.String(instanceID), + QueueId: aws.String(queueID), + QuickConnectIds: flex.ExpandStringSet(quickConnectIdsUpdateAdd), + }) if err != nil { - return diag.FromErr(fmt.Errorf("updating Queues Quick Connect IDs, specifically disassociating quick connects from queue (%s): %w", d.Id(), err)) + return diag.Errorf("updating Queues Quick Connect IDs, specifically associating quick connects to queue (%s): %s", d.Id(), err) } } - // re-associate the quick connects - if v, ok := d.GetOk("quick_connect_ids"); ok && v.(*schema.Set).Len() > 0 { - input := &connect.AssociateQueueQuickConnectsInput{ - InstanceId: aws.String(instanceID), - QueueId: aws.String(queueID), - } - input.QuickConnectIds = flex.ExpandStringSet(v.(*schema.Set)) - _, err = conn.AssociateQueueQuickConnectsWithContext(ctx, input) + if len(quickConnectIdsUpdateRemove.List()) > 0 { // nosemgrep:ci.semgrep.migrate.aws-api-context + _, err = conn.DisassociateQueueQuickConnectsWithContext(ctx, &connect.DisassociateQueueQuickConnectsInput{ + InstanceId: aws.String(instanceID), + QueueId: aws.String(queueID), + QuickConnectIds: flex.ExpandStringSet(quickConnectIdsUpdateRemove), + }) if err != nil { - return diag.FromErr(fmt.Errorf("updating Queues Quick Connect IDs, specifically associating quick connects to queue (%s): %w", d.Id(), err)) + return diag.Errorf("updating Queues Quick Connect IDs, specifically disassociating quick connects from queue (%s): %s", d.Id(), err) } } } diff --git a/internal/service/connect/routing_profile.go b/internal/service/connect/routing_profile.go index 6e9eee1d9c8..c8b0d9ccc46 100644 --- a/internal/service/connect/routing_profile.go +++ b/internal/service/connect/routing_profile.go @@ -110,10 +110,10 @@ func ResourceRoutingProfile() *schema.Resource { }, }, }, - // used to update the queue configs by first disassociating the existing set and re-associating them "queue_configs_associated": { - Type: schema.TypeSet, - Computed: true, + Deprecated: "Use the queue_configs instead", + Type: schema.TypeSet, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "channel": { @@ -327,35 +327,43 @@ func resourceRoutingProfileUpdate(ctx context.Context, d *schema.ResourceData, m // AssociateRoutingProfileQueues - Associates a set of queues with a routing profile. // DisassociateRoutingProfileQueues - Disassociates a set of queues from a routing profile. // UpdateRoutingProfileQueues - Updates the properties associated with a set of queues for a routing profile. - // since the update only updates the existing queues that are associated, we will instead disassociate (if there are any queues) - // and then associate all the queues again to ensure new queues can be added and unused queues can be removed - inputQueueAssociate := &connect.AssociateRoutingProfileQueuesInput{ - InstanceId: aws.String(instanceID), - RoutingProfileId: aws.String(routingProfileID), - } + // since the update only updates the existing queues that are associated, we will instead disassociate and associate + // the respective queues based on the diff detected + if d.HasChange("queue_configs") { + o, n := d.GetChange("queue_configs") - inputQueueDisassociate := &connect.DisassociateRoutingProfileQueuesInput{ - InstanceId: aws.String(instanceID), - RoutingProfileId: aws.String(routingProfileID), - } + if o == nil { + o = new(schema.Set) + } + if n == nil { + n = new(schema.Set) + } - if d.HasChange("queue_configs") { - // first disassociate all existing queues - currentAssociatedQueueReferences := expandRoutingProfileQueueReferences(d.Get("queue_configs_associated").(*schema.Set).List()) - if currentAssociatedQueueReferences != nil { - inputQueueDisassociate.QueueReferences = currentAssociatedQueueReferences - _, err = conn.DisassociateRoutingProfileQueuesWithContext(ctx, inputQueueDisassociate) + os := o.(*schema.Set) + ns := n.(*schema.Set) + queueConfigsUpdateAdd := ns.Difference(os).List() + queueConfigsUpdateRemove := os.Difference(ns).List() + + // disassociate first since Queue and channel type combination cannot be duplicated + if len(queueConfigsUpdateRemove) > 0 { + _, err = conn.DisassociateRoutingProfileQueuesWithContext(ctx, &connect.DisassociateRoutingProfileQueuesInput{ + InstanceId: aws.String(instanceID), + QueueReferences: expandRoutingProfileQueueReferences(queueConfigsUpdateRemove), + RoutingProfileId: aws.String(routingProfileID), + }) if err != nil { - return diag.FromErr(fmt.Errorf("updating RoutingProfile Queue Configs, specifically disassociating queues from routing profile (%s): %w", d.Id(), err)) + return diag.Errorf("updating RoutingProfile Queue Configs, specifically disassociating queues from routing profile (%s): %s", d.Id(), err) } } - // re-associate the queues - updatedQueueConfigs := expandRoutingProfileQueueConfigs(d.Get("queue_configs").(*schema.Set).List()) - if updatedQueueConfigs != nil { - inputQueueAssociate.QueueConfigs = updatedQueueConfigs - _, err = conn.AssociateRoutingProfileQueuesWithContext(ctx, inputQueueAssociate) + + if len(queueConfigsUpdateAdd) > 0 { + _, err = conn.AssociateRoutingProfileQueuesWithContext(ctx, &connect.AssociateRoutingProfileQueuesInput{ + InstanceId: aws.String(instanceID), + QueueConfigs: expandRoutingProfileQueueConfigs(queueConfigsUpdateAdd), + RoutingProfileId: aws.String(routingProfileID), + }) if err != nil { - return diag.FromErr(fmt.Errorf("updating RoutingProfile Queue Configs, specifically associating queues to routing profile (%s): %w", d.Id(), err)) + return diag.Errorf("updating RoutingProfile Queue Configs, specifically associating queues to routing profile (%s): %s", d.Id(), err) } } }