From 30fbfe548f042a267e63093021a9c1b788810b95 Mon Sep 17 00:00:00 2001 From: christian-calabrese <christian.calabrese@pagopa.it> Date: Tue, 29 Oct 2024 16:33:10 +0100 Subject: [PATCH] [CAI-242] - Keep lambda warm by invoking it every 3 minutes (#1215) * feat: keep lambda warm by invoking it every 3 minutes * fix: add missing permissions to lambda * chore: add changeset * fix: eslint cloudfront functions --- .changeset/dull-items-grow.md | 5 ++++ .../src/viewer-request-handler.ts | 12 ++++++--- .../src/modules/chatbot/data.tf | 7 ++++- .../src/modules/chatbot/lambda_chatbot.tf | 27 +++++++++++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 .changeset/dull-items-grow.md diff --git a/.changeset/dull-items-grow.md b/.changeset/dull-items-grow.md new file mode 100644 index 0000000000..a9398add08 --- /dev/null +++ b/.changeset/dull-items-grow.md @@ -0,0 +1,5 @@ +--- +"infrastructure": patch +--- + +Chatbot lambda is now kept warm by invoking it every 3 minutes diff --git a/apps/cloudfront-functions/src/viewer-request-handler.ts b/apps/cloudfront-functions/src/viewer-request-handler.ts index bcca874095..bf58211057 100644 --- a/apps/cloudfront-functions/src/viewer-request-handler.ts +++ b/apps/cloudfront-functions/src/viewer-request-handler.ts @@ -20,17 +20,21 @@ const handler = ( const isHomepage = uri === '/'; // List of special cases (add more as needed) - const specialCases: string[] = ['.bollo']; + const specialCases: readonly string[] = ['.bollo']; // Function to check if URI ends with any of the special cases - const isSpecialCase = specialCases.some(caseExt => uri.endsWith(caseExt)); + const isSpecialCase = specialCases.some((caseExt) => uri.endsWith(caseExt)); if (!isHomepage) { if (uriEndsWithSlash) { request.uri = uri.replace(/\/$/, ''); } // Always add .html if there's no file extension, including special cases - if (!isGitbookAssets && !isWoff2 && (!/\.[a-zA-Z]+$/.test(uri) || isSpecialCase)) { + if ( + !isGitbookAssets && + !isWoff2 && + (!/\.[a-zA-Z]+$/.test(uri) || isSpecialCase) + ) { request.uri += '.html'; } } @@ -40,4 +44,4 @@ const handler = ( // do nothing return event.request; } -}; \ No newline at end of file +}; diff --git a/apps/infrastructure/src/modules/chatbot/data.tf b/apps/infrastructure/src/modules/chatbot/data.tf index 5d2cdb431d..3e20bd5788 100644 --- a/apps/infrastructure/src/modules/chatbot/data.tf +++ b/apps/infrastructure/src/modules/chatbot/data.tf @@ -44,7 +44,12 @@ data "aws_iam_policy_document" "lambda_dynamodb_policy" { "dynamodb:UpdateItem", "dynamodb:GetRecords" ] - resources = [module.dynamodb_chatbot_queries.dynamodb_table_arn, module.dynamodb_chatbot_sessions.dynamodb_table_arn] + resources = [ + module.dynamodb_chatbot_queries.dynamodb_table_arn, + "${module.dynamodb_chatbot_queries.dynamodb_table_arn}/*", + module.dynamodb_chatbot_sessions.dynamodb_table_arn, + "${module.dynamodb_chatbot_sessions.dynamodb_table_arn}/*" + ] } } diff --git a/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf b/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf index 0e3e15e68e..a2e753ad59 100644 --- a/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf +++ b/apps/infrastructure/src/modules/chatbot/lambda_chatbot.tf @@ -104,3 +104,30 @@ module "index_id_ssm_parameter" { secure_type = true ignore_value_changes = true } + +# Invoke the lambda function every 3 minutes from 6:00 am to 11:00 pm to keep it warm +resource "aws_cloudwatch_event_rule" "lambda_invocation_rule" { + name = "${local.prefix}-lambda-invocation-rule" + schedule_expression = "cron(0/3 6-23 * * ? *)" +} + +resource "aws_cloudwatch_event_target" "lambda_target" { + rule = aws_cloudwatch_event_rule.lambda_invocation_rule.name + target_id = "keep-chatbot-lambda-warm" + arn = module.lambda_function.lambda_function_arn + input = jsonencode({ + resource = "/", + path = "/", + httpMethod = "OPTIONS", + requestContext = {}, + multiValueQueryStringParameters = null + }) +} + +resource "aws_lambda_permission" "allow_eventbridge" { + action = "lambda:InvokeFunction" + function_name = module.lambda_function.lambda_function_name + principal = "events.amazonaws.com" + source_arn = aws_cloudwatch_event_rule.lambda_invocation_rule.arn + statement_id = "AllowExecutionFromEventBridge" +} \ No newline at end of file