diff --git a/.changelog/34796.txt b/.changelog/34796.txt new file mode 100644 index 00000000000..98715fc5979 --- /dev/null +++ b/.changelog/34796.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_ssoadmin_application_assignments +``` diff --git a/internal/service/ssoadmin/application_assignments_data_source.go b/internal/service/ssoadmin/application_assignments_data_source.go new file mode 100644 index 00000000000..64332a8679d --- /dev/null +++ b/internal/service/ssoadmin/application_assignments_data_source.go @@ -0,0 +1,115 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package ssoadmin + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/ssoadmin" + awstypes "github.com/aws/aws-sdk-go-v2/service/ssoadmin/types" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkDataSource(name="Application Assignments") +func newDataSourceApplicationAssignments(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceApplicationAssignments{}, nil +} + +const ( + DSNameApplicationAssignments = "Application Assignments Data Source" +) + +type dataSourceApplicationAssignments struct { + framework.DataSourceWithConfigure +} + +func (d *dataSourceApplicationAssignments) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { // nosemgrep:ci.meta-in-func-name + resp.TypeName = "aws_ssoadmin_application_assignments" +} + +func (d *dataSourceApplicationAssignments) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "application_arn": schema.StringAttribute{ + Required: true, + }, + "id": framework.IDAttribute(), + }, + Blocks: map[string]schema.Block{ + "application_assignments": schema.ListNestedBlock{ + CustomType: fwtypes.NewListNestedObjectTypeOf[applicationAssignmentData](ctx), + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "application_arn": schema.StringAttribute{ + Computed: true, + }, + "principal_id": schema.StringAttribute{ + Computed: true, + }, + "principal_type": schema.StringAttribute{ + CustomType: fwtypes.StringEnumType[awstypes.PrincipalType](), + Computed: true, + }, + }, + }, + }, + }, + } +} +func (d *dataSourceApplicationAssignments) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + conn := d.Meta().SSOAdminClient(ctx) + + var data dataSourceApplicationAssignmentsData + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + paginator := ssoadmin.NewListApplicationAssignmentsPaginator(conn, &ssoadmin.ListApplicationAssignmentsInput{ + ApplicationArn: aws.String(data.ApplicationARN.ValueString()), + }) + + var out ssoadmin.ListApplicationAssignmentsOutput + for paginator.HasMorePages() { + page, err := paginator.NextPage(ctx) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.SSOAdmin, create.ErrActionReading, DSNameApplicationAssignments, data.ApplicationARN.String(), err), + err.Error(), + ) + return + } + + if page != nil && len(page.ApplicationAssignments) > 0 { + out.ApplicationAssignments = append(out.ApplicationAssignments, page.ApplicationAssignments...) + } + } + + resp.Diagnostics.Append(flex.Flatten(ctx, out, &data)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +type dataSourceApplicationAssignmentsData struct { + ApplicationARN types.String `tfsdk:"application_arn"` + ApplicationAssignments fwtypes.ListNestedObjectValueOf[applicationAssignmentData] `tfsdk:"application_assignments"` + ID types.String `tfsdk:"id"` +} + +type applicationAssignmentData struct { + ApplicationARN types.String `tfsdk:"application_arn"` + PrincipalID types.String `tfsdk:"principal_id"` + PrincipalType fwtypes.StringEnum[awstypes.PrincipalType] `tfsdk:"principal_type"` +} diff --git a/internal/service/ssoadmin/application_assignments_data_source_test.go b/internal/service/ssoadmin/application_assignments_data_source_test.go new file mode 100644 index 00000000000..cb918ef46e7 --- /dev/null +++ b/internal/service/ssoadmin/application_assignments_data_source_test.go @@ -0,0 +1,87 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package ssoadmin_test + +import ( + "fmt" + "testing" + + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccSSOAdminApplicationAssignmentsDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_ssoadmin_application_assignments.test" + applicationResourceName := "aws_ssoadmin_application.test" + userResourceName := "aws_identitystore_user.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.SSOAdminEndpointID) + acctest.PreCheckSSOAdminInstances(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.SSOAdminEndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: testAccApplicationAssignmentsDataSourceConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, "application_arn", applicationResourceName, "application_arn"), + resource.TestCheckResourceAttr(dataSourceName, "application_assignments.#", "1"), + resource.TestCheckResourceAttrPair(dataSourceName, "application_assignments.0.application_arn", applicationResourceName, "application_arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "application_assignments.0.principal_id", userResourceName, "user_id"), + resource.TestCheckResourceAttr(dataSourceName, "application_assignments.0.principal_type", "USER"), + ), + }, + }, + }) +} + +func testAccApplicationAssignmentsDataSourceConfigBase(rName string) string { + return fmt.Sprintf(` +data "aws_ssoadmin_instances" "test" {} + +resource "aws_ssoadmin_application" "test" { + name = %[1]q + application_provider_arn = %[2]q + instance_arn = tolist(data.aws_ssoadmin_instances.test.arns)[0] +} + +resource "aws_identitystore_user" "test" { + identity_store_id = tolist(data.aws_ssoadmin_instances.test.identity_store_ids)[0] + + display_name = "Acceptance Test" + user_name = %[1]q + + name { + family_name = "Doe" + given_name = "John" + } +} + +resource "aws_ssoadmin_application_assignment" "test" { + application_arn = aws_ssoadmin_application.test.application_arn + principal_id = aws_identitystore_user.test.user_id + principal_type = "USER" +} +`, rName, testAccApplicationProviderARN) +} + +func testAccApplicationAssignmentsDataSourceConfig_basic(rName string) string { + return acctest.ConfigCompose( + testAccApplicationAssignmentsDataSourceConfigBase(rName), + ` +data "aws_ssoadmin_application_assignments" "test" { + depends_on = [aws_ssoadmin_application_assignment.test] + + application_arn = aws_ssoadmin_application.test.application_arn +} +`) +} diff --git a/internal/service/ssoadmin/service_package_gen.go b/internal/service/ssoadmin/service_package_gen.go index 882e10d2b48..e36305586d7 100644 --- a/internal/service/ssoadmin/service_package_gen.go +++ b/internal/service/ssoadmin/service_package_gen.go @@ -18,6 +18,10 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.Serv Factory: newDataSourceApplication, Name: "Application", }, + { + Factory: newDataSourceApplicationAssignments, + Name: "Application Assignments", + }, { Factory: newDataSourceApplicationProviders, Name: "Application Providers", diff --git a/website/docs/d/ssoadmin_application_assignments.html.markdown b/website/docs/d/ssoadmin_application_assignments.html.markdown new file mode 100644 index 00000000000..c2aa02660c4 --- /dev/null +++ b/website/docs/d/ssoadmin_application_assignments.html.markdown @@ -0,0 +1,39 @@ +--- +subcategory: "SSO Admin" +layout: "aws" +page_title: "AWS: aws_ssoadmin_application_assignments" +description: |- + Terraform data source for managing AWS SSO Admin Application Assignments. +--- + +# Data Source: aws_ssoadmin_application_assignments + +Terraform data source for managing AWS SSO Admin Application Assignments. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_ssoadmin_application_assignments" "example" { + application_arn = aws_ssoadmin_application.example.application_arn +} +``` + +## Argument Reference + +The following arguments are required: + +* `application_arn` - (Required) ARN of the application. + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `application_assignments` - List of principals assigned to the application. See the [`application_assignments` attribute reference](#application_assignments-attribute-reference) below. + +### `application_assignments` Attribute Reference + +* `application_arn` - ARN of the application. +* `principal_id` - An identifier for an object in IAM Identity Center, such as a user or group. +* `principal_type` - Entity type for which the assignment will be created. Valid values are `USER` or `GROUP`.