From af4b61931e30ab5b2e582a33b595f9b66678db1e Mon Sep 17 00:00:00 2001 From: Sergey Novikov Date: Mon, 4 Nov 2024 17:30:04 +0100 Subject: [PATCH] OPS-6322 Add module resources --- Makefile | 2 +- README.md | 96 ++++++++++++++++++++++++++++++++++++++++++++------- data.tf | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++ main.tf | 73 +++++++++++++++++++++++++++++++++++++++ variables.tf | 54 +++++++++++++++++++++++++++++ versions.tf | 6 ++++ 6 files changed, 315 insertions(+), 13 deletions(-) create mode 100644 data.tf create mode 100644 main.tf create mode 100644 variables.tf diff --git a/Makefile b/Makefile index affb4f3..15f1d75 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,7 @@ test: _pull-tf echo "------------------------------------------------------------"; \ echo "# Terraform init"; \ echo "------------------------------------------------------------"; \ - if docker run $$(tty -s && echo "-it" || echo) --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \ + if docker run $$(tty -s && echo "-it" || echo) --rm --network host -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \ init \ -lock=false \ -upgrade \ diff --git a/README.md b/README.md index da64134..2c0d2c5 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ -# terraform-module-template -Template for Terraform modules - - +# terraform-aws-bedrock-agent + +Terraform module for Amazon Bedrock Agent resources + +[![lint](https://github.com/flaconi/terraform-aws-bedrock-agent/workflows/lint/badge.svg)](https://github.com/flaconi/terraform-aws-bedrock-agent/actions?query=workflow%3Alint) +[![test](https://github.com/flaconi/terraform-aws-bedrock-agent/workflows/test/badge.svg)](https://github.com/flaconi/terraform-aws-bedrock-agent/actions?query=workflow%3Atest) +[![Tag](https://img.shields.io/github/tag/flaconi/terraform-aws-bedrock-agent.svg)](https://github.com/flaconi/terraform-aws-bedrock-agent/releases) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) For requirements regarding module structure: [style-guide-terraform.md](https://github.com/Flaconi/devops-docs/blob/master/doc/conventions/style-guide-terraform.md) @@ -18,7 +17,9 @@ For requirements regarding module structure: [style-guide-terraform.md](https:// ## Providers -No providers. +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~> 5.73 | @@ -28,17 +29,88 @@ No providers. | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | ~> 1.3 | +| [aws](#requirement\_aws) | ~> 5.73 | ## Required Inputs -No required inputs. +The following input variables are required: + +### [name](#input\_name) + +Description: Name for the agent. + +Type: `string` + +### [alias\_name](#input\_alias\_name) + +Description: Name for the agent alias. + +Type: `string` + +### [knowledgebase\_name](#input\_knowledgebase\_name) + +Description: Name for the knowledgebase. + +Type: `string` + +### [s3\_arn](#input\_s3\_arn) + +Description: ARN of S3 bucket with data + +Type: `string` + +### [oss\_arn](#input\_oss\_arn) + +Description: ARN of OpenSearch Serverless Collection. + +Type: `string` ## Optional Inputs -No optional inputs. +The following input variables are optional (have default values): + +### [alias\_description](#input\_alias\_description) + +Description: Description for the agent alias. + +Type: `string` + +Default: `null` + +### [agent\_model\_id](#input\_agent\_model\_id) + +Description: Model identifier for agent. + +Type: `string` + +Default: `"anthropic.claude-v2"` + +### [knowledgebase\_decription](#input\_knowledgebase\_decription) + +Description: Description for the knowledgebase. + +Type: `string` + +Default: `null` + +### [knowledgebase\_model\_id](#input\_knowledgebase\_model\_id) + +Description: Model identifier for Knowledgebase. + +Type: `string` + +Default: `"amazon.titan-embed-text-v1"` + +### [tags](#input\_tags) + +Description: A map of tags to assign to the customization job and custom model. + +Type: `map(string)` + +Default: `{}` @@ -53,4 +125,4 @@ No outputs. **[MIT License](LICENSE)** -Copyright (c) 2023 **[Flaconi GmbH](https://github.com/flaconi)** +Copyright (c) 2024 **[Flaconi GmbH](https://github.com/flaconi)** diff --git a/data.tf b/data.tf new file mode 100644 index 0000000..7fb84bd --- /dev/null +++ b/data.tf @@ -0,0 +1,97 @@ +data "aws_caller_identity" "current" {} + +data "aws_region" "current" {} + +data "aws_bedrock_foundation_model" "agent" { + model_id = var.agent_model_id +} + +data "aws_bedrock_foundation_model" "knowledgebase" { + model_id = var.knowledgebase_model_id +} + +data "aws_iam_policy_document" "agent_trust" { + statement { + actions = ["sts:AssumeRole"] + principals { + identifiers = ["bedrock.amazonaws.com"] + type = "Service" + } + condition { + test = "StringEquals" + values = [data.aws_caller_identity.current.account_id] + variable = "aws:SourceAccount" + } + condition { + test = "ArnLike" + values = ["arn:aws:bedrock:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:agent/*"] + variable = "AWS:SourceArn" + } + } +} + +data "aws_iam_policy_document" "agent_permissions" { + statement { + actions = ["bedrock:InvokeModel"] + resources = [ + data.aws_bedrock_foundation_model.agent.model_arn, + ] + } +} + +data "aws_iam_policy_document" "knowledgebase_trust" { + statement { + actions = ["sts:AssumeRole"] + principals { + identifiers = ["bedrock.amazonaws.com"] + type = "Service" + } + condition { + test = "StringEquals" + values = [data.aws_caller_identity.current.account_id] + variable = "aws:SourceAccount" + } + condition { + test = "ArnLike" + values = ["arn:aws:bedrock:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:knowledge-base/*"] + variable = "AWS:SourceArn" + } + } +} + +data "aws_iam_policy_document" "knowledgebase_permissions" { + statement { + actions = ["bedrock:InvokeModel"] + resources = [ + data.aws_bedrock_foundation_model.knowledgebase.model_arn, + ] + } + statement { + actions = ["aoss:APIAccessAll"] + resources = [ + var.oss_arn + ] + } + statement { + actions = ["s3:ListBucket"] + resources = [ + var.s3_arn + ] + condition { + test = "StringEquals" + values = [data.aws_caller_identity.current.account_id] + variable = "aws:ResourceAccount" + } + } + statement { + actions = ["s3:GetObject"] + resources = [ + "${var.s3_arn}/*" + ] + condition { + test = "StringEquals" + values = [data.aws_caller_identity.current.account_id] + variable = "aws:ResourceAccount" + } + } +} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..f4259ed --- /dev/null +++ b/main.tf @@ -0,0 +1,73 @@ +resource "aws_iam_role" "agent" { + assume_role_policy = data.aws_iam_policy_document.agent_trust.json + name_prefix = "BedrockExecutionRoleForAgents_" +} + +resource "aws_iam_role_policy" "agent" { + policy = data.aws_iam_policy_document.agent_permissions.json + role = aws_iam_role.agent.id +} + +resource "aws_iam_role" "knowledgebase" { + assume_role_policy = data.aws_iam_policy_document.knowledgebase_trust.json + name_prefix = "BedrockExecutionRoleForKnowledgeBase_" +} + +resource "aws_iam_role_policy" "knowledgebase" { + policy = data.aws_iam_policy_document.knowledgebase_permissions.json + role = aws_iam_role.agent.id +} + +resource "aws_bedrockagent_agent" "this" { + agent_name = var.name + agent_resource_role_arn = aws_iam_role.agent.arn + idle_session_ttl_in_seconds = 500 + foundation_model = var.agent_model_id +} + +resource "aws_bedrockagent_knowledge_base" "this" { + name = var.knowledgebase_name + role_arn = aws_iam_role.knowledgebase.arn + knowledge_base_configuration { + vector_knowledge_base_configuration { + embedding_model_arn = data.aws_bedrock_foundation_model.knowledgebase.model_arn + } + type = "VECTOR" + } + storage_configuration { + type = "OPENSEARCH_SERVERLESS" + opensearch_serverless_configuration { + collection_arn = var.oss_arn + vector_index_name = "bedrock-knowledge-base-default-index" + field_mapping { + vector_field = "bedrock-knowledge-base-default-vector" + text_field = "AMAZON_BEDROCK_TEXT_CHUNK" + metadata_field = "AMAZON_BEDROCK_METADATA" + } + } + } +} + +resource "aws_bedrockagent_agent_alias" "this" { + agent_alias_name = var.alias_name + agent_id = aws_bedrockagent_agent.this.agent_id + description = var.alias_description +} + +resource "aws_bedrockagent_data_source" "this" { + knowledge_base_id = aws_bedrockagent_knowledge_base.this.id + name = var.knowledgebase_name + data_source_configuration { + type = "S3" + s3_configuration { + bucket_arn = var.s3_arn + } + } +} + +resource "aws_bedrockagent_agent_knowledge_base_association" "this" { + agent_id = aws_bedrockagent_agent.this.id + description = var.knowledgebase_decription + knowledge_base_id = aws_bedrockagent_knowledge_base.this.id + knowledge_base_state = "ENABLED" +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..8500a7e --- /dev/null +++ b/variables.tf @@ -0,0 +1,54 @@ +variable "name" { + description = "Name for the agent." + type = string +} + +variable "alias_name" { + description = "Name for the agent alias." + type = string +} + +variable "alias_description" { + description = "Description for the agent alias." + type = string + default = null +} + +variable "agent_model_id" { + description = "Model identifier for agent." + type = string + default = "anthropic.claude-v2" +} + +variable "knowledgebase_name" { + description = "Name for the knowledgebase." + type = string +} + +variable "knowledgebase_decription" { + description = "Description for the knowledgebase." + type = string + default = null +} + +variable "knowledgebase_model_id" { + description = "Model identifier for Knowledgebase." + type = string + default = "amazon.titan-embed-text-v1" +} + +variable "s3_arn" { + description = "ARN of S3 bucket with data" + type = string +} + +variable "oss_arn" { + description = "ARN of OpenSearch Serverless Collection." + type = string +} + +variable "tags" { + description = "A map of tags to assign to the customization job and custom model." + type = map(string) + default = {} +} diff --git a/versions.tf b/versions.tf index e6b4cbd..c06253b 100644 --- a/versions.tf +++ b/versions.tf @@ -1,3 +1,9 @@ terraform { required_version = "~> 1.3" + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.73" + } + } }