diff --git a/.changelog/22761.txt b/.changelog/22761.txt new file mode 100644 index 00000000000..dbb7dc408f6 --- /dev/null +++ b/.changelog/22761.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_connect_security_profile: add `permissions` attribute to read +``` \ No newline at end of file diff --git a/internal/service/connect/enum.go b/internal/service/connect/enum.go index 6ae001e36da..dd431646692 100644 --- a/internal/service/connect/enum.go +++ b/internal/service/connect/enum.go @@ -24,9 +24,12 @@ const ( // MaxResults Valid Range: Minimum value of 1. Maximum value of 1000 // https://docs.aws.amazon.com/connect/latest/APIReference/API_ListPrompts.html ListPromptsMaxResults = 60 - // ListLambdaFunctionsMaxResults Valid Range: Minimum value of 1. Maximum value of 1000. + // ListQuickConnectsMaxResults Valid Range: Minimum value of 1. Maximum value of 1000. // https://docs.aws.amazon.com/connect/latest/APIReference/API_ListQuickConnects.html ListQuickConnectsMaxResults = 60 + // ListSecurityProfilePermissionsMaxResults Valid Range: Minimum value of 1. Maximum value of 1000. + // https://docs.aws.amazon.com/connect/latest/APIReference/API_ListSecurityProfilePermissions.html + ListSecurityProfilePermissionsMaxResults = 60 ) func InstanceAttributeMapping() map[string]string { diff --git a/internal/service/connect/security_profile.go b/internal/service/connect/security_profile.go index 770709fba67..8ccec3c1e90 100644 --- a/internal/service/connect/security_profile.go +++ b/internal/service/connect/security_profile.go @@ -146,7 +146,17 @@ func resourceSecurityProfileRead(ctx context.Context, d *schema.ResourceData, me d.Set("organization_resource_id", resp.SecurityProfile.OrganizationResourceId) d.Set("security_profile_id", resp.SecurityProfile.Id) d.Set("name", resp.SecurityProfile.SecurityProfileName) - // NOTE: The response does not return information about the permissions + + // reading permissions requires a separate API call + permissions, err := getConnectSecurityProfilePermissions(ctx, conn, instanceID, securityProfileID) + + if err != nil { + return diag.FromErr(fmt.Errorf("error finding Connect Security Profile Permissions for Security Profile (%s): %w", securityProfileID, err)) + } + + if permissions != nil { + d.Set("permissions", flex.FlattenStringSet(permissions)) + } tags := KeyValueTags(resp.SecurityProfile.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) @@ -230,3 +240,29 @@ func SecurityProfileParseID(id string) (string, string, error) { return parts[0], parts[1], nil } + +func getConnectSecurityProfilePermissions(ctx context.Context, conn *connect.Connect, instanceID, securityProfileID string) ([]*string, error) { + var result []*string + + input := &connect.ListSecurityProfilePermissionsInput{ + InstanceId: aws.String(instanceID), + MaxResults: aws.Int64(ListSecurityProfilePermissionsMaxResults), + SecurityProfileId: aws.String(securityProfileID), + } + + err := conn.ListSecurityProfilePermissionsPagesWithContext(ctx, input, func(page *connect.ListSecurityProfilePermissionsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + result = append(result, page.Permissions...) + + return !lastPage + }) + + if err != nil { + return nil, err + } + + return result, nil +} diff --git a/internal/service/connect/security_profile_test.go b/internal/service/connect/security_profile_test.go index fc7f4c4d17c..316fb1adf23 100644 --- a/internal/service/connect/security_profile_test.go +++ b/internal/service/connect/security_profile_test.go @@ -18,8 +18,9 @@ import ( //Serialized acceptance tests due to Connect account limits (max 2 parallel tests) func TestAccConnectSecurityProfile_serial(t *testing.T) { testCases := map[string]func(t *testing.T){ - "basic": testAccSecurityProfile_basic, - "disappears": testAccSecurityProfile_disappears, + "basic": testAccSecurityProfile_basic, + "disappears": testAccSecurityProfile_disappears, + "update_permissions": testAccSecurityProfile_updatePermissions, } for name, tc := range testCases { @@ -52,15 +53,14 @@ func testAccSecurityProfile_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", rName2), resource.TestCheckResourceAttr(resourceName, "description", "Created"), - resource.TestCheckResourceAttr(resourceName, "permissions.#", "2"), + resource.TestCheckResourceAttr(resourceName, "permissions.#", "0"), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"permissions"}, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, }, { Config: testAccSecurityProfileBasicConfig(rName, rName2, "Updated"), @@ -72,6 +72,56 @@ func testAccSecurityProfile_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", rName2), resource.TestCheckResourceAttr(resourceName, "description", "Updated"), + resource.TestCheckResourceAttr(resourceName, "permissions.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + ), + }, + }, + }) +} + +func testAccSecurityProfile_updatePermissions(t *testing.T) { + var v connect.DescribeSecurityProfileOutput + rName := sdkacctest.RandomWithPrefix("resource-test-terraform") + rName2 := sdkacctest.RandomWithPrefix("resource-test-terraform") + resourceName := "aws_connect_security_profile.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, connect.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckSecurityProfileDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSecurityProfileBasicConfig(rName, rName2, "TestPermissionsUpdate"), + Check: resource.ComposeTestCheckFunc( + testAccCheckSecurityProfileExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttrSet(resourceName, "instance_id"), + resource.TestCheckResourceAttrSet(resourceName, "security_profile_id"), + + resource.TestCheckResourceAttr(resourceName, "name", rName2), + resource.TestCheckResourceAttr(resourceName, "description", "TestPermissionsUpdate"), + resource.TestCheckResourceAttr(resourceName, "permissions.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + // Test updating permissions + Config: testAccSecurityProfilePermissionsConfig(rName, rName2, "TestPermissionsUpdate"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckSecurityProfileExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttrSet(resourceName, "instance_id"), + resource.TestCheckResourceAttrSet(resourceName, "security_profile_id"), + + resource.TestCheckResourceAttr(resourceName, "name", rName2), + resource.TestCheckResourceAttr(resourceName, "description", "TestPermissionsUpdate"), resource.TestCheckResourceAttr(resourceName, "permissions.#", "2"), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), ), @@ -189,6 +239,22 @@ resource "aws_connect_security_profile" "test" { name = %[1]q description = %[2]q + tags = { + "Name" = "Test Security Profile" + } +} +`, rName2, label)) +} + +func testAccSecurityProfilePermissionsConfig(rName, rName2, label string) string { + return acctest.ConfigCompose( + testAccSecurityProfileBaseConfig(rName), + fmt.Sprintf(` +resource "aws_connect_security_profile" "test" { + instance_id = aws_connect_instance.test.id + name = %[1]q + description = %[2]q + permissions = [ "BasicAgentAccess", "OutboundCallAccess",