diff --git a/.changelog/38944.txt b/.changelog/38944.txt new file mode 100644 index 00000000000..67dc27eff53 --- /dev/null +++ b/.changelog/38944.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_bedrockagent_agent: Fixes consistency issues where only some prompts are overridden +``` diff --git a/internal/service/bedrockagent/agent.go b/internal/service/bedrockagent/agent.go index d7874690e99..439c70c2564 100644 --- a/internal/service/bedrockagent/agent.go +++ b/internal/service/bedrockagent/agent.go @@ -212,6 +212,8 @@ func (r *agentResource) Create(ctx context.Context, request resource.CreateReque } } + removeDefaultPrompts(agent) + // Set values for unknowns. response.Diagnostics.Append(fwflex.Flatten(ctx, agent, &data)...) if response.Diagnostics.HasError() { @@ -252,6 +254,8 @@ func (r *agentResource) Read(ctx context.Context, request resource.ReadRequest, return } + removeDefaultPrompts(agent) + response.Diagnostics.Append(fwflex.Flatten(ctx, agent, &data)...) if response.Diagnostics.HasError() { return @@ -329,6 +333,8 @@ func (r *agentResource) Update(ctx context.Context, request resource.UpdateReque } } + removeDefaultPrompts(agent) + // Set values for unknowns. response.Diagnostics.Append(fwflex.Flatten(ctx, agent, &new)...) if response.Diagnostics.HasError() { @@ -539,6 +545,22 @@ func waitAgentDeleted(ctx context.Context, conn *bedrockagent.Client, id string, return nil, err } +func removeDefaultPrompts(agent *awstypes.Agent) { + pocm := agent.PromptOverrideConfiguration + + overrides := pocm.PromptConfigurations + + var filtered []awstypes.PromptConfiguration + + for _, override := range overrides { + if override.PromptCreationMode == awstypes.CreationModeOverridden { + filtered = append(filtered, override) + } + } + + pocm.PromptConfigurations = filtered +} + type agentResourceModel struct { AgentARN types.String `tfsdk:"agent_arn"` AgentID types.String `tfsdk:"agent_id"` diff --git a/internal/service/bedrockagent/agent_test.go b/internal/service/bedrockagent/agent_test.go index f083325f64c..574f06e1998 100644 --- a/internal/service/bedrockagent/agent_test.go +++ b/internal/service/bedrockagent/agent_test.go @@ -83,6 +83,110 @@ func TestAccBedrockAgentAgent_full(t *testing.T) { }) } +func TestAccBedrockAgentAgent_singlePrompt(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_bedrockagent_agent.test" + var v awstypes.Agent + + 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: testAccCheckAgentDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccAgentConfig_singlePrompt(rName, "anthropic.claude-v2", "basic claude"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAgentExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "agent_name", rName), + resource.TestCheckResourceAttr(resourceName, "prompt_override_configuration.#", acctest.Ct1), + resource.TestCheckResourceAttr(resourceName, names.AttrDescription, "basic claude"), + resource.TestCheckResourceAttr(resourceName, "skip_resource_in_use_check", acctest.CtTrue), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"skip_resource_in_use_check"}, + }, + }, + }) +} + +func TestAccBedrockAgentAgent_addPrompt(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_bedrockagent_agent.test" + var v awstypes.Agent + + 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: testAccCheckAgentDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccAgentConfig_basic(rName, "anthropic.claude-v2", "basic claude"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAgentExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "agent_name", rName), + resource.TestCheckResourceAttr(resourceName, "prompt_override_configuration.#", acctest.Ct1), + resource.TestCheckResourceAttr(resourceName, "prompt_override_configuration.0.prompt_configurations.#", acctest.Ct0), + resource.TestCheckResourceAttr(resourceName, names.AttrDescription, "basic claude"), + resource.TestCheckResourceAttr(resourceName, "skip_resource_in_use_check", acctest.CtFalse), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"skip_resource_in_use_check"}, + }, + { + Config: testAccAgentConfig_singlePrompt(rName, "anthropic.claude-v2", "basic claude"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAgentExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "agent_name", rName), + resource.TestCheckResourceAttr(resourceName, "prompt_override_configuration.#", acctest.Ct1), + resource.TestCheckResourceAttr(resourceName, "prompt_override_configuration.0.prompt_configurations.#", acctest.Ct1), + resource.TestCheckResourceAttr(resourceName, names.AttrDescription, "basic claude"), + resource.TestCheckResourceAttr(resourceName, "skip_resource_in_use_check", acctest.CtTrue), + ), + }, + { + Config: testAccAgentConfig_full(rName, "anthropic.claude-v2", "basic claude"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAgentExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "agent_name", rName), + resource.TestCheckResourceAttr(resourceName, "prompt_override_configuration.#", acctest.Ct1), + resource.TestCheckResourceAttr(resourceName, "prompt_override_configuration.0.prompt_configurations.#", acctest.Ct4), + resource.TestCheckResourceAttr(resourceName, names.AttrDescription, "basic claude"), + resource.TestCheckResourceAttr(resourceName, "skip_resource_in_use_check", acctest.CtTrue), + ), + }, + { + Config: testAccAgentConfig_singlePrompt(rName, "anthropic.claude-v2", "basic claude"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAgentExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "agent_name", rName), + resource.TestCheckResourceAttr(resourceName, "prompt_override_configuration.#", acctest.Ct1), + resource.TestCheckResourceAttr(resourceName, "prompt_override_configuration.0.prompt_configurations.#", acctest.Ct1), + resource.TestCheckResourceAttr(resourceName, names.AttrDescription, "basic claude"), + resource.TestCheckResourceAttr(resourceName, "skip_resource_in_use_check", acctest.CtTrue), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"skip_resource_in_use_check"}, + }, + }, + }) +} + func TestAccBedrockAgentAgent_update(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -419,3 +523,40 @@ resource "aws_bedrockagent_agent" "test" { } `, rName, model, desc)) } + +func testAccAgentConfig_singlePrompt(rName, model, desc string) string { + return acctest.ConfigCompose(testAccAgent_base(rName, model), fmt.Sprintf(` +resource "aws_bedrockagent_agent" "test" { + agent_name = %[1]q + agent_resource_role_arn = aws_iam_role.test_agent.arn + description = %[3]q + idle_session_ttl_in_seconds = 500 + instruction = file("${path.module}/test-fixtures/instruction.txt") + foundation_model = %[2]q + skip_resource_in_use_check = true + + prompt_override_configuration { + override_lambda = null + prompt_configurations = [ + { + base_prompt_template = file("${path.module}/test-fixtures/post-processing.txt") + inference_configuration = [ + { + max_length = 2048 + stop_sequences = ["Human:"] + temperature = 0 + top_k = 250 + top_p = 1 + }, + ] + parser_mode = "DEFAULT" + prompt_creation_mode = "OVERRIDDEN" + prompt_state = "DISABLED" + prompt_type = "POST_PROCESSING" + }, + ] + } + +} +`, rName, model, desc)) +}