diff --git a/.changelog/45124.txt b/.changelog/45124.txt new file mode 100644 index 000000000000..25c5b2affd32 --- /dev/null +++ b/.changelog/45124.txt @@ -0,0 +1,7 @@ +```release-note:new-data-source +aws_bedrock_prompt_router +``` + +```release-note:new-data-source +aws_bedrock_prompt_routers +``` \ No newline at end of file diff --git a/internal/service/bedrock/prompt_router_data_source.go b/internal/service/bedrock/prompt_router_data_source.go new file mode 100644 index 000000000000..0ea78c1d6af0 --- /dev/null +++ b/internal/service/bedrock/prompt_router_data_source.go @@ -0,0 +1,144 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package bedrock + +import ( + "context" + "fmt" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/bedrock" + awstypes "github.com/aws/aws-sdk-go-v2/service/bedrock/types" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" + "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-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-provider-aws/internal/errs" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + fwflex "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/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkDataSource("aws_bedrock_prompt_router", name="Prompt Router") +func newPromptRouterDataSource(context.Context) (datasource.DataSourceWithConfigure, error) { + return &promptRouterDataSource{}, nil +} + +type promptRouterDataSource struct { + framework.DataSourceWithModel[promptRouterDataSourceModel] +} + +func (d *promptRouterDataSource) Schema(ctx context.Context, request datasource.SchemaRequest, response *datasource.SchemaResponse) { + response.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + names.AttrCreatedAt: schema.StringAttribute{ + CustomType: timetypes.RFC3339Type{}, + Computed: true, + }, + names.AttrDescription: schema.StringAttribute{ + Computed: true, + }, + "fallback_model": framework.DataSourceComputedListOfObjectAttribute[promptRouterTargetModelModel](ctx), + "models": framework.DataSourceComputedListOfObjectAttribute[promptRouterTargetModelModel](ctx), + "prompt_router_arn": schema.StringAttribute{ + CustomType: fwtypes.ARNType, + Required: true, + }, + "prompt_router_name": schema.StringAttribute{ + Computed: true, + }, + "routing_criteria": framework.DataSourceComputedListOfObjectAttribute[routingCriteriaModel](ctx), + names.AttrStatus: schema.StringAttribute{ + CustomType: fwtypes.StringEnumType[awstypes.PromptRouterStatus](), + Computed: true, + }, + names.AttrType: schema.StringAttribute{ + CustomType: fwtypes.StringEnumType[awstypes.PromptRouterType](), + Computed: true, + }, + "updated_at": schema.StringAttribute{ + CustomType: timetypes.RFC3339Type{}, + Computed: true, + }, + }, + } +} + +func (d *promptRouterDataSource) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { + var data promptRouterDataSourceModel + response.Diagnostics.Append(request.Config.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + conn := d.Meta().BedrockClient(ctx) + + output, err := findPromptRouterByARN(ctx, conn, data.PromptRouterARN.ValueString()) + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("reading Bedrock Prompt Router (%s)", data.PromptRouterARN.ValueString()), err.Error()) + return + } + + response.Diagnostics.Append(fwflex.Flatten(ctx, output, &data)...) + if response.Diagnostics.HasError() { + return + } + + response.Diagnostics.Append(response.State.Set(ctx, &data)...) +} + +func findPromptRouterByARN(ctx context.Context, conn *bedrock.Client, arn string) (*bedrock.GetPromptRouterOutput, error) { + input := &bedrock.GetPromptRouterInput{ + PromptRouterArn: aws.String(arn), + } + + return findPromptRouter(ctx, conn, input) +} + +func findPromptRouter(ctx context.Context, conn *bedrock.Client, input *bedrock.GetPromptRouterInput) (*bedrock.GetPromptRouterOutput, error) { + output, err := conn.GetPromptRouter(ctx, input) + + if errs.IsA[*awstypes.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + if output == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + return output, nil +} + +type promptRouterDataSourceModel struct { + framework.WithRegionModel + CreatedAt timetypes.RFC3339 `tfsdk:"created_at"` + Description types.String `tfsdk:"description"` + FallbackModel fwtypes.ListNestedObjectValueOf[promptRouterTargetModelModel] `tfsdk:"fallback_model"` + Models fwtypes.ListNestedObjectValueOf[promptRouterTargetModelModel] `tfsdk:"models"` + PromptRouterARN fwtypes.ARN `tfsdk:"prompt_router_arn"` + PromptRouterName types.String `tfsdk:"prompt_router_name"` + RoutingCriteria fwtypes.ListNestedObjectValueOf[routingCriteriaModel] `tfsdk:"routing_criteria"` + Status fwtypes.StringEnum[awstypes.PromptRouterStatus] `tfsdk:"status"` + Type fwtypes.StringEnum[awstypes.PromptRouterType] `tfsdk:"type"` + UpdatedAt timetypes.RFC3339 `tfsdk:"updated_at"` +} + +type promptRouterTargetModelModel struct { + ModelARN types.String `tfsdk:"model_arn"` +} + +type routingCriteriaModel struct { + ResponseQualityDifference types.Float64 `tfsdk:"response_quality_difference"` +} diff --git a/internal/service/bedrock/prompt_router_data_source_test.go b/internal/service/bedrock/prompt_router_data_source_test.go new file mode 100644 index 000000000000..a5e949d2def8 --- /dev/null +++ b/internal/service/bedrock/prompt_router_data_source_test.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package bedrock_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccBedrockPromptRouterDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + datasourceName := "data.aws_bedrock_prompt_router.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) }, + ErrorCheck: acctest.ErrorCheck(t, names.BedrockServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccPromptRouterDataSourceConfig_basic(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet(datasourceName, "prompt_router_arn"), + resource.TestCheckResourceAttrSet(datasourceName, "prompt_router_name"), + resource.TestCheckResourceAttrSet(datasourceName, names.AttrStatus), + resource.TestCheckResourceAttrSet(datasourceName, names.AttrType), + resource.TestCheckResourceAttrSet(datasourceName, names.AttrCreatedAt), + resource.TestCheckResourceAttrSet(datasourceName, "updated_at"), + ), + }, + }, + }) +} + +func testAccPromptRouterDataSourceConfig_basic() string { + return ` +data "aws_bedrock_prompt_routers" "test" {} + +data "aws_bedrock_prompt_router" "test" { + prompt_router_arn = data.aws_bedrock_prompt_routers.test.prompt_router_summaries[0].prompt_router_arn +} +` +} diff --git a/internal/service/bedrock/prompt_routers_data_source.go b/internal/service/bedrock/prompt_routers_data_source.go new file mode 100644 index 000000000000..1a2f0a6d86c5 --- /dev/null +++ b/internal/service/bedrock/prompt_routers_data_source.go @@ -0,0 +1,104 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package bedrock + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/service/bedrock" + awstypes "github.com/aws/aws-sdk-go-v2/service/bedrock/types" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" + "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/framework" + fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" +) + +// @FrameworkDataSource("aws_bedrock_prompt_routers", name="Prompt Routers") +func newPromptRoutersDataSource(context.Context) (datasource.DataSourceWithConfigure, error) { + return &promptRoutersDataSource{}, nil +} + +type promptRoutersDataSource struct { + framework.DataSourceWithModel[promptRoutersDataSourceModel] +} + +func (d *promptRoutersDataSource) Schema(ctx context.Context, request datasource.SchemaRequest, response *datasource.SchemaResponse) { + response.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "prompt_router_summaries": framework.DataSourceComputedListOfObjectAttribute[promptRouterSummaryModel](ctx), + }, + } +} + +func (d *promptRoutersDataSource) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { + var data promptRoutersDataSourceModel + response.Diagnostics.Append(request.Config.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + conn := d.Meta().BedrockClient(ctx) + + input := &bedrock.ListPromptRoutersInput{} + + response.Diagnostics.Append(fwflex.Expand(ctx, data, input)...) + if response.Diagnostics.HasError() { + return + } + + promptRouters, err := findPromptRouters(ctx, conn, input) + + if err != nil { + response.Diagnostics.AddError("listing Bedrock Prompt Routers", err.Error()) + return + } + + output := &bedrock.ListPromptRoutersOutput{ + PromptRouterSummaries: promptRouters, + } + response.Diagnostics.Append(fwflex.Flatten(ctx, output, &data)...) + if response.Diagnostics.HasError() { + return + } + + response.Diagnostics.Append(response.State.Set(ctx, &data)...) +} + +func findPromptRouters(ctx context.Context, conn *bedrock.Client, input *bedrock.ListPromptRoutersInput) ([]awstypes.PromptRouterSummary, error) { + var output = make([]awstypes.PromptRouterSummary, 0) + + pages := bedrock.NewListPromptRoutersPaginator(conn, input) + for pages.HasMorePages() { + page, err := pages.NextPage(ctx) + + if err != nil { + return nil, err + } + + output = append(output, page.PromptRouterSummaries...) + } + + return output, nil +} + +type promptRoutersDataSourceModel struct { + framework.WithRegionModel + PromptRouterSummaries fwtypes.ListNestedObjectValueOf[promptRouterSummaryModel] `tfsdk:"prompt_router_summaries"` +} + +type promptRouterSummaryModel struct { + CreatedAt timetypes.RFC3339 `tfsdk:"created_at"` + Description types.String `tfsdk:"description"` + FallbackModel fwtypes.ListNestedObjectValueOf[promptRouterTargetModelModel] `tfsdk:"fallback_model"` + Models fwtypes.ListNestedObjectValueOf[promptRouterTargetModelModel] `tfsdk:"models"` + PromptRouterARN fwtypes.ARN `tfsdk:"prompt_router_arn"` + PromptRouterName types.String `tfsdk:"prompt_router_name"` + RoutingCriteria fwtypes.ListNestedObjectValueOf[routingCriteriaModel] `tfsdk:"routing_criteria"` + Status fwtypes.StringEnum[awstypes.PromptRouterStatus] `tfsdk:"status"` + Type fwtypes.StringEnum[awstypes.PromptRouterType] `tfsdk:"type"` + UpdatedAt timetypes.RFC3339 `tfsdk:"updated_at"` +} diff --git a/internal/service/bedrock/prompt_routers_data_source_test.go b/internal/service/bedrock/prompt_routers_data_source_test.go new file mode 100644 index 000000000000..2810981e2b06 --- /dev/null +++ b/internal/service/bedrock/prompt_routers_data_source_test.go @@ -0,0 +1,37 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package bedrock_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccBedrockPromptRoutersDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + datasourceName := "data.aws_bedrock_prompt_routers.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) }, + ErrorCheck: acctest.ErrorCheck(t, names.BedrockServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccPromptRoutersDataSourceConfig_basic(), + Check: resource.ComposeTestCheckFunc( + acctest.CheckResourceAttrGreaterThanOrEqualValue(datasourceName, "prompt_router_summaries.#", 0), + ), + }, + }, + }) +} + +func testAccPromptRoutersDataSourceConfig_basic() string { + return ` +data "aws_bedrock_prompt_routers" "test" {} +` +} diff --git a/internal/service/bedrock/service_package_gen.go b/internal/service/bedrock/service_package_gen.go index cbe863945353..dc9659b9ebde 100644 --- a/internal/service/bedrock/service_package_gen.go +++ b/internal/service/bedrock/service_package_gen.go @@ -55,6 +55,18 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*inttypes.S Name: "Inference Profiles", Region: unique.Make(inttypes.ResourceRegionDefault()), }, + { + Factory: newPromptRouterDataSource, + TypeName: "aws_bedrock_prompt_router", + Name: "Prompt Router", + Region: unique.Make(inttypes.ResourceRegionDefault()), + }, + { + Factory: newPromptRoutersDataSource, + TypeName: "aws_bedrock_prompt_routers", + Name: "Prompt Routers", + Region: unique.Make(inttypes.ResourceRegionDefault()), + }, } } diff --git a/website/docs/d/bedrock_prompt_router.html.markdown b/website/docs/d/bedrock_prompt_router.html.markdown new file mode 100644 index 000000000000..65ba548766cd --- /dev/null +++ b/website/docs/d/bedrock_prompt_router.html.markdown @@ -0,0 +1,56 @@ +--- +subcategory: "Bedrock" +layout: "aws" +page_title: "AWS: aws_bedrock_prompt_router" +description: |- + Terraform data source for managing an AWS Bedrock Prompt Router. +--- + +# Data Source: aws_bedrock_prompt_router + +Terraform data source for managing an AWS Bedrock Prompt Router. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_bedrock_prompt_routers" "example" {} + +data "aws_bedrock_prompt_router" "example" { + prompt_router_arn = data.aws_bedrock_prompt_routers.example.prompt_router_summaries[0].prompt_router_arn +} +``` + +## Argument Reference + +This data source supports the following arguments: + +* `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference). +* `prompt_router_arn` - (Required) ARN of the prompt router. + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +- `created_at` - Time at which the prompt router was created. +- `description` - Description of the prompt router. +- `fallback_model` - List of information about the fallback model. See [`fallback_model`](#fallback_model). +- `models` - List of information about each model in the prompt router. See [`models`](#models). +- `prompt_router_name` - Name of the prompt router. +- `routing_criteria` - Routing criteria for the prompt router. See [`routing_criteria`](#routing_criteria). +- `status` - Status of the prompt router. `AVAILABLE` means that the prompt router is ready to route requests. +- `type` - Type of the prompt router. +- `updated_at` - Time at which the prompt router was last updated. + +### `fallback_model` + +- `model_arn` - Amazon Resource Name (ARN) of the fallback model. + +### `models` + +- `model_arn` - Amazon Resource Name (ARN) of the model. + +### `routing_criteria` + +- `response_quality_difference` - Threshold for the difference in quality between model responses. diff --git a/website/docs/d/bedrock_prompt_routers.html.markdown b/website/docs/d/bedrock_prompt_routers.html.markdown new file mode 100644 index 000000000000..f79118203f44 --- /dev/null +++ b/website/docs/d/bedrock_prompt_routers.html.markdown @@ -0,0 +1,56 @@ +--- +subcategory: "Bedrock" +layout: "aws" +page_title: "AWS: aws_bedrock_prompt_routers" +description: |- + Terraform data source for managing AWS Bedrock Prompt Routers. +--- + +# Data Source: aws_bedrock_prompt_routers + +Terraform data source for managing AWS Bedrock Prompt Routers. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_bedrock_prompt_routers" "example" {} +``` + +## Argument Reference + +This data source supports the following arguments: + +* `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference). + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +- `prompt_router_summaries` - List of prompt router summary objects. See [`prompt_router_summaries`](#prompt_router_summaries). + +### `prompt_router_summaries` + +- `created_at` - Time at which the prompt router was created. +- `description` - Description of the prompt router. +- `fallback_model` - List of information about the fallback model. See [`fallback_model`](#fallback_model). +- `models` - List of information about each model in the prompt router. See [`models`](#models). +- `prompt_router_arn` - Amazon Resource Name (ARN) of the prompt router. +- `prompt_router_name` - Name of the prompt router. +- `routing_criteria` - Routing criteria for the prompt router. See [`routing_criteria`](#routing_criteria). +- `status` - Status of the prompt router. `AVAILABLE` means that the prompt router is ready to route requests. +- `type` - Type of the prompt router. +- `updated_at` - Time at which the prompt router was last updated. + +### `fallback_model` + +- `model_arn` - Amazon Resource Name (ARN) of the fallback model. + +### `models` + +- `model_arn` - Amazon Resource Name (ARN) of the model. + +### `routing_criteria` + +- `response_quality_difference` - Threshold for the difference in quality between model responses.