From c7dc778eb1cf253e81608574e55c8785b8e4621a Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Thu, 4 Apr 2024 19:58:54 +0100 Subject: [PATCH 01/28] Revert "Remove other resource from this branch for PR" This reverts commit c50d19b625995d5387457fb865d2a2035885e904. --- .../bedrock_agent_action_group.go | 463 ++++++++++++++++++ .../bedrock_agent_action_group_test.go | 123 +++++ .../bedrockagent/service_package_gen.go | 4 + 3 files changed, 590 insertions(+) create mode 100644 internal/service/bedrockagent/bedrock_agent_action_group.go create mode 100644 internal/service/bedrockagent/bedrock_agent_action_group_test.go diff --git a/internal/service/bedrockagent/bedrock_agent_action_group.go b/internal/service/bedrockagent/bedrock_agent_action_group.go new file mode 100644 index 00000000000..82556e1f539 --- /dev/null +++ b/internal/service/bedrockagent/bedrock_agent_action_group.go @@ -0,0 +1,463 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package bedrockagent + +import ( + "context" + "fmt" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/bedrockagent" + awstypes "github.com/aws/aws-sdk-go-v2/service/bedrockagent/types" + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/errs" + "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" + "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" +) + +// @FrameworkResource(name="Bedrock Agent Action Group") +func newBedrockAgentActionGroupResource(context.Context) (resource.ResourceWithConfigure, error) { + r := &agentActionGroupResource{} + + r.SetDefaultDeleteTimeout(120 * time.Minute) + + return r, nil +} + +type agentActionGroupResource struct { + framework.ResourceWithConfigure + framework.WithImportByID + framework.WithTimeouts +} + +func (r *agentActionGroupResource) Metadata(_ context.Context, request resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "aws_bedrock_agent_action_group" +} + +func (r *agentActionGroupResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { + response.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "action_group_id": framework.IDAttribute(), + "action_group_name": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "action_group_state": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + + "agent_id": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "agent_version": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + + "client_token": schema.StringAttribute{ + Optional: true, + }, + "created_at": schema.StringAttribute{ + Computed: true, + }, + "description": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + names.AttrID: framework.IDAttribute(), + "parent_action_group_signature": schema.StringAttribute{ + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "prepared_at": schema.StringAttribute{ + Computed: true, + }, + "updated_at": schema.StringAttribute{ + Computed: true, + }, + }, + Blocks: map[string]schema.Block{ + "action_group_executor": schema.ListNestedBlock{ + CustomType: fwtypes.NewListNestedObjectTypeOf[actionGroupExecutor](ctx), + PlanModifiers: []planmodifier.List{ + listplanmodifier.RequiresReplace(), + }, + Validators: []validator.List{ + listvalidator.SizeAtMost(1), + }, + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "lambda": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + }, + }, + }, + "api_schema": schema.ListNestedBlock{ + CustomType: fwtypes.NewListNestedObjectTypeOf[apiSchema](ctx), + PlanModifiers: []planmodifier.List{ + listplanmodifier.RequiresReplace(), + }, + Validators: []validator.List{ + listvalidator.SizeAtMost(1), + }, + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "payload": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.ConflictsWith( + path.MatchRelative().AtParent().AtName("s3"), + ), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + }, + Blocks: map[string]schema.Block{ + "s3": schema.ListNestedBlock{ + CustomType: fwtypes.NewListNestedObjectTypeOf[s3](ctx), + Validators: []validator.List{ + listvalidator.SizeAtMost(1), + listvalidator.ConflictsWith( + path.MatchRelative().AtParent().AtName("payload"), + ), + }, + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "s3_bucket_name": schema.StringAttribute{ + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "s3_object_key": schema.StringAttribute{ + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func (r *agentActionGroupResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { + var data agentActionGroupResourceModel + response.Diagnostics.Append(request.Plan.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + conn := r.Meta().BedrockAgentClient(ctx) + + // input := &bedrockagent.CreateAgentActionGroupInput{} + // response.Diagnostics.Append(fwflex.Expand(ctx, data, input)...) + // if response.Diagnostics.HasError() { + // return + // } + + // if !data.ActionGroupExecutor.IsNull() { + // age, diags := data.ActionGroupExecutor.ToPtr(ctx) + // response.Diagnostics.Append(diags...) + // if response.Diagnostics.HasError() { + // return + // } + // input.ActionGroupExecutor = expandAge(age) + // } + + age, diags := data.ActionGroupExecutor.ToPtr(ctx) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + lambda := &awstypes.ActionGroupExecutorMemberLambda{ + Value: *fwflex.StringFromFramework(ctx, age.Lambda), + } + + apischema, diags := data.APISchema.ToPtr(ctx) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + s3, diags := apischema.S3.ToPtr(ctx) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + s3data := &awstypes.APISchemaMemberS3{} + response.Diagnostics.Append(fwflex.Expand(ctx, s3, &s3data.Value)...) + if response.Diagnostics.HasError() { + return + } + + input := &bedrockagent.CreateAgentActionGroupInput{ + ActionGroupName: data.ActionGroupName.ValueStringPointer(), + AgentId: data.AgentId.ValueStringPointer(), + AgentVersion: data.AgentVersion.ValueStringPointer(), + ActionGroupExecutor: lambda, + ApiSchema: s3data, + } + + output, err := conn.CreateAgentActionGroup(ctx, input) + + if err != nil { + response.Diagnostics.AddError("creating Bedrock Agent Group", err.Error()) + + return + } + + // Set values for unknowns. + //data.ActionGroupId = fwflex.StringToFramework(ctx, output.AgentActionGroup.ActionGroupId) + //data.ID = data.ActionGroupId + + var dataFromCreate agentActionGroupResourceModel + response.Diagnostics.Append(fwflex.Flatten(ctx, output.AgentActionGroup, &dataFromCreate)...) + data.CreatedAt = dataFromCreate.CreatedAt + data.UpdatedAt = dataFromCreate.UpdatedAt + data.PreparedAt = dataFromCreate.PreparedAt + data.ActionGroupState = dataFromCreate.ActionGroupState + data.Description = dataFromCreate.Description + data.AgentId = dataFromCreate.AgentId + data.ActionGroupId = dataFromCreate.ActionGroupId + data.AgentVersion = dataFromCreate.AgentVersion + data.ID = dataFromCreate.ActionGroupId + + response.Diagnostics.Append(response.State.Set(ctx, &data)...) +} + +func (r *agentActionGroupResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { + var data agentActionGroupResourceModel + response.Diagnostics.Append(request.State.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + if data.ID.IsNull() { + response.Diagnostics.AddError("parsing resource ID", "Action Group ID") + + return + } + + conn := r.Meta().BedrockAgentClient(ctx) + + AgentId := data.AgentId.ValueString() + ActionGroupId := data.ActionGroupId.ValueString() + AgentVersion := data.AgentVersion.ValueString() + + output, err := findAgentActionGroupByID(ctx, conn, ActionGroupId, AgentId, AgentVersion) + + if tfresource.NotFound(err) { + response.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err)) + response.State.RemoveResource(ctx) + + return + } + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("reading Bedrock Agent (%s)", AgentId), 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 (r *agentActionGroupResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { + var old, new agentActionGroupResourceModel + response.Diagnostics.Append(request.State.Get(ctx, &old)...) + if response.Diagnostics.HasError() { + return + } + response.Diagnostics.Append(request.Plan.Get(ctx, &new)...) + if response.Diagnostics.HasError() { + return + } + + conn := r.Meta().BedrockAgentClient(ctx) + + if agentActionGroupHasChanges(ctx, old, new) { + input := &bedrockagent.UpdateAgentActionGroupInput{} + response.Diagnostics.Append(fwflex.Expand(ctx, new, input)...) + if response.Diagnostics.HasError() { + return + } + + _, err := conn.UpdateAgentActionGroup(ctx, input) + + if err != nil { + response.Diagnostics.AddError( + create.ProblemStandardMessage(names.BedrockAgent, create.ErrActionUpdating, "Bedrock Agent", old.AgentId.ValueString(), err), + err.Error(), + ) + return + } + } + + out, err := findAgentActionGroupByID(ctx, conn, old.ActionGroupId.String(), old.ID.ValueString(), old.AgentVersion.ValueString()) + if err != nil { + response.Diagnostics.AddError( + create.ProblemStandardMessage(names.BedrockAgent, create.ErrActionUpdating, "Bedrock Agent", old.AgentId.ValueString(), err), + err.Error(), + ) + return + } + response.Diagnostics.Append(fwflex.Flatten(ctx, out, &new)...) + if response.Diagnostics.HasError() { + return + } + + response.Diagnostics.Append(response.State.Set(ctx, &new)...) +} + +func (r *agentActionGroupResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { + var data agentActionGroupResourceModel + response.Diagnostics.Append(request.State.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + conn := r.Meta().BedrockAgentClient(ctx) + + if !data.ActionGroupId.IsNull() { + _, err := conn.DeleteAgentActionGroup(ctx, &bedrockagent.DeleteAgentActionGroupInput{ + AgentId: fwflex.StringFromFramework(ctx, data.AgentId), + ActionGroupId: fwflex.StringFromFramework(ctx, data.ActionGroupId), + AgentVersion: fwflex.StringFromFramework(ctx, data.AgentVersion), + }) + + if errs.IsA[*awstypes.ResourceNotFoundException](err) { + return + } + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("deleting Bedrock Agent (%s)", data.ID.ValueString()), err.Error()) + + return + } + } +} + +// func (r *agentActionGroupResource) ModifyPlan(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse) { +// r.SetTagsAll(ctx, request, response) +// } + +func findAgentActionGroupByID(ctx context.Context, conn *bedrockagent.Client, grpid, agentid, agentversion string) (*bedrockagent.GetAgentActionGroupOutput, error) { + input := &bedrockagent.GetAgentActionGroupInput{ + ActionGroupId: aws.String(grpid), + AgentId: aws.String(agentid), + AgentVersion: aws.String(agentversion), + } + + output, err := conn.GetAgentActionGroup(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 agentActionGroupResourceModel struct { + ActionGroupId types.String `tfsdk:"action_group_id"` + ActionGroupExecutor fwtypes.ListNestedObjectValueOf[actionGroupExecutor] `tfsdk:"action_group_executor"` + ActionGroupName types.String `tfsdk:"action_group_name"` + ActionGroupState types.String `tfsdk:"action_group_state"` + AgentId types.String `tfsdk:"agent_id"` + AgentVersion types.String `tfsdk:"agent_version"` + APISchema fwtypes.ListNestedObjectValueOf[apiSchema] `tfsdk:"api_schema"` + ClientToken types.String `tfsdk:"client_token"` + CreatedAt types.String `tfsdk:"created_at"` + Description types.String `tfsdk:"description"` + ID types.String `tfsdk:"id"` + ParentActionGroupSignature types.String `tfsdk:"parent_action_group_signature"` + PreparedAt types.String `tfsdk:"prepared_at"` + UpdatedAt types.String `tfsdk:"updated_at"` +} + +type actionGroupExecutor struct { + Lambda types.String `tfsdk:"lambda"` +} + +type apiSchema struct { + Payload types.String `tfsdk:"payload"` + S3 fwtypes.ListNestedObjectValueOf[s3] `tfsdk:"s3"` +} + +type s3 struct { + S3BucketName types.String `tfsdk:"s3_bucket_name"` + S3ObjectKey types.String `tfsdk:"s3_object_key"` +} + +func agentActionGroupHasChanges(_ context.Context, plan, state agentActionGroupResourceModel) bool { + return !plan.ActionGroupName.Equal(state.ActionGroupName) || + !plan.Description.Equal(state.Description) +} + +func expandAge(agedata *actionGroupExecutor) awstypes.ActionGroupExecutor { + if !agedata.Lambda.IsNull() { + return &awstypes.ActionGroupExecutorMemberLambda{ + Value: agedata.Lambda.ValueString(), + } + } + return nil +} diff --git a/internal/service/bedrockagent/bedrock_agent_action_group_test.go b/internal/service/bedrockagent/bedrock_agent_action_group_test.go new file mode 100644 index 00000000000..bdbe6861721 --- /dev/null +++ b/internal/service/bedrockagent/bedrock_agent_action_group_test.go @@ -0,0 +1,123 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package bedrockagent_test + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/bedrockagent" + "github.com/aws/aws-sdk-go-v2/service/m2/types" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/errs" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccBedrockAgentActionGroup_basic(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_bedrock_agent_action_group.test" + var v bedrockagent.GetAgentActionGroupOutput + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) }, + ErrorCheck: acctest.ErrorCheck(t, names.BedrockAgentServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckBedrockAgentActionGroupDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccBedrockAgentActionGroupConfig_basic(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckBedrockAgentActionGroupExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "action_group_name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckBedrockAgentActionGroupDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).BedrockAgentClient(ctx) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_bedrock_agent_action_group" { + continue + } + + _, err := conn.GetAgentActionGroup(ctx, &bedrockagent.GetAgentActionGroupInput{ + ActionGroupId: aws.String(rs.Primary.ID), + AgentId: aws.String(rs.Primary.Attributes["agent_id"]), + AgentVersion: aws.String(rs.Primary.Attributes["agent_version"]), + }) + + if errs.IsA[*types.ResourceNotFoundException](err) { + return nil + } + if err != nil { + return create.Error(names.BedrockAgent, create.ErrActionCheckingDestroyed, "Bedrock Agent", rs.Primary.ID, err) + } + + return create.Error(names.BedrockAgent, create.ErrActionCheckingDestroyed, "Bedrock Agent", rs.Primary.ID, errors.New("not destroyed")) + } + + return nil + } +} +func testAccCheckBedrockAgentActionGroupExists(ctx context.Context, n string, v *bedrockagent.GetAgentActionGroupOutput) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).BedrockAgentClient(ctx) + + output, err := conn.GetAgentActionGroup(ctx, &bedrockagent.GetAgentActionGroupInput{ + ActionGroupId: aws.String(rs.Primary.ID), + AgentId: aws.String(*v.AgentActionGroup.AgentId), + AgentVersion: aws.String(*v.AgentActionGroup.AgentVersion), + }) + + if err != nil { + return err + } + + *v = *output + + return nil + } +} + +func testAccBedrockAgentActionGroupConfig_basic(rName string) string { + return fmt.Sprintf(` +resource "aws_bedrock_agent_action_group" "test" { + action_group_name = %[1]q + agent_id = "TLJ2L6TKGM" + agent_version = "DRAFT" + action_group_executor { + lambda = "arn:aws:lambda:us-west-2:xxxxxxxxxxxx:function:sairam:1" + } + api_schema { + s3 { + s3_bucket_name = "tf-acc-test-3678246384762388142" + s3_object_key = "sai.yaml" + } + } +} +`, rName) +} diff --git a/internal/service/bedrockagent/service_package_gen.go b/internal/service/bedrockagent/service_package_gen.go index 1141a63ff82..c7c2bcf9f0d 100644 --- a/internal/service/bedrockagent/service_package_gen.go +++ b/internal/service/bedrockagent/service_package_gen.go @@ -20,6 +20,10 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.Serv func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { return []*types.ServicePackageFrameworkResource{ + { + Factory: newBedrockAgentActionGroupResource, + Name: "Bedrock Agent Action Group", + }, { Factory: newBedrockAgentResource, Name: "Bedrock Agent", From 5540250bc373c7add8c8557187a05269eb69a90d Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Thu, 4 Apr 2024 20:01:36 +0100 Subject: [PATCH 02/28] Rename file appropriately. --- .../{bedrock_agent_action_group.go => action_group.go} | 0 .../{bedrock_agent_action_group_test.go => action_group_test.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename internal/service/bedrockagent/{bedrock_agent_action_group.go => action_group.go} (100%) rename internal/service/bedrockagent/{bedrock_agent_action_group_test.go => action_group_test.go} (100%) diff --git a/internal/service/bedrockagent/bedrock_agent_action_group.go b/internal/service/bedrockagent/action_group.go similarity index 100% rename from internal/service/bedrockagent/bedrock_agent_action_group.go rename to internal/service/bedrockagent/action_group.go diff --git a/internal/service/bedrockagent/bedrock_agent_action_group_test.go b/internal/service/bedrockagent/action_group_test.go similarity index 100% rename from internal/service/bedrockagent/bedrock_agent_action_group_test.go rename to internal/service/bedrockagent/action_group_test.go From 58980e55331f3c4fcb497213424169d3677f7215 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Thu, 4 Apr 2024 20:03:35 +0100 Subject: [PATCH 03/28] Some basic renaming --- internal/service/bedrockagent/action_group.go | 16 ++++++++-------- .../service/bedrockagent/action_group_test.go | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/service/bedrockagent/action_group.go b/internal/service/bedrockagent/action_group.go index 82556e1f539..7d7d1a94228 100644 --- a/internal/service/bedrockagent/action_group.go +++ b/internal/service/bedrockagent/action_group.go @@ -48,7 +48,7 @@ type agentActionGroupResource struct { } func (r *agentActionGroupResource) Metadata(_ context.Context, request resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = "aws_bedrock_agent_action_group" + resp.TypeName = "aws_bedrockagent_action_group" } func (r *agentActionGroupResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { @@ -185,7 +185,7 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. } func (r *agentActionGroupResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { - var data agentActionGroupResourceModel + var data actionGroupResourceModel response.Diagnostics.Append(request.Plan.Get(ctx, &data)...) if response.Diagnostics.HasError() { return @@ -254,7 +254,7 @@ func (r *agentActionGroupResource) Create(ctx context.Context, request resource. //data.ActionGroupId = fwflex.StringToFramework(ctx, output.AgentActionGroup.ActionGroupId) //data.ID = data.ActionGroupId - var dataFromCreate agentActionGroupResourceModel + var dataFromCreate actionGroupResourceModel response.Diagnostics.Append(fwflex.Flatten(ctx, output.AgentActionGroup, &dataFromCreate)...) data.CreatedAt = dataFromCreate.CreatedAt data.UpdatedAt = dataFromCreate.UpdatedAt @@ -270,7 +270,7 @@ func (r *agentActionGroupResource) Create(ctx context.Context, request resource. } func (r *agentActionGroupResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { - var data agentActionGroupResourceModel + var data actionGroupResourceModel response.Diagnostics.Append(request.State.Get(ctx, &data)...) if response.Diagnostics.HasError() { return @@ -312,7 +312,7 @@ func (r *agentActionGroupResource) Read(ctx context.Context, request resource.Re } func (r *agentActionGroupResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { - var old, new agentActionGroupResourceModel + var old, new actionGroupResourceModel response.Diagnostics.Append(request.State.Get(ctx, &old)...) if response.Diagnostics.HasError() { return @@ -359,7 +359,7 @@ func (r *agentActionGroupResource) Update(ctx context.Context, request resource. } func (r *agentActionGroupResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { - var data agentActionGroupResourceModel + var data actionGroupResourceModel response.Diagnostics.Append(request.State.Get(ctx, &data)...) if response.Diagnostics.HasError() { return @@ -417,7 +417,7 @@ func findAgentActionGroupByID(ctx context.Context, conn *bedrockagent.Client, gr return output, nil } -type agentActionGroupResourceModel struct { +type actionGroupResourceModel struct { ActionGroupId types.String `tfsdk:"action_group_id"` ActionGroupExecutor fwtypes.ListNestedObjectValueOf[actionGroupExecutor] `tfsdk:"action_group_executor"` ActionGroupName types.String `tfsdk:"action_group_name"` @@ -448,7 +448,7 @@ type s3 struct { S3ObjectKey types.String `tfsdk:"s3_object_key"` } -func agentActionGroupHasChanges(_ context.Context, plan, state agentActionGroupResourceModel) bool { +func agentActionGroupHasChanges(_ context.Context, plan, state actionGroupResourceModel) bool { return !plan.ActionGroupName.Equal(state.ActionGroupName) || !plan.Description.Equal(state.Description) } diff --git a/internal/service/bedrockagent/action_group_test.go b/internal/service/bedrockagent/action_group_test.go index bdbe6861721..8c197d8d2b1 100644 --- a/internal/service/bedrockagent/action_group_test.go +++ b/internal/service/bedrockagent/action_group_test.go @@ -25,7 +25,7 @@ import ( func TestAccBedrockAgentActionGroup_basic(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_bedrock_agent_action_group.test" + resourceName := "aws_bedrockagent_action_group.test" var v bedrockagent.GetAgentActionGroupOutput resource.ParallelTest(t, resource.TestCase{ @@ -105,7 +105,7 @@ func testAccCheckBedrockAgentActionGroupExists(ctx context.Context, n string, v func testAccBedrockAgentActionGroupConfig_basic(rName string) string { return fmt.Sprintf(` -resource "aws_bedrock_agent_action_group" "test" { +resource "aws_bedrockagent_action_group" "test" { action_group_name = %[1]q agent_id = "TLJ2L6TKGM" agent_version = "DRAFT" From 68dfdf586a23cb2ec0d1f1bcdfb3ab2fa7721f2c Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Mon, 15 Apr 2024 11:57:20 +0100 Subject: [PATCH 04/28] Rename to match API names --- .../{action_group.go => agent_action_group.go} | 4 ++-- .../{action_group_test.go => agent_action_group_test.go} | 0 internal/service/bedrockagent/service_package_gen.go | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) rename internal/service/bedrockagent/{action_group.go => agent_action_group.go} (99%) rename internal/service/bedrockagent/{action_group_test.go => agent_action_group_test.go} (100%) diff --git a/internal/service/bedrockagent/action_group.go b/internal/service/bedrockagent/agent_action_group.go similarity index 99% rename from internal/service/bedrockagent/action_group.go rename to internal/service/bedrockagent/agent_action_group.go index 7d7d1a94228..c1c0be5d4d4 100644 --- a/internal/service/bedrockagent/action_group.go +++ b/internal/service/bedrockagent/agent_action_group.go @@ -33,7 +33,7 @@ import ( ) // @FrameworkResource(name="Bedrock Agent Action Group") -func newBedrockAgentActionGroupResource(context.Context) (resource.ResourceWithConfigure, error) { +func newAgentActionGroupResource(context.Context) (resource.ResourceWithConfigure, error) { r := &agentActionGroupResource{} r.SetDefaultDeleteTimeout(120 * time.Minute) @@ -48,7 +48,7 @@ type agentActionGroupResource struct { } func (r *agentActionGroupResource) Metadata(_ context.Context, request resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = "aws_bedrockagent_action_group" + resp.TypeName = "aws_bedrockagent_agent_action_group" } func (r *agentActionGroupResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { diff --git a/internal/service/bedrockagent/action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go similarity index 100% rename from internal/service/bedrockagent/action_group_test.go rename to internal/service/bedrockagent/agent_action_group_test.go diff --git a/internal/service/bedrockagent/service_package_gen.go b/internal/service/bedrockagent/service_package_gen.go index f5f33087e10..616167ac572 100644 --- a/internal/service/bedrockagent/service_package_gen.go +++ b/internal/service/bedrockagent/service_package_gen.go @@ -20,6 +20,10 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.Serv func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { return []*types.ServicePackageFrameworkResource{ + { + Factory: newAgentActionGroupResource, + Name: "Bedrock Agent Action Group", + }, { Factory: newAgentAliasResource, Name: "Bedrock Agent Alias", @@ -34,10 +38,6 @@ func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.Servic IdentifierAttribute: "agent_arn", }, }, - { - Factory: newBedrockAgentActionGroupResource, - Name: "Bedrock Agent Action Group", - }, } } From aae2ed1c807ede2f1fe072f2c43545bc4f267b90 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Tue, 16 Apr 2024 14:41:31 +0100 Subject: [PATCH 05/28] Work to tidy up a bit --- .../bedrockagent/agent_action_group.go | 175 ++++++++++++------ .../bedrockagent/agent_action_group_test.go | 6 +- 2 files changed, 118 insertions(+), 63 deletions(-) diff --git a/internal/service/bedrockagent/agent_action_group.go b/internal/service/bedrockagent/agent_action_group.go index c1c0be5d4d4..52c7097adea 100644 --- a/internal/service/bedrockagent/agent_action_group.go +++ b/internal/service/bedrockagent/agent_action_group.go @@ -6,6 +6,7 @@ package bedrockagent import ( "context" "fmt" + "github.com/hashicorp/terraform-plugin-framework/diag" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -193,56 +194,28 @@ func (r *agentActionGroupResource) Create(ctx context.Context, request resource. conn := r.Meta().BedrockAgentClient(ctx) - // input := &bedrockagent.CreateAgentActionGroupInput{} - // response.Diagnostics.Append(fwflex.Expand(ctx, data, input)...) - // if response.Diagnostics.HasError() { - // return - // } - - // if !data.ActionGroupExecutor.IsNull() { - // age, diags := data.ActionGroupExecutor.ToPtr(ctx) - // response.Diagnostics.Append(diags...) - // if response.Diagnostics.HasError() { - // return - // } - // input.ActionGroupExecutor = expandAge(age) - // } - - age, diags := data.ActionGroupExecutor.ToPtr(ctx) - response.Diagnostics.Append(diags...) - if response.Diagnostics.HasError() { - return - } - lambda := &awstypes.ActionGroupExecutorMemberLambda{ - Value: *fwflex.StringFromFramework(ctx, age.Lambda), - } + var input bedrockagent.CreateAgentActionGroupInput + response.Diagnostics.Append(fwflex.Expand(ctx, data, &input)...) - apischema, diags := data.APISchema.ToPtr(ctx) + apiConfig, diags := expandApiSchema(ctx, data.APISchema) response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { return } - s3, diags := apischema.S3.ToPtr(ctx) + input.ApiSchema = apiConfig + + ageConfig, diags := expandActionGroupExecutor(ctx, data.ActionGroupExecutor) response.Diagnostics.Append(diags...) - if response.Diagnostics.HasError() { - return - } - s3data := &awstypes.APISchemaMemberS3{} - response.Diagnostics.Append(fwflex.Expand(ctx, s3, &s3data.Value)...) + if response.Diagnostics.HasError() { return } - input := &bedrockagent.CreateAgentActionGroupInput{ - ActionGroupName: data.ActionGroupName.ValueStringPointer(), - AgentId: data.AgentId.ValueStringPointer(), - AgentVersion: data.AgentVersion.ValueStringPointer(), - ActionGroupExecutor: lambda, - ApiSchema: s3data, - } + input.ActionGroupExecutor = ageConfig - output, err := conn.CreateAgentActionGroup(ctx, input) + output, err := conn.CreateAgentActionGroup(ctx, &input) if err != nil { response.Diagnostics.AddError("creating Bedrock Agent Group", err.Error()) @@ -250,20 +223,8 @@ func (r *agentActionGroupResource) Create(ctx context.Context, request resource. return } - // Set values for unknowns. - //data.ActionGroupId = fwflex.StringToFramework(ctx, output.AgentActionGroup.ActionGroupId) - //data.ID = data.ActionGroupId - var dataFromCreate actionGroupResourceModel response.Diagnostics.Append(fwflex.Flatten(ctx, output.AgentActionGroup, &dataFromCreate)...) - data.CreatedAt = dataFromCreate.CreatedAt - data.UpdatedAt = dataFromCreate.UpdatedAt - data.PreparedAt = dataFromCreate.PreparedAt - data.ActionGroupState = dataFromCreate.ActionGroupState - data.Description = dataFromCreate.Description - data.AgentId = dataFromCreate.AgentId - data.ActionGroupId = dataFromCreate.ActionGroupId - data.AgentVersion = dataFromCreate.AgentVersion data.ID = dataFromCreate.ActionGroupId response.Diagnostics.Append(response.State.Set(ctx, &data)...) @@ -308,6 +269,22 @@ func (r *agentActionGroupResource) Read(ctx context.Context, request resource.Re return } + apiSchemaData, moreDiags := flattenApiSchema(ctx, output.AgentActionGroup.ApiSchema) + response.Diagnostics.Append(moreDiags...) + if response.Diagnostics.HasError() { + return + } + + data.APISchema = apiSchemaData + + ageData, moreDiags := flattenActionGroupExecutor(ctx, output.AgentActionGroup.ActionGroupExecutor) + response.Diagnostics.Append(moreDiags...) + if response.Diagnostics.HasError() { + return + } + + data.ActionGroupExecutor = ageData + response.Diagnostics.Append(response.State.Set(ctx, &data)...) } @@ -331,6 +308,24 @@ func (r *agentActionGroupResource) Update(ctx context.Context, request resource. return } + apiConfig, diags := expandApiSchema(ctx, new.APISchema) + response.Diagnostics.Append(diags...) + + if response.Diagnostics.HasError() { + return + } + + input.ApiSchema = apiConfig + + ageConfig, diags := expandActionGroupExecutor(ctx, new.ActionGroupExecutor) + response.Diagnostics.Append(diags...) + + if response.Diagnostics.HasError() { + return + } + + input.ActionGroupExecutor = ageConfig + _, err := conn.UpdateAgentActionGroup(ctx, input) if err != nil { @@ -386,10 +381,6 @@ func (r *agentActionGroupResource) Delete(ctx context.Context, request resource. } } -// func (r *agentActionGroupResource) ModifyPlan(ctx context.Context, request resource.ModifyPlanRequest, response *resource.ModifyPlanResponse) { -// r.SetTagsAll(ctx, request, response) -// } - func findAgentActionGroupByID(ctx context.Context, conn *bedrockagent.Client, grpid, agentid, agentversion string) (*bedrockagent.GetAgentActionGroupOutput, error) { input := &bedrockagent.GetAgentActionGroupInput{ ActionGroupId: aws.String(grpid), @@ -453,11 +444,75 @@ func agentActionGroupHasChanges(_ context.Context, plan, state actionGroupResour !plan.Description.Equal(state.Description) } -func expandAge(agedata *actionGroupExecutor) awstypes.ActionGroupExecutor { - if !agedata.Lambda.IsNull() { - return &awstypes.ActionGroupExecutorMemberLambda{ - Value: agedata.Lambda.ValueString(), - } +func expandActionGroupExecutor(ctx context.Context, age fwtypes.ListNestedObjectValueOf[actionGroupExecutor]) (awstypes.ActionGroupExecutor, diag.Diagnostics) { + var diags diag.Diagnostics + var ageObject awstypes.ActionGroupExecutor + planAge, moreDiags := age.ToPtr(ctx) + + diags.Append(moreDiags...) + if diags.HasError() { + return ageObject, diags + } + + if !planAge.Lambda.IsNull() { + var lambdaAge awstypes.ActionGroupExecutorMemberLambda + diags.Append(fwflex.Expand(ctx, planAge.Lambda, &lambdaAge.Value)...) + ageObject = &lambdaAge + } + + return ageObject, diags +} + +func flattenActionGroupExecutor(ctx context.Context, age awstypes.ActionGroupExecutor) (fwtypes.ListNestedObjectValueOf[actionGroupExecutor], diag.Diagnostics) { + var ageData actionGroupExecutor + switch v := age.(type) { + case *awstypes.ActionGroupExecutorMemberLambda: + ageData.Lambda = fwflex.StringValueToFramework(ctx, v.Value) + } + + return fwtypes.NewListNestedObjectValueOfPtr(ctx, &ageData) +} + +func expandApiSchema(ctx context.Context, api fwtypes.ListNestedObjectValueOf[apiSchema]) (awstypes.APISchema, diag.Diagnostics) { + var diags diag.Diagnostics + var apiObject awstypes.APISchema + planApi, moreDiags := api.ToPtr(ctx) + diags.Append(moreDiags...) + if diags.HasError() { + return apiObject, diags + } + + if !planApi.S3.IsNull() { + var s3 awstypes.APISchemaMemberS3 + diags.Append(fwflex.Expand(ctx, planApi.S3, &s3.Value)...) + apiObject = &s3 } - return nil + + if !planApi.Payload.IsNull() { + var payload awstypes.APISchemaMemberPayload + diags.Append(fwflex.Expand(ctx, planApi.Payload, &payload.Value)...) + apiObject = &payload + } + return apiObject, diags +} + +func flattenApiSchema(ctx context.Context, apiObject awstypes.APISchema) (fwtypes.ListNestedObjectValueOf[apiSchema], diag.Diagnostics) { + var diags diag.Diagnostics + var apiSchemaData []*apiSchema + + switch v := apiObject.(type) { + case *awstypes.APISchemaMemberS3: + var s3data s3 + diags.Append(fwflex.Flatten(ctx, v, s3data)...) + apiSchemaData = append(apiSchemaData, &apiSchema{S3: fwtypes.NewListNestedObjectValueOfPtrMust(ctx, &s3data)}) + case *awstypes.APISchemaMemberPayload: + payloadValue := fwflex.StringValueToFramework(ctx, v.Value) + apiValue := apiSchema{Payload: payloadValue} + apiSchemaData = append(apiSchemaData, &apiValue) + } + + apiSchemaDataReturn, moreDiags := fwtypes.NewListNestedObjectValueOfSlice(ctx, apiSchemaData) + diags.Append(moreDiags...) + + return apiSchemaDataReturn, diags } diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index 8c197d8d2b1..d574fbe7660 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -104,10 +104,10 @@ func testAccCheckBedrockAgentActionGroupExists(ctx context.Context, n string, v } func testAccBedrockAgentActionGroupConfig_basic(rName string) string { - return fmt.Sprintf(` + return acctest.ConfigCompose(testAccAgentConfig_basic(rName, "anthropic.claude-v2", "basic claude"), fmt.Sprintf(` resource "aws_bedrockagent_action_group" "test" { action_group_name = %[1]q - agent_id = "TLJ2L6TKGM" + agent_id = aws_bedrockagent_agent.test.agent_id agent_version = "DRAFT" action_group_executor { lambda = "arn:aws:lambda:us-west-2:xxxxxxxxxxxx:function:sairam:1" @@ -119,5 +119,5 @@ resource "aws_bedrockagent_action_group" "test" { } } } -`, rName) +`, rName)) } From 22446fa1a22dcdac196db5455a01187aaf99a953 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Tue, 16 Apr 2024 18:09:14 +0100 Subject: [PATCH 06/28] Get basic tests running --- .../bedrockagent/agent_action_group.go | 109 +++++++++++------- .../bedrockagent/agent_action_group_test.go | 64 +++++++--- internal/service/bedrockagent/export_tests.go | 5 +- .../test-fixtures/api_schema.yaml | 23 ++++ .../test-fixtures/lambda_function.py | 24 ++++ .../test-fixtures/lambda_function.zip | Bin 0 -> 467 bytes 6 files changed, 165 insertions(+), 60 deletions(-) create mode 100644 internal/service/bedrockagent/test-fixtures/api_schema.yaml create mode 100644 internal/service/bedrockagent/test-fixtures/lambda_function.py create mode 100644 internal/service/bedrockagent/test-fixtures/lambda_function.zip diff --git a/internal/service/bedrockagent/agent_action_group.go b/internal/service/bedrockagent/agent_action_group.go index 52c7097adea..6ecc70d3eb0 100644 --- a/internal/service/bedrockagent/agent_action_group.go +++ b/internal/service/bedrockagent/agent_action_group.go @@ -6,7 +6,10 @@ package bedrockagent import ( "context" "fmt" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" + intflex "github.com/hashicorp/terraform-provider-aws/internal/flex" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -33,6 +36,10 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) +const ( + agentActionGroupIdParts = 3 +) + // @FrameworkResource(name="Bedrock Agent Action Group") func newAgentActionGroupResource(context.Context) (resource.ResourceWithConfigure, error) { r := &agentActionGroupResource{} @@ -82,16 +89,12 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. stringplanmodifier.RequiresReplace(), }, }, - - "client_token": schema.StringAttribute{ - Optional: true, - }, "created_at": schema.StringAttribute{ - Computed: true, + CustomType: timetypes.RFC3339Type{}, + Computed: true, }, "description": schema.StringAttribute{ Optional: true, - Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), }, @@ -103,11 +106,14 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. stringplanmodifier.UseStateForUnknown(), }, }, - "prepared_at": schema.StringAttribute{ + "skip_resource_in_use_check": schema.BoolAttribute{ Computed: true, + Default: booldefault.StaticBool(false), + Optional: true, }, "updated_at": schema.StringAttribute{ - Computed: true, + CustomType: timetypes.RFC3339Type{}, + Computed: true, }, }, Blocks: map[string]schema.Block{ @@ -197,23 +203,23 @@ func (r *agentActionGroupResource) Create(ctx context.Context, request resource. var input bedrockagent.CreateAgentActionGroupInput response.Diagnostics.Append(fwflex.Expand(ctx, data, &input)...) - apiConfig, diags := expandApiSchema(ctx, data.APISchema) + apiSchemaInput, diags := expandApiSchema(ctx, data.APISchema) response.Diagnostics.Append(diags...) if response.Diagnostics.HasError() { return } - input.ApiSchema = apiConfig + input.ApiSchema = apiSchemaInput - ageConfig, diags := expandActionGroupExecutor(ctx, data.ActionGroupExecutor) + actionGroupExecutorInput, diags := expandActionGroupExecutor(ctx, data.ActionGroupExecutor) response.Diagnostics.Append(diags...) if response.Diagnostics.HasError() { return } - input.ActionGroupExecutor = ageConfig + input.ActionGroupExecutor = actionGroupExecutorInput output, err := conn.CreateAgentActionGroup(ctx, &input) @@ -223,9 +229,14 @@ func (r *agentActionGroupResource) Create(ctx context.Context, request resource. return } - var dataFromCreate actionGroupResourceModel - response.Diagnostics.Append(fwflex.Flatten(ctx, output.AgentActionGroup, &dataFromCreate)...) - data.ID = dataFromCreate.ActionGroupId + response.Diagnostics.Append(fwflex.Flatten(ctx, output.AgentActionGroup, &data)...) + + err = data.setId() + if err != nil { + response.Diagnostics.AddError("creating Bedrock Agent Group", err.Error()) + + return + } response.Diagnostics.Append(response.State.Set(ctx, &data)...) } @@ -245,11 +256,7 @@ func (r *agentActionGroupResource) Read(ctx context.Context, request resource.Re conn := r.Meta().BedrockAgentClient(ctx) - AgentId := data.AgentId.ValueString() - ActionGroupId := data.ActionGroupId.ValueString() - AgentVersion := data.AgentVersion.ValueString() - - output, err := findAgentActionGroupByID(ctx, conn, ActionGroupId, AgentId, AgentVersion) + output, err := findAgentActionGroupByID(ctx, conn, data.ID.ValueString()) if tfresource.NotFound(err) { response.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err)) @@ -259,12 +266,12 @@ func (r *agentActionGroupResource) Read(ctx context.Context, request resource.Re } if err != nil { - response.Diagnostics.AddError(fmt.Sprintf("reading Bedrock Agent (%s)", AgentId), err.Error()) + response.Diagnostics.AddError(fmt.Sprintf("reading Bedrock Agent (%s)", data.ID.ValueString()), err.Error()) return } - response.Diagnostics.Append(fwflex.Flatten(ctx, output, &data)...) + response.Diagnostics.Append(fwflex.Flatten(ctx, output.AgentActionGroup, &data)...) if response.Diagnostics.HasError() { return } @@ -337,7 +344,7 @@ func (r *agentActionGroupResource) Update(ctx context.Context, request resource. } } - out, err := findAgentActionGroupByID(ctx, conn, old.ActionGroupId.String(), old.ID.ValueString(), old.AgentVersion.ValueString()) + out, err := findAgentActionGroupByID(ctx, conn, old.ID.ValueString()) if err != nil { response.Diagnostics.AddError( create.ProblemStandardMessage(names.BedrockAgent, create.ErrActionUpdating, "Bedrock Agent", old.AgentId.ValueString(), err), @@ -364,9 +371,10 @@ func (r *agentActionGroupResource) Delete(ctx context.Context, request resource. if !data.ActionGroupId.IsNull() { _, err := conn.DeleteAgentActionGroup(ctx, &bedrockagent.DeleteAgentActionGroupInput{ - AgentId: fwflex.StringFromFramework(ctx, data.AgentId), - ActionGroupId: fwflex.StringFromFramework(ctx, data.ActionGroupId), - AgentVersion: fwflex.StringFromFramework(ctx, data.AgentVersion), + AgentId: fwflex.StringFromFramework(ctx, data.AgentId), + ActionGroupId: fwflex.StringFromFramework(ctx, data.ActionGroupId), + AgentVersion: fwflex.StringFromFramework(ctx, data.AgentVersion), + SkipResourceInUseCheck: data.SkipResourceInUseCheck.ValueBool(), }) if errs.IsA[*awstypes.ResourceNotFoundException](err) { @@ -381,11 +389,21 @@ func (r *agentActionGroupResource) Delete(ctx context.Context, request resource. } } -func findAgentActionGroupByID(ctx context.Context, conn *bedrockagent.Client, grpid, agentid, agentversion string) (*bedrockagent.GetAgentActionGroupOutput, error) { +func findAgentActionGroupByID(ctx context.Context, conn *bedrockagent.Client, id string) (*bedrockagent.GetAgentActionGroupOutput, error) { + parts, err := intflex.ExpandResourceId(id, agentActionGroupIdParts, false) + + if err != nil { + return nil, err + } + + actionGroupId := parts[0] + agentId := parts[1] + agentVersion := parts[2] + input := &bedrockagent.GetAgentActionGroupInput{ - ActionGroupId: aws.String(grpid), - AgentId: aws.String(agentid), - AgentVersion: aws.String(agentversion), + ActionGroupId: aws.String(actionGroupId), + AgentId: aws.String(agentId), + AgentVersion: aws.String(agentVersion), } output, err := conn.GetAgentActionGroup(ctx, input) @@ -416,13 +434,21 @@ type actionGroupResourceModel struct { AgentId types.String `tfsdk:"agent_id"` AgentVersion types.String `tfsdk:"agent_version"` APISchema fwtypes.ListNestedObjectValueOf[apiSchema] `tfsdk:"api_schema"` - ClientToken types.String `tfsdk:"client_token"` - CreatedAt types.String `tfsdk:"created_at"` + CreatedAt timetypes.RFC3339 `tfsdk:"created_at"` Description types.String `tfsdk:"description"` ID types.String `tfsdk:"id"` ParentActionGroupSignature types.String `tfsdk:"parent_action_group_signature"` - PreparedAt types.String `tfsdk:"prepared_at"` - UpdatedAt types.String `tfsdk:"updated_at"` + SkipResourceInUseCheck types.Bool `tfsdk:"skip_resource_in_use_check"` + UpdatedAt timetypes.RFC3339 `tfsdk:"updated_at"` +} + +func (a *actionGroupResourceModel) setId() error { + id, err := intflex.FlattenResourceId([]string{a.ActionGroupId.ValueString(), a.AgentId.ValueString(), a.AgentVersion.ValueString()}, agentActionGroupIdParts, false) + if err != nil { + return err + } + a.ID = types.StringValue(id) + return nil } type actionGroupExecutor struct { @@ -498,21 +524,20 @@ func expandApiSchema(ctx context.Context, api fwtypes.ListNestedObjectValueOf[ap func flattenApiSchema(ctx context.Context, apiObject awstypes.APISchema) (fwtypes.ListNestedObjectValueOf[apiSchema], diag.Diagnostics) { var diags diag.Diagnostics - var apiSchemaData []*apiSchema + apiSchemaData := &apiSchema{ + S3: fwtypes.NewListNestedObjectValueOfNull[s3](ctx), + Payload: types.StringNull(), + } switch v := apiObject.(type) { case *awstypes.APISchemaMemberS3: var s3data s3 diags.Append(fwflex.Flatten(ctx, v, s3data)...) - apiSchemaData = append(apiSchemaData, &apiSchema{S3: fwtypes.NewListNestedObjectValueOfPtrMust(ctx, &s3data)}) + apiSchemaData.S3 = fwtypes.NewListNestedObjectValueOfPtrMust(ctx, &s3data) case *awstypes.APISchemaMemberPayload: payloadValue := fwflex.StringValueToFramework(ctx, v.Value) - apiValue := apiSchema{Payload: payloadValue} - apiSchemaData = append(apiSchemaData, &apiValue) + apiSchemaData.Payload = payloadValue } - apiSchemaDataReturn, moreDiags := fwtypes.NewListNestedObjectValueOfSlice(ctx, apiSchemaData) - diags.Append(moreDiags...) - - return apiSchemaDataReturn, diags + return fwtypes.NewListNestedObjectValueOfPtrMust(ctx, apiSchemaData), diags } diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index d574fbe7660..e0c908163b5 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + bedrockagent2 "github.com/hashicorp/terraform-provider-aws/internal/service/bedrockagent" "testing" "github.com/aws/aws-sdk-go-v2/aws" @@ -25,7 +26,7 @@ import ( func TestAccBedrockAgentActionGroup_basic(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_bedrockagent_action_group.test" + resourceName := "aws_bedrockagent_agent_action_group.test" var v bedrockagent.GetAgentActionGroupOutput resource.ParallelTest(t, resource.TestCase{ @@ -42,9 +43,10 @@ func TestAccBedrockAgentActionGroup_basic(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"skip_resource_in_use_check"}, }, }, }) @@ -87,11 +89,7 @@ func testAccCheckBedrockAgentActionGroupExists(ctx context.Context, n string, v conn := acctest.Provider.Meta().(*conns.AWSClient).BedrockAgentClient(ctx) - output, err := conn.GetAgentActionGroup(ctx, &bedrockagent.GetAgentActionGroupInput{ - ActionGroupId: aws.String(rs.Primary.ID), - AgentId: aws.String(*v.AgentActionGroup.AgentId), - AgentVersion: aws.String(*v.AgentActionGroup.AgentVersion), - }) + output, err := bedrockagent2.FindAgentActionGroupByID(ctx, conn, rs.Primary.ID) if err != nil { return err @@ -104,20 +102,54 @@ func testAccCheckBedrockAgentActionGroupExists(ctx context.Context, n string, v } func testAccBedrockAgentActionGroupConfig_basic(rName string) string { - return acctest.ConfigCompose(testAccAgentConfig_basic(rName, "anthropic.claude-v2", "basic claude"), fmt.Sprintf(` -resource "aws_bedrockagent_action_group" "test" { + return acctest.ConfigCompose(testAccAgentConfig_basic(rName, "anthropic.claude-v2", "basic claude"), + testAccBedrockAgentActionGroupConfig_lamba(rName), + fmt.Sprintf(` +resource "aws_bedrockagent_agent_action_group" "test" { action_group_name = %[1]q agent_id = aws_bedrockagent_agent.test.agent_id agent_version = "DRAFT" + skip_resource_in_use_check = true action_group_executor { - lambda = "arn:aws:lambda:us-west-2:xxxxxxxxxxxx:function:sairam:1" + lambda = aws_lambda_function.test_lambda.arn } api_schema { - s3 { - s3_bucket_name = "tf-acc-test-3678246384762388142" - s3_object_key = "sai.yaml" - } + payload = file("${path.module}/test-fixtures/api_schema.yaml") } } `, rName)) } + +func testAccBedrockAgentActionGroupConfig_lamba(rName string) string { + return fmt.Sprintf(` +data "aws_iam_policy_document" "lambda_assume" { + statement { + effect = "Allow" + + principals { + type = "Service" + identifiers = ["lambda.amazonaws.com"] + } + + actions = ["sts:AssumeRole"] + } +} + +resource "aws_iam_role" "lambda" { + name_prefix = %[1]q + assume_role_policy = data.aws_iam_policy_document.lambda_assume.json +} + +resource "aws_lambda_function" "test_lambda" { + filename = "${path.module}/test-fixtures/lambda_function.zip" + function_name = %[1]q + role = aws_iam_role.lambda.arn + handler = "lambda_handler" + + source_code_hash = filebase64sha256("${path.module}/test-fixtures/lambda_function.zip") + + runtime = "python3.9" +} + +`, rName) +} diff --git a/internal/service/bedrockagent/export_tests.go b/internal/service/bedrockagent/export_tests.go index 4ccfed4e7c2..c417fd76cfc 100644 --- a/internal/service/bedrockagent/export_tests.go +++ b/internal/service/bedrockagent/export_tests.go @@ -4,6 +4,7 @@ package bedrockagent var ( - ResourceAgentAlias = newAgentAliasResource - FindAgentAliasByID = findAgentAliasByID + ResourceAgentAlias = newAgentAliasResource + FindAgentAliasByID = findAgentAliasByID + FindAgentActionGroupByID = findAgentActionGroupByID ) diff --git a/internal/service/bedrockagent/test-fixtures/api_schema.yaml b/internal/service/bedrockagent/test-fixtures/api_schema.yaml new file mode 100644 index 00000000000..a24647f2e5c --- /dev/null +++ b/internal/service/bedrockagent/test-fixtures/api_schema.yaml @@ -0,0 +1,23 @@ +openapi: 3.0.0 +info: + title: Hello Agent API + version: 1.0.0 + description: Says Hello +paths: + /hello: + get: + summary: Gets a Hello + description: Says Hello + operationId: sayHello + responses: + '200': + description: Hello + content: + 'application/json': + schema: + type: object + properties: + message: + type: string + description: The Hello message + diff --git a/internal/service/bedrockagent/test-fixtures/lambda_function.py b/internal/service/bedrockagent/test-fixtures/lambda_function.py new file mode 100644 index 00000000000..9dd603f60bd --- /dev/null +++ b/internal/service/bedrockagent/test-fixtures/lambda_function.py @@ -0,0 +1,24 @@ +import json + +def lambda_handler(event, context): + response = {"message": "Hello"} + + response_body = {"application/json": {"body": json.dumps(response)}} + + action_response = { + "actionGroup": event["actionGroup"], + "apiPath": event["apiPath"], + "httpMethod": event["httpMethod"], + "httpStatusCode": 200, + "response": response_body, + } + + session_attributes = event["sessionAttributes"] + prompt_session_attributes = event["promptSessionAttributes"] + + return { + "messageVersion": "1.0", + "response" : action_response, + "sessionAttributes": session_attributes, + "promptSessionAttributes": prompt_session_attributes, + } \ No newline at end of file diff --git a/internal/service/bedrockagent/test-fixtures/lambda_function.zip b/internal/service/bedrockagent/test-fixtures/lambda_function.zip new file mode 100644 index 0000000000000000000000000000000000000000..ada892b198ca8961594dfbe76be3b8654e288225 GIT binary patch literal 467 zcmWIWW@Zs#U|`^2;3=OFu{vjZtRy1?!yYCE1|bF+hMdIQq?E+?w9>rflFa-(y@JZn z5Kac>j%K;EE+8(g;AUWC`2o}bHlsFhW7c5P#Nl}_-7V^KG!dWmhlvWj(gga3ss zNupUz`cYjyKhqCNUg5i8YyE+5&gAz8SRbFiue*`y)U`lf^+)u8=hf~K}&+$t14<(=IeYrwq5dC?Oc)Xt6OqrtzBZJc+AOb zRp%MD6>eXTduKhrBJ26;uJS5@gR%3}KV&BJ`&^RHyg2vsPuA*5C(Kg)AM813VV1(|^ Date: Tue, 16 Apr 2024 21:31:03 +0100 Subject: [PATCH 07/28] Add test for s3 schema --- .../bedrockagent/agent_action_group_test.go | 70 ++++++++++++++++++- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index e0c908163b5..0433d6e8055 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -52,6 +52,35 @@ func TestAccBedrockAgentActionGroup_basic(t *testing.T) { }) } +func TestAccBedrockAgentActionGroup_s3ApiSchema(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_bedrockagent_agent_action_group.test" + var v bedrockagent.GetAgentActionGroupOutput + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) }, + ErrorCheck: acctest.ErrorCheck(t, names.BedrockAgentServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckBedrockAgentActionGroupDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccBedrockAgentActionGroupConfig_basic(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckBedrockAgentActionGroupExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "action_group_name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"skip_resource_in_use_check"}, + }, + }, + }) +} + func testAccCheckBedrockAgentActionGroupDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).BedrockAgentClient(ctx) @@ -106,9 +135,9 @@ func testAccBedrockAgentActionGroupConfig_basic(rName string) string { testAccBedrockAgentActionGroupConfig_lamba(rName), fmt.Sprintf(` resource "aws_bedrockagent_agent_action_group" "test" { - action_group_name = %[1]q - agent_id = aws_bedrockagent_agent.test.agent_id - agent_version = "DRAFT" + action_group_name = %[1]q + agent_id = aws_bedrockagent_agent.test.agent_id + agent_version = "DRAFT" skip_resource_in_use_check = true action_group_executor { lambda = aws_lambda_function.test_lambda.arn @@ -120,6 +149,41 @@ resource "aws_bedrockagent_agent_action_group" "test" { `, rName)) } +func testAccBedrockAgentActionGroupConfig_s3ApiSchema(rName string) string { + return acctest.ConfigCompose(testAccAgentConfig_basic(rName, "anthropic.claude-v2", "basic claude"), + testAccBedrockAgentActionGroupConfig_lamba(rName), + fmt.Sprintf(` +resource "aws_s3_bucket" "test" { + bucket = %[1]q +} + +resource "aws_s3_object" "test" { + bucket = aws_s3_bucket.test.id + key = "api_schema.yaml" + source = "${path.module}/test-fixtures/api_schema.yaml" +} + +resource "aws_bedrockagent_agent_action_group" "test" { + action_group_name = %[1]q + agent_id = aws_bedrockagent_agent.test.agent_id + agent_version = "DRAFT" + skip_resource_in_use_check = true + action_group_executor { + lambda = aws_lambda_function.test_lambda.arn + } + api_schema { + s3 { + s3_bucket_name = aws_s3_bucket.test.id + s3_object_key = aws_s3_object.test.key + } + } + depends_on = [aws_s3_object.test] +} + + +`, rName)) +} + func testAccBedrockAgentActionGroupConfig_lamba(rName string) string { return fmt.Sprintf(` data "aws_iam_policy_document" "lambda_assume" { From 31ea5a6e8c2f21e5e57ee78d5f60f6e52db1d099 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Tue, 16 Apr 2024 22:28:18 +0100 Subject: [PATCH 08/28] Update agent role permissions for S3 API Schema, fix flex issues in S3 expand/flatten --- .../bedrockagent/agent_action_group.go | 39 ++++++++++++------- .../bedrockagent/agent_action_group_test.go | 3 +- internal/service/bedrockagent/agent_test.go | 11 ++++++ .../test-fixtures/api_schema.yaml | 2 +- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/internal/service/bedrockagent/agent_action_group.go b/internal/service/bedrockagent/agent_action_group.go index 6ecc70d3eb0..f67b2e27367 100644 --- a/internal/service/bedrockagent/agent_action_group.go +++ b/internal/service/bedrockagent/agent_action_group.go @@ -501,25 +501,36 @@ func flattenActionGroupExecutor(ctx context.Context, age awstypes.ActionGroupExe func expandApiSchema(ctx context.Context, api fwtypes.ListNestedObjectValueOf[apiSchema]) (awstypes.APISchema, diag.Diagnostics) { var diags diag.Diagnostics - var apiObject awstypes.APISchema - planApi, moreDiags := api.ToPtr(ctx) - diags.Append(moreDiags...) + planApi, d := api.ToPtr(ctx) + diags.Append(d...) if diags.HasError() { - return apiObject, diags + return nil, diags } if !planApi.S3.IsNull() { - var s3 awstypes.APISchemaMemberS3 - diags.Append(fwflex.Expand(ctx, planApi.S3, &s3.Value)...) - apiObject = &s3 + planS3Api, d := planApi.S3.ToPtr(ctx) + diags.Append(d...) + if diags.HasError() { + return nil, diags + } + + apiObject := &awstypes.APISchemaMemberS3{} + diags.Append(fwflex.Expand(ctx, planS3Api, &apiObject.Value)...) + if diags.HasError() { + return nil, diags + } + return apiObject, diags } if !planApi.Payload.IsNull() { - var payload awstypes.APISchemaMemberPayload - diags.Append(fwflex.Expand(ctx, planApi.Payload, &payload.Value)...) - apiObject = &payload + apiObject := &awstypes.APISchemaMemberPayload{} + diags.Append(fwflex.Expand(ctx, planApi.Payload, &apiObject.Value)...) + if diags.HasError() { + return nil, diags + } + return apiObject, diags } - return apiObject, diags + return nil, diags } func flattenApiSchema(ctx context.Context, apiObject awstypes.APISchema) (fwtypes.ListNestedObjectValueOf[apiSchema], diag.Diagnostics) { @@ -531,9 +542,9 @@ func flattenApiSchema(ctx context.Context, apiObject awstypes.APISchema) (fwtype switch v := apiObject.(type) { case *awstypes.APISchemaMemberS3: - var s3data s3 - diags.Append(fwflex.Flatten(ctx, v, s3data)...) - apiSchemaData.S3 = fwtypes.NewListNestedObjectValueOfPtrMust(ctx, &s3data) + s3data := &s3{} + diags.Append(fwflex.Flatten(ctx, v.Value, s3data)...) + apiSchemaData.S3 = fwtypes.NewListNestedObjectValueOfPtrMust(ctx, s3data) case *awstypes.APISchemaMemberPayload: payloadValue := fwflex.StringValueToFramework(ctx, v.Value) apiSchemaData.Payload = payloadValue diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index 0433d6e8055..d6f25489cc2 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -65,7 +65,7 @@ func TestAccBedrockAgentActionGroup_s3ApiSchema(t *testing.T) { CheckDestroy: testAccCheckBedrockAgentActionGroupDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccBedrockAgentActionGroupConfig_basic(rName), + Config: testAccBedrockAgentActionGroupConfig_s3ApiSchema(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckBedrockAgentActionGroupExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "action_group_name", rName), @@ -138,6 +138,7 @@ resource "aws_bedrockagent_agent_action_group" "test" { action_group_name = %[1]q agent_id = aws_bedrockagent_agent.test.agent_id agent_version = "DRAFT" + description = "Basic Agent Action" skip_resource_in_use_check = true action_group_executor { lambda = aws_lambda_function.test_lambda.arn diff --git a/internal/service/bedrockagent/agent_test.go b/internal/service/bedrockagent/agent_test.go index 1686cb445f7..6b6636787ea 100644 --- a/internal/service/bedrockagent/agent_test.go +++ b/internal/service/bedrockagent/agent_test.go @@ -424,6 +424,17 @@ resource "aws_iam_role_policy" "test" { role = aws_iam_role.test.id } +resource "aws_iam_role_policy_attachment" "test_s3" { + role = aws_iam_role.test.id + policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess" +} + +resource "aws_iam_role_policy_attachment" "test_lambda" { + role = aws_iam_role.test.id + policy_arn = "arn:aws:iam::aws:policy/AWSLambda_FullAccess" +} + + data "aws_caller_identity" "current" {} data "aws_region" "current" {} diff --git a/internal/service/bedrockagent/test-fixtures/api_schema.yaml b/internal/service/bedrockagent/test-fixtures/api_schema.yaml index a24647f2e5c..ef4d305c739 100644 --- a/internal/service/bedrockagent/test-fixtures/api_schema.yaml +++ b/internal/service/bedrockagent/test-fixtures/api_schema.yaml @@ -11,7 +11,7 @@ paths: operationId: sayHello responses: '200': - description: Hello + description: Hello Response content: 'application/json': schema: From 49aa4c49b1b68314b983fd17a2eee00bab647ca3 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Tue, 16 Apr 2024 22:29:00 +0100 Subject: [PATCH 09/28] Sort whitespace --- internal/service/bedrockagent/test-fixtures/api_schema.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/service/bedrockagent/test-fixtures/api_schema.yaml b/internal/service/bedrockagent/test-fixtures/api_schema.yaml index ef4d305c739..72765cd6730 100644 --- a/internal/service/bedrockagent/test-fixtures/api_schema.yaml +++ b/internal/service/bedrockagent/test-fixtures/api_schema.yaml @@ -19,5 +19,4 @@ paths: properties: message: type: string - description: The Hello message - + description: The Hello message \ No newline at end of file From ef9ff6ad19528dc6eb75e69ea3626035bf66a41e Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Tue, 16 Apr 2024 22:32:52 +0100 Subject: [PATCH 10/28] Add copyright to these test files --- internal/service/bedrockagent/test-fixtures/api_schema.yaml | 3 +++ internal/service/bedrockagent/test-fixtures/lambda_function.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/internal/service/bedrockagent/test-fixtures/api_schema.yaml b/internal/service/bedrockagent/test-fixtures/api_schema.yaml index 72765cd6730..dd4b8b24deb 100644 --- a/internal/service/bedrockagent/test-fixtures/api_schema.yaml +++ b/internal/service/bedrockagent/test-fixtures/api_schema.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + openapi: 3.0.0 info: title: Hello Agent API diff --git a/internal/service/bedrockagent/test-fixtures/lambda_function.py b/internal/service/bedrockagent/test-fixtures/lambda_function.py index 9dd603f60bd..c1e83953b69 100644 --- a/internal/service/bedrockagent/test-fixtures/lambda_function.py +++ b/internal/service/bedrockagent/test-fixtures/lambda_function.py @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + import json def lambda_handler(event, context): From 51c482ef880733f36e6e7f2ef41cbc308da5c6f5 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Tue, 16 Apr 2024 22:33:12 +0100 Subject: [PATCH 11/28] Fix function names --- .../bedrockagent/agent_action_group_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index d6f25489cc2..539d930e18c 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -36,7 +36,7 @@ func TestAccBedrockAgentActionGroup_basic(t *testing.T) { CheckDestroy: testAccCheckBedrockAgentActionGroupDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccBedrockAgentActionGroupConfig_basic(rName), + Config: testAccAgentActionGroupConfig_basic(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckBedrockAgentActionGroupExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "action_group_name", rName), @@ -65,7 +65,7 @@ func TestAccBedrockAgentActionGroup_s3ApiSchema(t *testing.T) { CheckDestroy: testAccCheckBedrockAgentActionGroupDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccBedrockAgentActionGroupConfig_s3ApiSchema(rName), + Config: testAccAgentActionGroupConfig_s3ApiSchema(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckBedrockAgentActionGroupExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "action_group_name", rName), @@ -130,9 +130,9 @@ func testAccCheckBedrockAgentActionGroupExists(ctx context.Context, n string, v } } -func testAccBedrockAgentActionGroupConfig_basic(rName string) string { +func testAccAgentActionGroupConfig_basic(rName string) string { return acctest.ConfigCompose(testAccAgentConfig_basic(rName, "anthropic.claude-v2", "basic claude"), - testAccBedrockAgentActionGroupConfig_lamba(rName), + testAccAgentActionGroupConfig_lamba(rName), fmt.Sprintf(` resource "aws_bedrockagent_agent_action_group" "test" { action_group_name = %[1]q @@ -150,9 +150,9 @@ resource "aws_bedrockagent_agent_action_group" "test" { `, rName)) } -func testAccBedrockAgentActionGroupConfig_s3ApiSchema(rName string) string { +func testAccAgentActionGroupConfig_s3ApiSchema(rName string) string { return acctest.ConfigCompose(testAccAgentConfig_basic(rName, "anthropic.claude-v2", "basic claude"), - testAccBedrockAgentActionGroupConfig_lamba(rName), + testAccAgentActionGroupConfig_lamba(rName), fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -185,7 +185,7 @@ resource "aws_bedrockagent_agent_action_group" "test" { `, rName)) } -func testAccBedrockAgentActionGroupConfig_lamba(rName string) string { +func testAccAgentActionGroupConfig_lamba(rName string) string { return fmt.Sprintf(` data "aws_iam_policy_document" "lambda_assume" { statement { From 85a3af5b71060e9f9708f892a49150519db0e284 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Tue, 16 Apr 2024 22:37:09 +0100 Subject: [PATCH 12/28] More lint checks --- .../service/bedrockagent/agent_action_group.go | 18 +++++++++--------- .../bedrockagent/agent_action_group_test.go | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/internal/service/bedrockagent/agent_action_group.go b/internal/service/bedrockagent/agent_action_group.go index f67b2e27367..954a62e3e8e 100644 --- a/internal/service/bedrockagent/agent_action_group.go +++ b/internal/service/bedrockagent/agent_action_group.go @@ -6,20 +6,19 @@ package bedrockagent import ( "context" "fmt" - "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - intflex "github.com/hashicorp/terraform-provider-aws/internal/flex" "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/bedrockagent" awstypes "github.com/aws/aws-sdk-go-v2/service/bedrockagent/types" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" @@ -29,6 +28,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" + intflex "github.com/hashicorp/terraform-provider-aws/internal/flex" "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" @@ -203,7 +203,7 @@ func (r *agentActionGroupResource) Create(ctx context.Context, request resource. var input bedrockagent.CreateAgentActionGroupInput response.Diagnostics.Append(fwflex.Expand(ctx, data, &input)...) - apiSchemaInput, diags := expandApiSchema(ctx, data.APISchema) + apiSchemaInput, diags := expandAPISchema(ctx, data.APISchema) response.Diagnostics.Append(diags...) if response.Diagnostics.HasError() { @@ -276,7 +276,7 @@ func (r *agentActionGroupResource) Read(ctx context.Context, request resource.Re return } - apiSchemaData, moreDiags := flattenApiSchema(ctx, output.AgentActionGroup.ApiSchema) + apiSchemaData, moreDiags := flattenAPISchema(ctx, output.AgentActionGroup.ApiSchema) response.Diagnostics.Append(moreDiags...) if response.Diagnostics.HasError() { return @@ -315,7 +315,7 @@ func (r *agentActionGroupResource) Update(ctx context.Context, request resource. return } - apiConfig, diags := expandApiSchema(ctx, new.APISchema) + apiConfig, diags := expandAPISchema(ctx, new.APISchema) response.Diagnostics.Append(diags...) if response.Diagnostics.HasError() { @@ -499,7 +499,7 @@ func flattenActionGroupExecutor(ctx context.Context, age awstypes.ActionGroupExe return fwtypes.NewListNestedObjectValueOfPtr(ctx, &ageData) } -func expandApiSchema(ctx context.Context, api fwtypes.ListNestedObjectValueOf[apiSchema]) (awstypes.APISchema, diag.Diagnostics) { +func expandAPISchema(ctx context.Context, api fwtypes.ListNestedObjectValueOf[apiSchema]) (awstypes.APISchema, diag.Diagnostics) { var diags diag.Diagnostics planApi, d := api.ToPtr(ctx) diags.Append(d...) @@ -533,7 +533,7 @@ func expandApiSchema(ctx context.Context, api fwtypes.ListNestedObjectValueOf[ap return nil, diags } -func flattenApiSchema(ctx context.Context, apiObject awstypes.APISchema) (fwtypes.ListNestedObjectValueOf[apiSchema], diag.Diagnostics) { +func flattenAPISchema(ctx context.Context, apiObject awstypes.APISchema) (fwtypes.ListNestedObjectValueOf[apiSchema], diag.Diagnostics) { var diags diag.Diagnostics apiSchemaData := &apiSchema{ S3: fwtypes.NewListNestedObjectValueOfNull[s3](ctx), diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index 539d930e18c..d9de11daac2 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -7,7 +7,6 @@ import ( "context" "errors" "fmt" - bedrockagent2 "github.com/hashicorp/terraform-provider-aws/internal/service/bedrockagent" "testing" "github.com/aws/aws-sdk-go-v2/aws" @@ -20,6 +19,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/errs" + tfagent "github.com/hashicorp/terraform-provider-aws/internal/service/bedrockagent" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -65,7 +65,7 @@ func TestAccBedrockAgentActionGroup_s3ApiSchema(t *testing.T) { CheckDestroy: testAccCheckBedrockAgentActionGroupDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccAgentActionGroupConfig_s3ApiSchema(rName), + Config: testAccAgentActionGroupConfig_s3APISchema(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckBedrockAgentActionGroupExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "action_group_name", rName), @@ -118,7 +118,7 @@ func testAccCheckBedrockAgentActionGroupExists(ctx context.Context, n string, v conn := acctest.Provider.Meta().(*conns.AWSClient).BedrockAgentClient(ctx) - output, err := bedrockagent2.FindAgentActionGroupByID(ctx, conn, rs.Primary.ID) + output, err := tfagent.FindAgentActionGroupByID(ctx, conn, rs.Primary.ID) if err != nil { return err @@ -150,7 +150,7 @@ resource "aws_bedrockagent_agent_action_group" "test" { `, rName)) } -func testAccAgentActionGroupConfig_s3ApiSchema(rName string) string { +func testAccAgentActionGroupConfig_s3APISchema(rName string) string { return acctest.ConfigCompose(testAccAgentConfig_basic(rName, "anthropic.claude-v2", "basic claude"), testAccAgentActionGroupConfig_lamba(rName), fmt.Sprintf(` From 25d6e4c0a095b4ec404f396c9ed8cd4a6112dc7d Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:22:10 +0100 Subject: [PATCH 13/28] Fix static partition --- internal/service/bedrockagent/agent_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/bedrockagent/agent_test.go b/internal/service/bedrockagent/agent_test.go index 6b6636787ea..e598c092ebd 100644 --- a/internal/service/bedrockagent/agent_test.go +++ b/internal/service/bedrockagent/agent_test.go @@ -426,12 +426,12 @@ resource "aws_iam_role_policy" "test" { resource "aws_iam_role_policy_attachment" "test_s3" { role = aws_iam_role.test.id - policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess" + policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/AmazonS3FullAccess" } resource "aws_iam_role_policy_attachment" "test_lambda" { role = aws_iam_role.test.id - policy_arn = "arn:aws:iam::aws:policy/AWSLambda_FullAccess" + policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/AWSLambda_FullAccess" } From 94405c1c0554876c94428a533a273d7abed64137 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:22:40 +0100 Subject: [PATCH 14/28] Function name --- internal/service/bedrockagent/agent_action_group_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index d9de11daac2..2721b29ea7f 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -52,7 +52,7 @@ func TestAccBedrockAgentActionGroup_basic(t *testing.T) { }) } -func TestAccBedrockAgentActionGroup_s3ApiSchema(t *testing.T) { +func TestAccBedrockAgentActionGroup_s3APISchema(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_bedrockagent_agent_action_group.test" From 2a7f66ccafc151f3ce0ad38c465d7ff2b6e2e9e8 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:23:05 +0100 Subject: [PATCH 15/28] Missing newline --- internal/service/bedrockagent/test-fixtures/api_schema.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/bedrockagent/test-fixtures/api_schema.yaml b/internal/service/bedrockagent/test-fixtures/api_schema.yaml index dd4b8b24deb..8941aa51d24 100644 --- a/internal/service/bedrockagent/test-fixtures/api_schema.yaml +++ b/internal/service/bedrockagent/test-fixtures/api_schema.yaml @@ -22,4 +22,4 @@ paths: properties: message: type: string - description: The Hello message \ No newline at end of file + description: The Hello message From 1715b768054baa30d8c91fa113358378dcd3e910 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:24:08 +0100 Subject: [PATCH 16/28] Function names lint --- .../service/bedrockagent/agent_action_group_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index 2721b29ea7f..2181c3c3f58 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -33,12 +33,12 @@ func TestAccBedrockAgentActionGroup_basic(t *testing.T) { PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) }, ErrorCheck: acctest.ErrorCheck(t, names.BedrockAgentServiceID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - CheckDestroy: testAccCheckBedrockAgentActionGroupDestroy(ctx), + CheckDestroy: testAccCheckAgentActionGroupDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccAgentActionGroupConfig_basic(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckBedrockAgentActionGroupExists(ctx, resourceName, &v), + testAccCheckAgentActionGroupExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "action_group_name", rName), ), }, @@ -62,12 +62,12 @@ func TestAccBedrockAgentActionGroup_s3APISchema(t *testing.T) { PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) }, ErrorCheck: acctest.ErrorCheck(t, names.BedrockAgentServiceID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - CheckDestroy: testAccCheckBedrockAgentActionGroupDestroy(ctx), + CheckDestroy: testAccCheckAgentActionGroupDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccAgentActionGroupConfig_s3APISchema(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckBedrockAgentActionGroupExists(ctx, resourceName, &v), + testAccCheckAgentActionGroupExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "action_group_name", rName), ), }, @@ -81,7 +81,7 @@ func TestAccBedrockAgentActionGroup_s3APISchema(t *testing.T) { }) } -func testAccCheckBedrockAgentActionGroupDestroy(ctx context.Context) resource.TestCheckFunc { +func testAccCheckAgentActionGroupDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).BedrockAgentClient(ctx) @@ -109,7 +109,7 @@ func testAccCheckBedrockAgentActionGroupDestroy(ctx context.Context) resource.Te return nil } } -func testAccCheckBedrockAgentActionGroupExists(ctx context.Context, n string, v *bedrockagent.GetAgentActionGroupOutput) resource.TestCheckFunc { +func testAccCheckAgentActionGroupExists(ctx context.Context, n string, v *bedrockagent.GetAgentActionGroupOutput) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { From 545a2c8e02f806eb69636964b5c3534234c76f72 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:40:09 +0100 Subject: [PATCH 17/28] First pass on docs --- ...rockagent_agent_action_group.html.markdown | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 website/docs/r/bedrockagent_agent_action_group.html.markdown diff --git a/website/docs/r/bedrockagent_agent_action_group.html.markdown b/website/docs/r/bedrockagent_agent_action_group.html.markdown new file mode 100644 index 00000000000..bf8ae9f634c --- /dev/null +++ b/website/docs/r/bedrockagent_agent_action_group.html.markdown @@ -0,0 +1,109 @@ +--- +subcategory: "Agents for Amazon Bedrock" +layout: "aws" +page_title: "AWS: aws_bedrockagent_agent_action_group" +description: |- + Terraform resource for managing an AWS Agents for Amazon Bedrock Agent Action Group. +--- +# Resource: aws_bedrockagent_agent_action_group + +Terraform resource for managing an AWS Agents for Amazon Bedrock Agent Action Group. + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_bedrockagent_agent_action_group" "example" { + action_group_name = "example" + agent_id = "ABDJFOWER1" + agent_version = "DRAFT" + skip_resource_in_use_check = true + action_group_executor { + lambda = "arn:aws:lambda:us-east-1:123456789012:function:example-function" + } + api_schema { + s3 { + s3_bucket_name = "example-bucket" + s3_object_key = "path/to/schema.json" + } + } + depends_on = [aws_s3_object.test] +} + +``` + +## Argument Reference + +The following arguments are required: + +* `action_group_name` - (Required) Name of the Agent Action Group. +* `agent_id` - (Required) Id of the Agent for the Action Group. +* `agent_version` - (Required) Version of the Agent to attach the Action Group to. +* `action_group_executor` - (Required) Configuration of the executor for the Action Group. +* `api_schema` - (Required) Configuration of the API Schema for the Action Group. + +### action_group_executor + +This argument is processed in [attribute-as-blocks mode](https://www.terraform.io/docs/configuration/attr-as-blocks.html). + +The following arguments are required: + +* `lambda` - (Required) ARN of the Lambda that defines the business logic for the action group. + +### api_schema + +This argument is processed in [attribute-as-blocks mode](https://www.terraform.io/docs/configuration/attr-as-blocks.html). + +The following arguments are optional: + +* `payload` - (Optional) YAML or JSON OpenAPI Schema. +* `s3` - (Optional) Configuration of S3 schema location + +### s3 + +This argument is processed in [attribute-as-blocks mode](https://www.terraform.io/docs/configuration/attr-as-blocks.html). + +The following arguments are optional: + +* `s3_bucket_name` - (Required) The S3 bucket name that contains the OpenAPI Schema. +* `s3_object_key` - (Required) The S3 Object Key for the OpenAPI Schema in the S3 Bucket. + +The following arguments are optional: + +* `action_group_state` - (Optional) `ENABLED` or `DISABLED` +* `description` - (Optional) Description of the Agent Action Group. +* `skip_resource_in_use_check` - (Optional) Set to true to skip the in-use check when deleting. + + +## Attribute Reference + +This resource exports the following attributes in addition to the arguments above: + +* `created_at` - Timestamp the Agent Action Group was created at. +* `updated_at` - Timestamp the Agent Action Group was updated at. + +## Timeouts + +[Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): + +* `create` - (Default `5m`) +* `update` - (Default `5m`) +* `delete` - (Default `5m`) + +## Import + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import Agents for Amazon Bedrock Agent Action Group using the `ABDJFOWER1,HSKTNKANI4,DRAFT`. For example: + +```terraform +import { + to = aws_bedrockagent_agent_action_group.example + id = "ABDJFOWER1,HSKTNKANI4,DRAFT" +} +``` + +Using `terraform import`, import Agents for Amazon Bedrock Agent Action Group using the `example_id_arg`. For example: + +```console +% terraform import aws_bedrockagent_agent_action_group.example ABDJFOWER1,HSKTNKANI4,DRAFT +``` From 55ef3da8a48b4d895db025ab27036fb1663dd9ab Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:40:40 +0100 Subject: [PATCH 18/28] Remove erroneous depends_on --- website/docs/r/bedrockagent_agent_action_group.html.markdown | 1 - 1 file changed, 1 deletion(-) diff --git a/website/docs/r/bedrockagent_agent_action_group.html.markdown b/website/docs/r/bedrockagent_agent_action_group.html.markdown index bf8ae9f634c..761647c4208 100644 --- a/website/docs/r/bedrockagent_agent_action_group.html.markdown +++ b/website/docs/r/bedrockagent_agent_action_group.html.markdown @@ -28,7 +28,6 @@ resource "aws_bedrockagent_agent_action_group" "example" { s3_object_key = "path/to/schema.json" } } - depends_on = [aws_s3_object.test] } ``` From 5f24d8b9b5e5e4a81df8f1eece9be4b3ae0f1d88 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:43:43 +0100 Subject: [PATCH 19/28] Remove some requires replace since the docs indicate it's not required --- internal/service/bedrockagent/agent_action_group.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/internal/service/bedrockagent/agent_action_group.go b/internal/service/bedrockagent/agent_action_group.go index 954a62e3e8e..7501e5019b4 100644 --- a/internal/service/bedrockagent/agent_action_group.go +++ b/internal/service/bedrockagent/agent_action_group.go @@ -19,7 +19,6 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -119,9 +118,6 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. Blocks: map[string]schema.Block{ "action_group_executor": schema.ListNestedBlock{ CustomType: fwtypes.NewListNestedObjectTypeOf[actionGroupExecutor](ctx), - PlanModifiers: []planmodifier.List{ - listplanmodifier.RequiresReplace(), - }, Validators: []validator.List{ listvalidator.SizeAtMost(1), }, @@ -129,18 +125,12 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. Attributes: map[string]schema.Attribute{ "lambda": schema.StringAttribute{ Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), - }, }, }, }, }, "api_schema": schema.ListNestedBlock{ CustomType: fwtypes.NewListNestedObjectTypeOf[apiSchema](ctx), - PlanModifiers: []planmodifier.List{ - listplanmodifier.RequiresReplace(), - }, Validators: []validator.List{ listvalidator.SizeAtMost(1), }, From 4b5bfb701f1b52e07f130deccbb3d8b7e2671fcd Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:51:16 +0100 Subject: [PATCH 20/28] Linting --- website/docs/r/bedrockagent_agent_action_group.html.markdown | 1 - 1 file changed, 1 deletion(-) diff --git a/website/docs/r/bedrockagent_agent_action_group.html.markdown b/website/docs/r/bedrockagent_agent_action_group.html.markdown index 761647c4208..24b56c31d2b 100644 --- a/website/docs/r/bedrockagent_agent_action_group.html.markdown +++ b/website/docs/r/bedrockagent_agent_action_group.html.markdown @@ -74,7 +74,6 @@ The following arguments are optional: * `description` - (Optional) Description of the Agent Action Group. * `skip_resource_in_use_check` - (Optional) Set to true to skip the in-use check when deleting. - ## Attribute Reference This resource exports the following attributes in addition to the arguments above: From 9ac7abf61ee0f406c9a9c7cef139a1ffc6777885 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:52:05 +0100 Subject: [PATCH 21/28] Add update test --- .../bedrockagent/agent_action_group_test.go | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index 2181c3c3f58..29b2189c714 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -81,6 +81,49 @@ func TestAccBedrockAgentActionGroup_s3APISchema(t *testing.T) { }) } +func TestAccBedrockAgentActionGroup_update(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_bedrockagent_agent_action_group.test" + var v bedrockagent.GetAgentActionGroupOutput + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) }, + ErrorCheck: acctest.ErrorCheck(t, names.BedrockAgentServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckAgentActionGroupDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccAgentActionGroupConfig_s3APISchema(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAgentActionGroupExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "action_group_name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"skip_resource_in_use_check"}, + }, + { + Config: testAccAgentActionGroupConfig_basic(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAgentActionGroupExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "action_group_name", rName), + resource.TestCheckResourceAttr(resourceName, "description", "Basic Agent Action"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"skip_resource_in_use_check"}, + }, + }, + }) +} + func testAccCheckAgentActionGroupDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).BedrockAgentClient(ctx) From 457d810d677028ce818608210988819924ef61ff Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:53:18 +0100 Subject: [PATCH 22/28] Add changelog --- .changelog/36935.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/36935.txt diff --git a/.changelog/36935.txt b/.changelog/36935.txt new file mode 100644 index 00000000000..f9ba640efaf --- /dev/null +++ b/.changelog/36935.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_bedrockagent_agent_action_group +``` From 58dccd10d8b6c7a95b87966f4fee0d8a3aa46491 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Wed, 17 Apr 2024 09:55:16 +0100 Subject: [PATCH 23/28] Update zip to include lamba with copyright --- .../test-fixtures/lambda_function.zip | Bin 467 -> 519 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/internal/service/bedrockagent/test-fixtures/lambda_function.zip b/internal/service/bedrockagent/test-fixtures/lambda_function.zip index ada892b198ca8961594dfbe76be3b8654e288225..c07d3bc7b5dbf6ab19661e8f186835bb05f63db2 100644 GIT binary patch delta 436 zcmcc2+|D8q;LXe;!oa}5!SHyUv+?fdYSABz^mK2J{MKYUO`ge8%uZOV<9T({XRPs)6b)W-)s7Bi2XcdPo` z&hPVzt5X(zxz`cfx+I?O#FU#}K2t6_8%<7~_2op?&o5T9x`mdsUhHXh*(jP&v?=18 z`(qPtp^NnysT1}@t4?k?JnhPwn+0JZKA)s~q%>?G$ z15w+UX9-)i?h5-dBW6NZ@1x&+C%3F~JsF@;`JCPAWMkEp+8_U?Z13IncXL4j&)kTY zs;)L$SO0eRf3P`lZCUQF())T{uM=IaC7s;R)v-`uvX;wUhWa%k{~x+;y?;g2DCez9 zq5MIM(@H<~Y-HBEWD(e8{rc1AZxV|HXNw)QYEH~KAh%y}*E^G2E8LPl&i~>P8Jj7v zu6gam!U+%i^b__Rn*Z7E>t delta 383 zcmZo?xy&pP;LXe;!oa}5!N5~KA!2pT^jJwo28KOM6D4HpJDTOvx`4Q}f}4SnP#Nl}_-7V^KG!dWmhlvWj(gga3ssNupUz`cYjyKhqCNUg5i8YyE+5 z&gAz8SRbFSzp(8@|IL<=DJ%A|FEd$|tL4f2YPP`zZ$6s^|CIl%54|tB-GX!a@f)6D zjzLR;+p8*SSmx_|JGNc&TJ2ns@2gvKX02UfrFhKAYgOkNwiRw)k9%i5zas1T>aOxC zfrGL0)IVe<^ZQ(q(7ZVJ^H0|5Nhi!w{U7W(XknJbzhB@!zf`i%M&po}$$eAq`ZQO_ zzFOgOA<4i10D^m?vj6}9 From 55ca976f1ce24279c530de054ccbd05e226b1e8b Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Fri, 19 Apr 2024 10:04:39 +0100 Subject: [PATCH 24/28] Tidy up to match changes from @ewbankkit in other PRs --- .../bedrockagent/agent_action_group.go | 23 +++++-------------- .../bedrockagent/agent_action_group_test.go | 9 ++++---- ...rockagent_agent_action_group.html.markdown | 7 ------ 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/internal/service/bedrockagent/agent_action_group.go b/internal/service/bedrockagent/agent_action_group.go index 7501e5019b4..d0bbfa0d0a2 100644 --- a/internal/service/bedrockagent/agent_action_group.go +++ b/internal/service/bedrockagent/agent_action_group.go @@ -11,7 +11,6 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/bedrockagent" awstypes "github.com/aws/aws-sdk-go-v2/service/bedrockagent/types" - "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -39,7 +38,7 @@ const ( agentActionGroupIdParts = 3 ) -// @FrameworkResource(name="Bedrock Agent Action Group") +// @FrameworkResource(name="Agent Action Group") func newAgentActionGroupResource(context.Context) (resource.ResourceWithConfigure, error) { r := &agentActionGroupResource{} @@ -88,10 +87,6 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. stringplanmodifier.RequiresReplace(), }, }, - "created_at": schema.StringAttribute{ - CustomType: timetypes.RFC3339Type{}, - Computed: true, - }, "description": schema.StringAttribute{ Optional: true, PlanModifiers: []planmodifier.String{ @@ -110,10 +105,6 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. Default: booldefault.StaticBool(false), Optional: true, }, - "updated_at": schema.StringAttribute{ - CustomType: timetypes.RFC3339Type{}, - Computed: true, - }, }, Blocks: map[string]schema.Block{ "action_group_executor": schema.ListNestedBlock{ @@ -261,12 +252,12 @@ func (r *agentActionGroupResource) Read(ctx context.Context, request resource.Re return } - response.Diagnostics.Append(fwflex.Flatten(ctx, output.AgentActionGroup, &data)...) + response.Diagnostics.Append(fwflex.Flatten(ctx, output, &data)...) if response.Diagnostics.HasError() { return } - apiSchemaData, moreDiags := flattenAPISchema(ctx, output.AgentActionGroup.ApiSchema) + apiSchemaData, moreDiags := flattenAPISchema(ctx, output.ApiSchema) response.Diagnostics.Append(moreDiags...) if response.Diagnostics.HasError() { return @@ -274,7 +265,7 @@ func (r *agentActionGroupResource) Read(ctx context.Context, request resource.Re data.APISchema = apiSchemaData - ageData, moreDiags := flattenActionGroupExecutor(ctx, output.AgentActionGroup.ActionGroupExecutor) + ageData, moreDiags := flattenActionGroupExecutor(ctx, output.ActionGroupExecutor) response.Diagnostics.Append(moreDiags...) if response.Diagnostics.HasError() { return @@ -379,7 +370,7 @@ func (r *agentActionGroupResource) Delete(ctx context.Context, request resource. } } -func findAgentActionGroupByID(ctx context.Context, conn *bedrockagent.Client, id string) (*bedrockagent.GetAgentActionGroupOutput, error) { +func findAgentActionGroupByID(ctx context.Context, conn *bedrockagent.Client, id string) (*awstypes.AgentActionGroup, error) { parts, err := intflex.ExpandResourceId(id, agentActionGroupIdParts, false) if err != nil { @@ -413,7 +404,7 @@ func findAgentActionGroupByID(ctx context.Context, conn *bedrockagent.Client, id return nil, tfresource.NewEmptyResultError(input) } - return output, nil + return output.AgentActionGroup, nil } type actionGroupResourceModel struct { @@ -424,12 +415,10 @@ type actionGroupResourceModel struct { AgentId types.String `tfsdk:"agent_id"` AgentVersion types.String `tfsdk:"agent_version"` APISchema fwtypes.ListNestedObjectValueOf[apiSchema] `tfsdk:"api_schema"` - CreatedAt timetypes.RFC3339 `tfsdk:"created_at"` Description types.String `tfsdk:"description"` ID types.String `tfsdk:"id"` ParentActionGroupSignature types.String `tfsdk:"parent_action_group_signature"` SkipResourceInUseCheck types.Bool `tfsdk:"skip_resource_in_use_check"` - UpdatedAt timetypes.RFC3339 `tfsdk:"updated_at"` } func (a *actionGroupResourceModel) setId() error { diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index 29b2189c714..e502b706b16 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + awstypes "github.com/aws/aws-sdk-go-v2/service/bedrockagent/types" "testing" "github.com/aws/aws-sdk-go-v2/aws" @@ -27,7 +28,7 @@ func TestAccBedrockAgentActionGroup_basic(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_bedrockagent_agent_action_group.test" - var v bedrockagent.GetAgentActionGroupOutput + var v awstypes.AgentActionGroup resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) }, @@ -56,7 +57,7 @@ func TestAccBedrockAgentActionGroup_s3APISchema(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_bedrockagent_agent_action_group.test" - var v bedrockagent.GetAgentActionGroupOutput + var v awstypes.AgentActionGroup resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) }, @@ -85,7 +86,7 @@ func TestAccBedrockAgentActionGroup_update(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_bedrockagent_agent_action_group.test" - var v bedrockagent.GetAgentActionGroupOutput + var v awstypes.AgentActionGroup resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, names.BedrockEndpointID) }, @@ -152,7 +153,7 @@ func testAccCheckAgentActionGroupDestroy(ctx context.Context) resource.TestCheck return nil } } -func testAccCheckAgentActionGroupExists(ctx context.Context, n string, v *bedrockagent.GetAgentActionGroupOutput) resource.TestCheckFunc { +func testAccCheckAgentActionGroupExists(ctx context.Context, n string, v *awstypes.AgentActionGroup) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { diff --git a/website/docs/r/bedrockagent_agent_action_group.html.markdown b/website/docs/r/bedrockagent_agent_action_group.html.markdown index 24b56c31d2b..9ab1f15ee3b 100644 --- a/website/docs/r/bedrockagent_agent_action_group.html.markdown +++ b/website/docs/r/bedrockagent_agent_action_group.html.markdown @@ -74,13 +74,6 @@ The following arguments are optional: * `description` - (Optional) Description of the Agent Action Group. * `skip_resource_in_use_check` - (Optional) Set to true to skip the in-use check when deleting. -## Attribute Reference - -This resource exports the following attributes in addition to the arguments above: - -* `created_at` - Timestamp the Agent Action Group was created at. -* `updated_at` - Timestamp the Agent Action Group was updated at. - ## Timeouts [Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): From e5cef3b561838d87ade3d699e2686e111282d4b9 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Fri, 19 Apr 2024 10:27:21 +0100 Subject: [PATCH 25/28] Make gen --- internal/service/bedrockagent/service_package_gen.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/bedrockagent/service_package_gen.go b/internal/service/bedrockagent/service_package_gen.go index 1b90cf88145..cbc628a5d3f 100644 --- a/internal/service/bedrockagent/service_package_gen.go +++ b/internal/service/bedrockagent/service_package_gen.go @@ -22,7 +22,7 @@ func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.Servic return []*types.ServicePackageFrameworkResource{ { Factory: newAgentActionGroupResource, - Name: "Bedrock Agent Action Group", + Name: "Agent Action Group", }, { Factory: newAgentAliasResource, From 8602817586929160909166ba8dce9014fc1c5701 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Fri, 19 Apr 2024 10:28:56 +0100 Subject: [PATCH 26/28] Fix import lint --- internal/service/bedrockagent/agent_action_group_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index e502b706b16..71f91deca4b 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -7,11 +7,11 @@ import ( "context" "errors" "fmt" - awstypes "github.com/aws/aws-sdk-go-v2/service/bedrockagent/types" "testing" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/bedrockagent" + awstypes "github.com/aws/aws-sdk-go-v2/service/bedrockagent/types" "github.com/aws/aws-sdk-go-v2/service/m2/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" From ad09a56d2926d1f5ded77715902fe302105e71a7 Mon Sep 17 00:00:00 2001 From: Andrew Tulloch Date: Fri, 19 Apr 2024 10:37:40 +0100 Subject: [PATCH 27/28] Restore empty attribute section --- website/docs/r/bedrockagent_agent_action_group.html.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/docs/r/bedrockagent_agent_action_group.html.markdown b/website/docs/r/bedrockagent_agent_action_group.html.markdown index 9ab1f15ee3b..1b4f1899ca0 100644 --- a/website/docs/r/bedrockagent_agent_action_group.html.markdown +++ b/website/docs/r/bedrockagent_agent_action_group.html.markdown @@ -74,6 +74,10 @@ The following arguments are optional: * `description` - (Optional) Description of the Agent Action Group. * `skip_resource_in_use_check` - (Optional) Set to true to skip the in-use check when deleting. +## Attribute Reference + +This resource exports the following attributes in addition to the arguments above: + ## Timeouts [Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): From 6d44f0feae186b4a7b01ec322180388727c7d7e4 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 19 Apr 2024 11:44:06 -0400 Subject: [PATCH 28/28] r/aws_bedrockagent_agent_action_group: Tidy up. --- .../bedrockagent/agent_action_group.go | 395 ++++++++---------- .../bedrockagent/agent_action_group_test.go | 31 +- internal/service/bedrockagent/exports_test.go | 10 +- 3 files changed, 192 insertions(+), 244 deletions(-) diff --git a/internal/service/bedrockagent/agent_action_group.go b/internal/service/bedrockagent/agent_action_group.go index d0bbfa0d0a2..e73eddc9621 100644 --- a/internal/service/bedrockagent/agent_action_group.go +++ b/internal/service/bedrockagent/agent_action_group.go @@ -8,12 +8,12 @@ import ( "fmt" "time" + "github.com/YakDriver/regexache" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/bedrockagent" awstypes "github.com/aws/aws-sdk-go-v2/service/bedrockagent/types" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" @@ -23,10 +23,9 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" - "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" - intflex "github.com/hashicorp/terraform-provider-aws/internal/flex" + "github.com/hashicorp/terraform-provider-aws/internal/flex" "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" @@ -34,10 +33,6 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -const ( - agentActionGroupIdParts = 3 -) - // @FrameworkResource(name="Agent Action Group") func newAgentActionGroupResource(context.Context) (resource.ResourceWithConfigure, error) { r := &agentActionGroupResource{} @@ -53,8 +48,8 @@ type agentActionGroupResource struct { framework.WithTimeouts } -func (r *agentActionGroupResource) Metadata(_ context.Context, request resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = "aws_bedrockagent_agent_action_group" +func (*agentActionGroupResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { + response.TypeName = "aws_bedrockagent_agent_action_group" } func (r *agentActionGroupResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { @@ -63,18 +58,15 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. "action_group_id": framework.IDAttribute(), "action_group_name": schema.StringAttribute{ Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), + Validators: []validator.String{ + stringvalidator.RegexMatches(regexache.MustCompile(`^([0-9a-zA-Z][_-]?){1,100}$`), "valid characters are a-z, A-Z, 0-9, _ (underscore) and - (hyphen). The name can have up to 100 characters"), }, }, "action_group_state": schema.StringAttribute{ - Optional: true, - Computed: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, + CustomType: fwtypes.StringEnumType[awstypes.ActionGroupState](), + Optional: true, + Computed: true, }, - "agent_id": schema.StringAttribute{ Required: true, PlanModifiers: []planmodifier.String{ @@ -89,39 +81,38 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. }, "description": schema.StringAttribute{ Optional: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), + Validators: []validator.String{ + stringvalidator.LengthBetween(1, 200), }, }, names.AttrID: framework.IDAttribute(), "parent_action_group_signature": schema.StringAttribute{ - Optional: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, + CustomType: fwtypes.StringEnumType[awstypes.ActionGroupSignature](), + Optional: true, }, "skip_resource_in_use_check": schema.BoolAttribute{ + Optional: true, Computed: true, Default: booldefault.StaticBool(false), - Optional: true, }, }, Blocks: map[string]schema.Block{ "action_group_executor": schema.ListNestedBlock{ - CustomType: fwtypes.NewListNestedObjectTypeOf[actionGroupExecutor](ctx), + CustomType: fwtypes.NewListNestedObjectTypeOf[actionGroupExecutorModel](ctx), Validators: []validator.List{ listvalidator.SizeAtMost(1), }, NestedObject: schema.NestedBlockObject{ Attributes: map[string]schema.Attribute{ "lambda": schema.StringAttribute{ - Required: true, + CustomType: fwtypes.ARNType, + Optional: true, }, }, }, }, "api_schema": schema.ListNestedBlock{ - CustomType: fwtypes.NewListNestedObjectTypeOf[apiSchema](ctx), + CustomType: fwtypes.NewListNestedObjectTypeOf[apiSchemaModel](ctx), Validators: []validator.List{ listvalidator.SizeAtMost(1), }, @@ -134,14 +125,11 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. path.MatchRelative().AtParent().AtName("s3"), ), }, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, }, }, Blocks: map[string]schema.Block{ "s3": schema.ListNestedBlock{ - CustomType: fwtypes.NewListNestedObjectTypeOf[s3](ctx), + CustomType: fwtypes.NewListNestedObjectTypeOf[s3IdentifierModel](ctx), Validators: []validator.List{ listvalidator.SizeAtMost(1), listvalidator.ConflictsWith( @@ -152,15 +140,9 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. Attributes: map[string]schema.Attribute{ "s3_bucket_name": schema.StringAttribute{ Optional: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, }, "s3_object_key": schema.StringAttribute{ Optional: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, }, }, }, @@ -173,7 +155,7 @@ func (r *agentActionGroupResource) Schema(ctx context.Context, request resource. } func (r *agentActionGroupResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { - var data actionGroupResourceModel + var data agentActionGroupResourceModel response.Diagnostics.Append(request.Plan.Get(ctx, &data)...) if response.Diagnostics.HasError() { return @@ -181,63 +163,65 @@ func (r *agentActionGroupResource) Create(ctx context.Context, request resource. conn := r.Meta().BedrockAgentClient(ctx) - var input bedrockagent.CreateAgentActionGroupInput - response.Diagnostics.Append(fwflex.Expand(ctx, data, &input)...) - - apiSchemaInput, diags := expandAPISchema(ctx, data.APISchema) - response.Diagnostics.Append(diags...) - + input := &bedrockagent.CreateAgentActionGroupInput{} + response.Diagnostics.Append(fwflex.Expand(ctx, data, input)...) if response.Diagnostics.HasError() { return } - input.ApiSchema = apiSchemaInput - - actionGroupExecutorInput, diags := expandActionGroupExecutor(ctx, data.ActionGroupExecutor) - response.Diagnostics.Append(diags...) + // AutoFlEx doesn't yet handle union types. + if !data.ActionGroupExecutor.IsNull() { + actionGroupExecutorData, diags := data.ActionGroupExecutor.ToPtr(ctx) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } - if response.Diagnostics.HasError() { - return + input.ActionGroupExecutor = expandActionGroupExecutor(ctx, actionGroupExecutorData) } - input.ActionGroupExecutor = actionGroupExecutorInput - - output, err := conn.CreateAgentActionGroup(ctx, &input) - - if err != nil { - response.Diagnostics.AddError("creating Bedrock Agent Group", err.Error()) + if !data.APISchema.IsNull() { + apiSchemaData, diags := data.APISchema.ToPtr(ctx) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } - return + input.ApiSchema = expandAPISchema(ctx, apiSchemaData) } - response.Diagnostics.Append(fwflex.Flatten(ctx, output.AgentActionGroup, &data)...) + output, err := conn.CreateAgentActionGroup(ctx, input) - err = data.setId() if err != nil { - response.Diagnostics.AddError("creating Bedrock Agent Group", err.Error()) + response.Diagnostics.AddError("creating Bedrock Agent Action Group", err.Error()) return } + // Set values for unknowns. + data.ActionGroupID = fwflex.StringToFramework(ctx, output.AgentActionGroup.ActionGroupId) + data.ActionGroupState = fwtypes.StringEnumValue(output.AgentActionGroup.ActionGroupState) + data.setID() + response.Diagnostics.Append(response.State.Set(ctx, &data)...) } func (r *agentActionGroupResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { - var data actionGroupResourceModel + var data agentActionGroupResourceModel response.Diagnostics.Append(request.State.Get(ctx, &data)...) if response.Diagnostics.HasError() { return } - if data.ID.IsNull() { - response.Diagnostics.AddError("parsing resource ID", "Action Group ID") + if err := data.InitFromID(); err != nil { + response.Diagnostics.AddError("parsing resource ID", err.Error()) return } conn := r.Meta().BedrockAgentClient(ctx) - output, err := findAgentActionGroupByID(ctx, conn, data.ID.ValueString()) + output, err := findAgentActionGroupByThreePartKey(ctx, conn, data.ActionGroupID.ValueString(), data.AgentID.ValueString(), data.AgentVersion.ValueString()) if tfresource.NotFound(err) { response.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err)) @@ -247,7 +231,7 @@ func (r *agentActionGroupResource) Read(ctx context.Context, request resource.Re } if err != nil { - response.Diagnostics.AddError(fmt.Sprintf("reading Bedrock Agent (%s)", data.ID.ValueString()), err.Error()) + response.Diagnostics.AddError(fmt.Sprintf("reading Bedrock Agent Action Group (%s)", data.ID.ValueString()), err.Error()) return } @@ -257,27 +241,15 @@ func (r *agentActionGroupResource) Read(ctx context.Context, request resource.Re return } - apiSchemaData, moreDiags := flattenAPISchema(ctx, output.ApiSchema) - response.Diagnostics.Append(moreDiags...) - if response.Diagnostics.HasError() { - return - } - - data.APISchema = apiSchemaData - - ageData, moreDiags := flattenActionGroupExecutor(ctx, output.ActionGroupExecutor) - response.Diagnostics.Append(moreDiags...) - if response.Diagnostics.HasError() { - return - } - - data.ActionGroupExecutor = ageData + // AutoFlEx doesn't yet handle union types. + data.ActionGroupExecutor = flattenActionGroupExecutor(ctx, output.ActionGroupExecutor) + data.APISchema = flattenAPISchema(ctx, output.ApiSchema) response.Diagnostics.Append(response.State.Set(ctx, &data)...) } func (r *agentActionGroupResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { - var old, new actionGroupResourceModel + var old, new agentActionGroupResourceModel response.Diagnostics.Append(request.State.Get(ctx, &old)...) if response.Diagnostics.HasError() { return @@ -289,60 +261,62 @@ func (r *agentActionGroupResource) Update(ctx context.Context, request resource. conn := r.Meta().BedrockAgentClient(ctx) - if agentActionGroupHasChanges(ctx, old, new) { + if !new.ActionGroupExecutor.Equal(old.ActionGroupExecutor) || + !new.ActionGroupName.Equal(old.ActionGroupName) || + !new.ActionGroupState.Equal(old.ActionGroupState) || + !new.APISchema.Equal(old.APISchema) || + !new.Description.Equal(old.Description) || + !new.ParentActionGroupSignature.Equal(old.ParentActionGroupSignature) { input := &bedrockagent.UpdateAgentActionGroupInput{} response.Diagnostics.Append(fwflex.Expand(ctx, new, input)...) if response.Diagnostics.HasError() { return } - apiConfig, diags := expandAPISchema(ctx, new.APISchema) - response.Diagnostics.Append(diags...) + // AutoFlEx doesn't yet handle union types. + if !new.ActionGroupExecutor.IsNull() { + actionGroupExecutorData, diags := new.ActionGroupExecutor.ToPtr(ctx) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } - if response.Diagnostics.HasError() { - return + input.ActionGroupExecutor = expandActionGroupExecutor(ctx, actionGroupExecutorData) } - input.ApiSchema = apiConfig - - ageConfig, diags := expandActionGroupExecutor(ctx, new.ActionGroupExecutor) - response.Diagnostics.Append(diags...) + if !new.APISchema.IsNull() { + apiSchemaData, diags := new.APISchema.ToPtr(ctx) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } - if response.Diagnostics.HasError() { - return + input.ApiSchema = expandAPISchema(ctx, apiSchemaData) } - input.ActionGroupExecutor = ageConfig - _, err := conn.UpdateAgentActionGroup(ctx, input) if err != nil { - response.Diagnostics.AddError( - create.ProblemStandardMessage(names.BedrockAgent, create.ErrActionUpdating, "Bedrock Agent", old.AgentId.ValueString(), err), - err.Error(), - ) + response.Diagnostics.AddError(fmt.Sprintf("updating Bedrock Agent Action Group (%s)", new.ID.ValueString()), err.Error()) + return } } - out, err := findAgentActionGroupByID(ctx, conn, old.ID.ValueString()) + output, err := findAgentActionGroupByThreePartKey(ctx, conn, new.ActionGroupID.ValueString(), new.AgentID.ValueString(), new.AgentVersion.ValueString()) if err != nil { - response.Diagnostics.AddError( - create.ProblemStandardMessage(names.BedrockAgent, create.ErrActionUpdating, "Bedrock Agent", old.AgentId.ValueString(), err), - err.Error(), - ) - return - } - response.Diagnostics.Append(fwflex.Flatten(ctx, out, &new)...) - if response.Diagnostics.HasError() { + response.Diagnostics.AddError(fmt.Sprintf("reading Bedrock Agent Action Group (%s)", new.ID.ValueString()), err.Error()) + return } + new.ActionGroupState = fwtypes.StringEnumValue(output.ActionGroupState) + response.Diagnostics.Append(response.State.Set(ctx, &new)...) } func (r *agentActionGroupResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { - var data actionGroupResourceModel + var data agentActionGroupResourceModel response.Diagnostics.Append(request.State.Get(ctx, &data)...) if response.Diagnostics.HasError() { return @@ -350,40 +324,28 @@ func (r *agentActionGroupResource) Delete(ctx context.Context, request resource. conn := r.Meta().BedrockAgentClient(ctx) - if !data.ActionGroupId.IsNull() { - _, err := conn.DeleteAgentActionGroup(ctx, &bedrockagent.DeleteAgentActionGroupInput{ - AgentId: fwflex.StringFromFramework(ctx, data.AgentId), - ActionGroupId: fwflex.StringFromFramework(ctx, data.ActionGroupId), - AgentVersion: fwflex.StringFromFramework(ctx, data.AgentVersion), - SkipResourceInUseCheck: data.SkipResourceInUseCheck.ValueBool(), - }) - - if errs.IsA[*awstypes.ResourceNotFoundException](err) { - return - } - - if err != nil { - response.Diagnostics.AddError(fmt.Sprintf("deleting Bedrock Agent (%s)", data.ID.ValueString()), err.Error()) + _, err := conn.DeleteAgentActionGroup(ctx, &bedrockagent.DeleteAgentActionGroupInput{ + ActionGroupId: fwflex.StringFromFramework(ctx, data.ActionGroupID), + AgentId: fwflex.StringFromFramework(ctx, data.AgentID), + AgentVersion: fwflex.StringFromFramework(ctx, data.AgentVersion), + SkipResourceInUseCheck: data.SkipResourceInUseCheck.ValueBool(), + }) - return - } + if errs.IsA[*awstypes.ResourceNotFoundException](err) { + return } -} - -func findAgentActionGroupByID(ctx context.Context, conn *bedrockagent.Client, id string) (*awstypes.AgentActionGroup, error) { - parts, err := intflex.ExpandResourceId(id, agentActionGroupIdParts, false) if err != nil { - return nil, err - } + response.Diagnostics.AddError(fmt.Sprintf("deleting Bedrock Agent Action Group (%s)", data.ID.ValueString()), err.Error()) - actionGroupId := parts[0] - agentId := parts[1] - agentVersion := parts[2] + return + } +} +func findAgentActionGroupByThreePartKey(ctx context.Context, conn *bedrockagent.Client, actionGroupID, agentID, agentVersion string) (*awstypes.AgentActionGroup, error) { input := &bedrockagent.GetAgentActionGroupInput{ - ActionGroupId: aws.String(actionGroupId), - AgentId: aws.String(agentId), + ActionGroupId: aws.String(actionGroupID), + AgentId: aws.String(agentID), AgentVersion: aws.String(agentVersion), } @@ -400,134 +362,129 @@ func findAgentActionGroupByID(ctx context.Context, conn *bedrockagent.Client, id return nil, err } - if output == nil { + if output == nil || output.AgentActionGroup == nil { return nil, tfresource.NewEmptyResultError(input) } return output.AgentActionGroup, nil } -type actionGroupResourceModel struct { - ActionGroupId types.String `tfsdk:"action_group_id"` - ActionGroupExecutor fwtypes.ListNestedObjectValueOf[actionGroupExecutor] `tfsdk:"action_group_executor"` - ActionGroupName types.String `tfsdk:"action_group_name"` - ActionGroupState types.String `tfsdk:"action_group_state"` - AgentId types.String `tfsdk:"agent_id"` - AgentVersion types.String `tfsdk:"agent_version"` - APISchema fwtypes.ListNestedObjectValueOf[apiSchema] `tfsdk:"api_schema"` - Description types.String `tfsdk:"description"` - ID types.String `tfsdk:"id"` - ParentActionGroupSignature types.String `tfsdk:"parent_action_group_signature"` - SkipResourceInUseCheck types.Bool `tfsdk:"skip_resource_in_use_check"` +type agentActionGroupResourceModel struct { + ActionGroupID types.String `tfsdk:"action_group_id"` + ActionGroupExecutor fwtypes.ListNestedObjectValueOf[actionGroupExecutorModel] `tfsdk:"action_group_executor"` + ActionGroupName types.String `tfsdk:"action_group_name"` + ActionGroupState fwtypes.StringEnum[awstypes.ActionGroupState] `tfsdk:"action_group_state"` + AgentID types.String `tfsdk:"agent_id"` + AgentVersion types.String `tfsdk:"agent_version"` + APISchema fwtypes.ListNestedObjectValueOf[apiSchemaModel] `tfsdk:"api_schema"` + Description types.String `tfsdk:"description"` + ID types.String `tfsdk:"id"` + ParentActionGroupSignature fwtypes.StringEnum[awstypes.ActionGroupSignature] `tfsdk:"parent_action_group_signature"` + SkipResourceInUseCheck types.Bool `tfsdk:"skip_resource_in_use_check"` } -func (a *actionGroupResourceModel) setId() error { - id, err := intflex.FlattenResourceId([]string{a.ActionGroupId.ValueString(), a.AgentId.ValueString(), a.AgentVersion.ValueString()}, agentActionGroupIdParts, false) +const ( + agentActionGroupResourceIDPartCount = 3 +) + +func (m *agentActionGroupResourceModel) InitFromID() error { + id := m.ID.ValueString() + parts, err := flex.ExpandResourceId(id, agentActionGroupResourceIDPartCount, false) + if err != nil { return err } - a.ID = types.StringValue(id) + + m.ActionGroupID = types.StringValue(parts[0]) + m.AgentID = types.StringValue(parts[1]) + m.AgentVersion = types.StringValue(parts[2]) + return nil } -type actionGroupExecutor struct { - Lambda types.String `tfsdk:"lambda"` +func (m *agentActionGroupResourceModel) setID() { + m.ID = types.StringValue(errs.Must(flex.FlattenResourceId([]string{m.ActionGroupID.ValueString(), m.AgentID.ValueString(), m.AgentVersion.ValueString()}, agentActionGroupResourceIDPartCount, false))) } -type apiSchema struct { - Payload types.String `tfsdk:"payload"` - S3 fwtypes.ListNestedObjectValueOf[s3] `tfsdk:"s3"` +type actionGroupExecutorModel struct { + Lambda fwtypes.ARN `tfsdk:"lambda"` } -type s3 struct { - S3BucketName types.String `tfsdk:"s3_bucket_name"` - S3ObjectKey types.String `tfsdk:"s3_object_key"` +type apiSchemaModel struct { + Payload types.String `tfsdk:"payload"` + S3 fwtypes.ListNestedObjectValueOf[s3IdentifierModel] `tfsdk:"s3"` } -func agentActionGroupHasChanges(_ context.Context, plan, state actionGroupResourceModel) bool { - return !plan.ActionGroupName.Equal(state.ActionGroupName) || - !plan.Description.Equal(state.Description) +type s3IdentifierModel struct { + S3BucketName types.String `tfsdk:"s3_bucket_name"` + S3ObjectKey types.String `tfsdk:"s3_object_key"` } -func expandActionGroupExecutor(ctx context.Context, age fwtypes.ListNestedObjectValueOf[actionGroupExecutor]) (awstypes.ActionGroupExecutor, diag.Diagnostics) { - var diags diag.Diagnostics - var ageObject awstypes.ActionGroupExecutor - planAge, moreDiags := age.ToPtr(ctx) - - diags.Append(moreDiags...) - if diags.HasError() { - return ageObject, diags +func expandActionGroupExecutor(_ context.Context, actionGroupExecutorData *actionGroupExecutorModel) awstypes.ActionGroupExecutor { + if !actionGroupExecutorData.Lambda.IsNull() { + return &awstypes.ActionGroupExecutorMemberLambda{ + Value: actionGroupExecutorData.Lambda.ValueString(), + } } - if !planAge.Lambda.IsNull() { - var lambdaAge awstypes.ActionGroupExecutorMemberLambda - diags.Append(fwflex.Expand(ctx, planAge.Lambda, &lambdaAge.Value)...) - ageObject = &lambdaAge + return nil +} + +func flattenActionGroupExecutor(ctx context.Context, apiObject awstypes.ActionGroupExecutor) fwtypes.ListNestedObjectValueOf[actionGroupExecutorModel] { + if apiObject == nil { + return fwtypes.NewListNestedObjectValueOfNull[actionGroupExecutorModel](ctx) } - return ageObject, diags -} + var actionGroupExecutorData actionGroupExecutorModel -func flattenActionGroupExecutor(ctx context.Context, age awstypes.ActionGroupExecutor) (fwtypes.ListNestedObjectValueOf[actionGroupExecutor], diag.Diagnostics) { - var ageData actionGroupExecutor - switch v := age.(type) { + switch v := apiObject.(type) { case *awstypes.ActionGroupExecutorMemberLambda: - ageData.Lambda = fwflex.StringValueToFramework(ctx, v.Value) + actionGroupExecutorData.Lambda = fwtypes.ARNValueMust(v.Value) } - return fwtypes.NewListNestedObjectValueOfPtr(ctx, &ageData) + return fwtypes.NewListNestedObjectValueOfPtrMust(ctx, &actionGroupExecutorData) } -func expandAPISchema(ctx context.Context, api fwtypes.ListNestedObjectValueOf[apiSchema]) (awstypes.APISchema, diag.Diagnostics) { - var diags diag.Diagnostics - planApi, d := api.ToPtr(ctx) - diags.Append(d...) - if diags.HasError() { - return nil, diags +func expandAPISchema(ctx context.Context, apiSchemaData *apiSchemaModel) awstypes.APISchema { + if !apiSchemaData.Payload.IsNull() { + return &awstypes.APISchemaMemberPayload{ + Value: apiSchemaData.Payload.ValueString(), + } } - if !planApi.S3.IsNull() { - planS3Api, d := planApi.S3.ToPtr(ctx) - diags.Append(d...) - if diags.HasError() { - return nil, diags - } + if !apiSchemaData.S3.IsNull() { + s3IdentifierModel := fwdiag.Must(apiSchemaData.S3.ToPtr(ctx)) - apiObject := &awstypes.APISchemaMemberS3{} - diags.Append(fwflex.Expand(ctx, planS3Api, &apiObject.Value)...) - if diags.HasError() { - return nil, diags + return &awstypes.APISchemaMemberS3{ + Value: awstypes.S3Identifier{ + S3BucketName: fwflex.StringFromFramework(ctx, s3IdentifierModel.S3BucketName), + S3ObjectKey: fwflex.StringFromFramework(ctx, s3IdentifierModel.S3ObjectKey), + }, } - return apiObject, diags } - if !planApi.Payload.IsNull() { - apiObject := &awstypes.APISchemaMemberPayload{} - diags.Append(fwflex.Expand(ctx, planApi.Payload, &apiObject.Value)...) - if diags.HasError() { - return nil, diags - } - return apiObject, diags - } - return nil, diags + return nil } -func flattenAPISchema(ctx context.Context, apiObject awstypes.APISchema) (fwtypes.ListNestedObjectValueOf[apiSchema], diag.Diagnostics) { - var diags diag.Diagnostics - apiSchemaData := &apiSchema{ - S3: fwtypes.NewListNestedObjectValueOfNull[s3](ctx), - Payload: types.StringNull(), +func flattenAPISchema(ctx context.Context, apiObject awstypes.APISchema) fwtypes.ListNestedObjectValueOf[apiSchemaModel] { + if apiObject == nil { + return fwtypes.NewListNestedObjectValueOfNull[apiSchemaModel](ctx) } + var apiSchemaData apiSchemaModel + switch v := apiObject.(type) { - case *awstypes.APISchemaMemberS3: - s3data := &s3{} - diags.Append(fwflex.Flatten(ctx, v.Value, s3data)...) - apiSchemaData.S3 = fwtypes.NewListNestedObjectValueOfPtrMust(ctx, s3data) case *awstypes.APISchemaMemberPayload: - payloadValue := fwflex.StringValueToFramework(ctx, v.Value) - apiSchemaData.Payload = payloadValue + apiSchemaData.Payload = fwflex.StringValueToFramework(ctx, v.Value) + apiSchemaData.S3 = fwtypes.NewListNestedObjectValueOfNull[s3IdentifierModel](ctx) + + case *awstypes.APISchemaMemberS3: + apiSchemaData.Payload = types.StringNull() + apiSchemaData.S3 = fwtypes.NewListNestedObjectValueOfPtrMust(ctx, &s3IdentifierModel{ + S3BucketName: fwflex.StringToFramework(ctx, v.Value.S3BucketName), + S3ObjectKey: fwflex.StringToFramework(ctx, v.Value.S3ObjectKey), + }) } - return fwtypes.NewListNestedObjectValueOfPtrMust(ctx, apiSchemaData), diags + return fwtypes.NewListNestedObjectValueOfPtrMust(ctx, &apiSchemaData) } diff --git a/internal/service/bedrockagent/agent_action_group_test.go b/internal/service/bedrockagent/agent_action_group_test.go index 71f91deca4b..c19fd9f255a 100644 --- a/internal/service/bedrockagent/agent_action_group_test.go +++ b/internal/service/bedrockagent/agent_action_group_test.go @@ -5,22 +5,17 @@ package bedrockagent_test import ( "context" - "errors" "fmt" "testing" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/service/bedrockagent" awstypes "github.com/aws/aws-sdk-go-v2/service/bedrockagent/types" - "github.com/aws/aws-sdk-go-v2/service/m2/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" - "github.com/hashicorp/terraform-provider-aws/internal/create" - "github.com/hashicorp/terraform-provider-aws/internal/errs" - tfagent "github.com/hashicorp/terraform-provider-aws/internal/service/bedrockagent" + tfbedrockagent "github.com/hashicorp/terraform-provider-aws/internal/service/bedrockagent" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -130,24 +125,21 @@ func testAccCheckAgentActionGroupDestroy(ctx context.Context) resource.TestCheck conn := acctest.Provider.Meta().(*conns.AWSClient).BedrockAgentClient(ctx) for _, rs := range s.RootModule().Resources { - if rs.Type != "aws_bedrock_agent_action_group" { + if rs.Type != "aws_bedrockagent_agent_action_group" { continue } - _, err := conn.GetAgentActionGroup(ctx, &bedrockagent.GetAgentActionGroupInput{ - ActionGroupId: aws.String(rs.Primary.ID), - AgentId: aws.String(rs.Primary.Attributes["agent_id"]), - AgentVersion: aws.String(rs.Primary.Attributes["agent_version"]), - }) + _, err := tfbedrockagent.FindAgentActionGroupByThreePartKey(ctx, conn, rs.Primary.Attributes["action_group_id"], rs.Primary.Attributes["agent_id"], rs.Primary.Attributes["agent_version"]) - if errs.IsA[*types.ResourceNotFoundException](err) { - return nil + if tfresource.NotFound(err) { + continue } + if err != nil { - return create.Error(names.BedrockAgent, create.ErrActionCheckingDestroyed, "Bedrock Agent", rs.Primary.ID, err) + return err } - return create.Error(names.BedrockAgent, create.ErrActionCheckingDestroyed, "Bedrock Agent", rs.Primary.ID, errors.New("not destroyed")) + return fmt.Errorf("Bedrock Agent Action Group %s still exists", rs.Primary.ID) } return nil @@ -162,7 +154,7 @@ func testAccCheckAgentActionGroupExists(ctx context.Context, n string, v *awstyp conn := acctest.Provider.Meta().(*conns.AWSClient).BedrockAgentClient(ctx) - output, err := tfagent.FindAgentActionGroupByID(ctx, conn, rs.Primary.ID) + output, err := tfbedrockagent.FindAgentActionGroupByThreePartKey(ctx, conn, rs.Primary.Attributes["action_group_id"], rs.Primary.Attributes["agent_id"], rs.Primary.Attributes["agent_version"]) if err != nil { return err @@ -224,8 +216,6 @@ resource "aws_bedrockagent_agent_action_group" "test" { } depends_on = [aws_s3_object.test] } - - `, rName)) } @@ -259,6 +249,5 @@ resource "aws_lambda_function" "test_lambda" { runtime = "python3.9" } - `, rName) } diff --git a/internal/service/bedrockagent/exports_test.go b/internal/service/bedrockagent/exports_test.go index 120eb53070a..8b6de35182e 100644 --- a/internal/service/bedrockagent/exports_test.go +++ b/internal/service/bedrockagent/exports_test.go @@ -5,9 +5,11 @@ package bedrockagent // Exports for use in tests only. var ( - ResourceAgent = newAgentResource - ResourceAgentAlias = newAgentAliasResource + ResourceAgent = newAgentResource + ResourceAgentActionGroup = newAgentActionGroupResource + ResourceAgentAlias = newAgentAliasResource - FindAgentAliasByTwoPartKey = findAgentAliasByTwoPartKey - FindAgentByID = findAgentByID + FindAgentActionGroupByThreePartKey = findAgentActionGroupByThreePartKey + FindAgentAliasByTwoPartKey = findAgentAliasByTwoPartKey + FindAgentByID = findAgentByID )