Skip to content

Module Structure

terraform-aws-arc-bedrock

Latest Release Last Updated Terraform GitHub Actions

Quality gate

Known Vulnerabilities

Overview

This Terraform module provides an automated way to deploy and manage AWS Bedrock Agents, Collaborators, Action Groups, and associated IAM Roles. The module is designed to be flexible, reusable, and configurable to suit various use cases.

Features

  • Bedrock Agent Creation: Deploys an AWS Bedrock agent with configurable settings.
  • Collaborator Management: Supports multiple collaborators with required IAM permissions.
  • Action Groups: Enables defining multiple action groups for executing Lambda-based functions.
  • IAM Role Management: Automatically provisions IAM roles with necessary policies for Bedrock resources.

Module Components

1. Bedrock Agent

  • Configurable name, foundation model, and instruction set.
  • Supports enabling/disabling agent collaboration.
  • Customizable session timeout settings.

2. Collaborators

  • Allows defining multiple collaborators with their own permissions.
  • IAM roles and policies created dynamically.

3. Action Groups

  • Enables defining multiple action groups.
  • Supports dynamic function schemas for action execution.
  • Integrates AWS Lambda functions.

4. IAM Roles & Policies

  • Automatically provisions IAM roles for agents and collaborators.
  • Grants necessary permissions for Bedrock services.

Usage

Prerequisites

Before using this module, ensure you have the following:

  • AWS credentials configured.
  • Terraform installed.
  • A working knowledge of Terraform.

Getting Started

  1. Define the Module

Initially, it's essential to define a Terraform module, which is organized as a distinct directory encompassing Terraform configuration files. Within this module directory, input variables and output values must be defined in the variables.tf and outputs.tf files, respectively. The following illustrates an example directory structure:

1
2
3
4
5
bedrock-agent/
|-- main.tf
|-- variables.tf
|-- outputs.tf
|-- locals.tf
  1. Define Input Variables

Inside the variables.tf or in *.tfvars file, you should define values for the variables that the module requires.

  1. Use the Module in Your Main Configuration In your main Terraform configuration file (e.g., main.tf), you can use the module. Specify the source of the module, and version, For Example
module "bedrock_agents" {
  source = "sourcefuse/arc-bedrock/aws"
  version = "0.0.1"

  bedrock_agent_config = {
    create              = true
    name                = "arc-bedrock-agent"
    foundation_model    = "anthropic.claude-3-5-sonnet-20241022-v2:0"
    instruction         = "You are a customer support assistant. Answer user queries."
    agent_collaboration = "SUPERVISOR"
    prepare_agent       = false
    description         = "Supervisor agent"
  }
  agent_collaborator = {
    name                        = "collab-1"
    collaborator_name           = "Collaborator-One"
    foundation_model            = "anthropic.claude-3-5-sonnet-20241022-v2:0"
    instruction                 = "do what the supervisor is asking you to do"
    collaboration_instruction   = "tell the other agent on what to do"
    alias_name                  = "DocProcessor"
    description                 = "Collaborator 1"
    relay_conversation_history  = "TO_COLLABORATOR"
    prepare_agent               = true
    idle_session_ttl_in_seconds = 600
    action_groups               = local.action_groups
  }

  tags = module.tags.tags
}
  1. Output Values

Inside the outputs.tf file of the module, you can define output values that can be referenced in the main configuration. For example:

output "agent_arn" {
  value       = module.bedrock_agent.agent_arn
  description = "Agent arn"
}

output "agent_id" {
  value       = module.bedrock_agent.agent_id
  description = "Agent ID"
}

output "collaborator_agent_id" {
  description = "Agent ID created for collaborators."
  value       = module.bedrock_agent.collaborator_agent_id
}

output "agent_role_arn" {
  value       = module.bedrock_agent.agent_role_arn
  description = "Agent Role arn"
}
  1. .tfvars

Inside the .tfvars file of the module, you can provide desired values that can be referenced in the main configuration. For example:

Edit the locals.tf file and provide desired values.

collaborators - List of Collaborator Agents

action_groups - Action groups for Collaborator Agents

locals {

  collaborators = [
    {
      name                        = "collab-2"
      supervisor_agent_id         = module.bedrock_agent.agent_id
      collaborator_name           = "Collaborator-Two"
      foundation_model            = "anthropic.claude-3-5-sonnet-20241022-v2:0"
      instruction                 = "do what the supervisor is asking you to do"
      collaboration_instruction   = "tell the other agent on what to do"
      alias_name                  = "TechSupport"
      description                 = "Collaborator 2"
      relay_conversation_history  = "TO_COLLABORATOR"
      prepare_agent               = true
      idle_session_ttl_in_seconds = 600
      action_groups               = local.action_groups
    },
    {
      name                        = "collab-3"
      supervisor_agent_id         = module.bedrock_agent.agent_id
      collaborator_name           = "Collaborator-Three"
      foundation_model            = "anthropic.claude-3-5-sonnet-20241022-v2:0"
      instruction                 = "do what the supervisor is asking you to do"
      collaboration_instruction   = "tell the other agent on what to do"
      alias_name                  = "TechSupport"
      description                 = "Collaborator 3"
      relay_conversation_history  = "TO_COLLABORATOR"
      prepare_agent               = true
      idle_session_ttl_in_seconds = 600
      action_groups               = local.action_groups
    }
  ]

  action_groups = [{
    name                       = "singlerulegenerationagent-actiongroup"
    state                      = "ENABLED"
    agent_version              = "DRAFT"
    skip_resource_in_use_check = true
    action_group_executor      = { lambda = "arn:aws:lambda:us-east-1:884360309640:function:arc-debug-budgets-default" }

    function_schema = [
      {
        functions = [
          {
            name        = "extract_general_props"
            description = "Extracts general info properties based on the user prompt."
            parameters = [
              {
                map_block_key = "prompt"
                type          = "string"
                description   = "The user instruction/prompt to create or edit the rule."
                required      = true
              },
              {
                map_block_key = "rule_context"
                type          = "string"
                description   = "The existing rule to be updated, if provided."
                required      = false
              }
            ]
          },
          {
            name        = "extract_static_props"
            description = "Extracts static properties based on the user prompt."
            parameters = [
              {
                map_block_key = "prompt"
                type          = "string"
                description   = "The user instruction/prompt to create or edit the rule."
                required      = true
              },
              {
                map_block_key = "rule_context"
                type          = "string"
                description   = "The existing rule to be updated, if provided."
                required      = false
              }
            ]
          }
        ]
      }
    ]
  }]

}

First Time Usage

uncomment the backend block in main.tf

terraform init -backend-config=config.dev.hcl
If testing locally, terraform init should be fine

Create a dev workspace

terraform workspace new dev

Plan Terraform

terraform plan -var-file dev.tfvars

Apply Terraform

terraform apply -var-file dev.tfvars

Production Setup

terraform init -backend-config=config.prod.hcl

Create a prod workspace

terraform workspace new prod

Plan Terraform

terraform plan -var-file prod.tfvars

Apply Terraform

terraform apply -var-file prod.tfvars  -parallelism=1

Cleanup

Destroy Terraform

terraform destroy -var-file dev.tfvars -parallelism=1

Module Usage

To see a full example, check out the main.tf file in the example folder.

Requirements

Name Version
terraform >= 1.3, < 2.0.0
aws >= 5.0, < 6.0
opensearch 2.3.1
time 0.13.0

Providers

Name Version
aws 5.89.0

Modules

Name Source Version
collaborators ./modules/collaborator n/a
knowledge_base ./modules/knowledge-base n/a

Resources

Name Type
aws_bedrockagent_agent.collaborator resource
aws_bedrockagent_agent.this resource
aws_bedrockagent_agent_alias.this resource
aws_iam_role.collaborator resource
aws_iam_role.this resource
aws_iam_role_policy.collaborator resource
aws_iam_role_policy.this resource
aws_caller_identity.current data source
aws_iam_policy_document.agent_permissions data source
aws_iam_policy_document.agent_trust data source
aws_iam_policy_document.collaborator_agent_permissions data source
aws_partition.current data source
aws_region.current data source

Inputs

Name Description Type Default Required
agent_collaborator Configuration object for a collaborator, including name, instructions, and settings.
object({
name = string
supervisor_agent_id = optional(string, null)
collaborator_name = optional(string, null)
instruction = string
collaboration_instruction = string
alias_name = string
foundation_model = string
description = optional(string, "")
relay_conversation_history = optional(string, "TO_COLLABORATOR")
prepare_agent = optional(bool, true)
idle_session_ttl_in_seconds = optional(number, 500)

action_groups = optional(list(object({
name = string
state = string
agent_version = string
skip_resource_in_use_check = optional(bool, true)
action_group_executor = object(
{
lambda = optional(object({
name = string
add_permission = optional(bool, true)
}))
custom_control = optional(string, null)
})
function_schema = list(object({
functions = list(object({
name = string
description = string
parameters = list(object({
map_block_key = string
type = string
description = string
required = bool
}))
}))
}))

})), [])
})
null no
bedrock_agent_config Configuration for the Amazon Bedrock Agent, including name, session TTL, foundation model, tags, instructions, collaboration settings, and preparation options.
object({
create = optional(bool, false)
name = optional(string, null)
alias_name = optional(string, null)
alias_description = optional(string, null)
idle_session_ttl_in_seconds = optional(number, 500)
foundation_model = optional(string, null)
instruction = optional(string, null)
agent_collaboration = optional(string, "DISABLED")
description = optional(string, null)
prepare_agent = optional(bool, true)
role_arn = optional(string, null)
})
{
"create": false
}
no
environment Name of the environment, i.e. dev, stage, prod string n/a yes
knowledge_base_config Configuration for AWS Bedrock Agent Knowledge Base, including vector storage, embedding model, and OpenSearch integration.
object({
create = optional(bool, false)
name = string
role_arn = optional(string, null)
agent_role_name = optional(string, null)
foundation_model_arn = string
description = optional(string, null)
agent_id = optional(string, null)
instruction = string
data_source_list = list(object({
type = optional(string, "S3")
s3_config = optional(object({
create = optional(bool, false)
name = string
inclusion_prefixes = optional(list(string), [])
}))
}))
data_storage_list = optional(list(object({
type = optional(string, "S3")
s3_config = optional(object({
create = optional(bool, false)
prefix = optional(string, "")
name = string
}))
})), [])
embedding_model_configuration = object({
dimensions = optional(number, 1024)
embedding_data_type = string
})
storage_configuration = object({
type = optional(string, "OPENSEARCH_SERVERLESS")
opensearch_serverless_configuration = object({
create = optional(bool, false)
name = optional(string, null)
collection_arn = optional(string, null)
access_policy_rules = optional(list(any), [])
data_lifecycle_policy_rules = optional(list(any), [])
index_config = object({
number_of_shards = optional(string, "2")
number_of_replicas = optional(string, "0")
index_knn = optional(bool, true)
index_knn_algo_param_ef_search = optional(string, "512")
mappings = optional(string, null)
})
vector_index_name = string
field_mapping = object({
vector_field = string
text_field = string
metadata_field = string
})
})
})
})
{
"create": false,
"data_source_list": [],
"data_storage_list": [],
"embedding_model_configuration": null,
"foundation_model_arn": null,
"instruction": null,
"name": null,
"storage_configuration": null
}
no
namespace Namespace of the project, i.e. arc string n/a yes
tags Tags for Bedrock resources map(string) {} no

Outputs

Name Description
agent_arn Agent arn
agent_id Agent ID
agent_role_arn Agent Role arn
alias_arn ARN of the alias
alias_id Unique identifier of the alias.
collaborator_agent_id Agent ID created for collaborators.
collaborator_role_arns ARNs of the IAM roles created for collaborators.
opensearch_collection_endpoint Opensearch Collection endpoint

Development

Prerequisites

Configurations

  • Configure pre-commit hooks
pre-commit install

Git commits

while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch

For Example

git commit -m "your commit message #major"
By specifying this , it will bump the version and if you dont specify this in your commit message then by default it will consider patch and will bump that accordingly

Tests

  • Tests are available in test directory
  • Configure the dependencies
1
2
3
cd test
go mod init github.com/sourcefuse/terraform-aws-arc-bedrock
go get github.com/gruntwork-io/terratest/modules/terraform
  • Now execute the test
cd test/
go test

Authors

This project is authored by:

  • SourceFuse ARC Team