Skip to content

Instantly share code, notes, and snippets.

@jason-riddle
Last active December 5, 2023 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jason-riddle/a7fae152bc9e5a5ad08e1705ef16563c to your computer and use it in GitHub Desktop.
Save jason-riddle/a7fae152bc9e5a5ad08e1705ef16563c to your computer and use it in GitHub Desktop.
# https://github.com/jason-riddle/amazon-bedrock-kendra-lex-chatbot
variable "lambda_image" {
description = "The Lambda container image to use in the stack"
type = string
default = "foo"
# default = "${ACCOUNT_ID}.dkr.ecr.${STACK_REGION}.amazonaws.com/${CF_STACK_NAME}:latest"
}
resource "aws_kendra_index" "kendra_index" {
name = "KendraChatbotIndex"
role_arn = aws_iam_role.kendra_role.arn
edition = "DEVELOPER_EDITION"
}
resource "aws_kendra_data_source" "kendra_data_source" {
index_id = aws_kendra_index.kendra_index.id
name = "KendraChatbotIndexDataSource"
role_arn = aws_iam_role.kendra_role.arn
type = "S3"
data_source_configuration {
s3_configuration {
bucket_name = aws_s3_bucket.web_data_s3_bucket.id
}
}
}
resource "aws_s3_bucket" "web_data_s3_bucket" {
bucket = "web-data-s3-bucket" # You may customize the bucket name
}
resource "aws_s3_bucket_acl" "private" {
bucket = aws_s3_bucket.web_data_s3_bucket.id
acl = "private"
}
resource "aws_iam_role" "kendra_role" {
name = "KendraChatbotRole"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Effect = "Allow",
Principal = {
Service = "kendra.amazonaws.com"
},
Action = "sts:AssumeRole",
}]
})
inline_policy {
name = "kendra-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow",
Action = ["kendra:BatchPutDocument", "kendra:BatchDeleteDocument"],
Resource = "*",
},
{
Effect = "Allow",
Action = ["s3:GetObject"],
Resource = "${aws_s3_bucket.web_data_s3_bucket.arn}/*",
},
{
Effect = "Allow",
Action = ["s3:ListBucket"],
Resource = aws_s3_bucket.web_data_s3_bucket.arn,
}
]
})
}
managed_policy_arns = ["arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"]
}
resource "aws_iam_role" "orchestrator_role" {
name = "OrchestratorChatbotRole"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Effect = "Allow",
Principal = {
Service = "lambda.amazonaws.com"
},
Action = "sts:AssumeRole",
}]
})
inline_policy {
name = "lambda_policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow",
Action = ["bedrock:InvokeModel"],
Resource = "*",
},
{
Effect = "Allow",
Action = ["kendra:Retrieve", "kendra:Query"],
Resource = aws_kendra_index.kendra_index.arn,
}
]
})
}
managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]
}
resource "aws_lambda_function" "orchestrator_function" {
package_type = "Image"
role = aws_iam_role.orchestrator_role.arn
function_name = "ChatbotOrchestratorFunction"
memory_size = 1024
timeout = 120
image_config {
image_uri = var.lambda_image
}
architectures = ["x86_64"]
environment {
variables = {
kendra_index_id = aws_kendra_index.kendra_index.id
aws_region = var.aws_region
}
}
}
resource "aws_iam_role" "bot_runtime_role" {
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Effect = "Allow",
Principal = {
Service = ["lexv2.amazonaws.com"]
},
Action = ["sts:AssumeRole"],
}]
})
path = "/"
inline_policy {
name = "LexRuntimeRolePolicy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow",
Action = ["polly:SynthesizeSpeech", "comprehend:DetectSentiment"],
Resource = "*",
}
]
})
}
}
resource "aws_lambda_permission" "invoke_from_lex" {
function_name = aws_lambda_function.orchestrator_function.arn
action = "lambda:InvokeFunction"
principal = "lexv2.amazonaws.com"
}
# resource "aws_lex_bot" "chatbot" {
# depends_on = [aws_iam_role.bot_runtime_role]
# name = "Chatbot"
# # role_arn = aws_iam_role.bot_runtime_role.arn
# child_directed = false
# idle_session_ttl_in_seconds = 300
# description = "LLM Bot"
# bot_locales {
# locale_id = "en_US"
# description = "Password Reset for LLM"
# nlu_confidence_threshold = 0.40
# voice_settings {
# voice_id = "Ivy"
# }
# slot_types {
# name = "AccountID"
# description = "Slot Type description"
# slot_type_values {
# value {
# value = "012345678901"
# }
# }
# value_selection_setting {
# resolution_strategy = "ORIGINAL_VALUE"
# }
# }
# intents {
# name = "PasswordReset"
# description = "Intent to reset password"
# sample_utterances = ["reset password", "forgot my password"]
# intent_confirmation_setting {
# prompt_specification {
# message_groups_list {
# message {
# plain_text_message {
# value = "I have sent a password reset email. Anything else I can help with?"
# }
# }
# }
# max_retries = 0
# allow_interrupt = false
# }
# declination_response {
# message_groups_list {
# message {
# plain_text_message {
# value = "Okay, I will not send a password reset email."
# }
# }
# }
# allow_interrupt = false
# }
# }
# slot_priorities {
# priority = 1
# slot_name = "AccountEmail"
# }
# slots {
# name = "AccountEmail"
# description = "something"
# slot_type_name = "AMAZON.EmailAddress"
# value_elicitation_setting {
# slot_constraint = "Required"
# prompt_specification {
# message_groups_list {
# message {
# plain_text_message {
# value = "I can help with that, what's your email?"
# }
# }
# }
# max_retries = 0
# allow_interrupt = false
# }
# }
# }
# }
# intents {
# name = "FallbackIntent"
# description = "Invoke Lambda when FallbackIntent gets hit"
# parent_intent_signature = "AMAZON.FallbackIntent"
# fulfillment_code_hook {
# enabled = true
# is_active = true
# }
# }
# intents {
# name = "Goodbye"
# description = "Terminate Conversation"
# sample_utterances = ["No more questions", "Goodbye"]
# intent_confirmation_setting {
# prompt_specification {
# message_groups_list {
# message {
# plain_text_message {
# value = "Goodbye"
# }
# }
# }
# max_retries = 0
# allow_interrupt = false
# }
# }
# }
# }
# }
# resource "aws_lex_bot_version" "chatbot_version1" {
# depends_on = [aws_lex_bot.chatbot]
# bot_id = aws_lex_bot.chatbot.id
# bot_version_locale_specification {
# locale_id = "en_US"
# source_bot_version = "DRAFT"
# }
# description = "Chatbot Version."
# }
# resource "aws_lex_bot_alias" "bot_alias" {
# depends_on = [aws_lex_bot_version.chatbot_version1]
# bot_id = aws_lex_bot.chatbot.id
# bot_alias_name = "ChatbotTestAlias"
# bot_alias_locale_settings {
# locale_id = "en_US"
# bot_alias_locale_setting {
# enabled = true
# code_hook_specification {
# lambda_code_hook {
# code_hook_interface_version = "1.0"
# lambda_arn = aws_lambda_function.orchestrator_function.arn
# }
# }
# }
# }
# bot_version = aws_lex_bot_version.chatbot_version1.bot_version
# sentiment_analysis_settings {
# detect_sentiment = true
# }
# }
# output "bot_alias" {
# value = aws_lex_bot_alias.bot_alias.name
# }
# output "bot_alias_id" {
# value = aws_lex_bot_alias.bot_alias.bot_alias_id
# }
# output "chatbot_id" {
# value = aws_lex_bot.chatbot.id
# }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment