diff --git a/lib/chatbot-api/functions/api-handler/index.py b/lib/chatbot-api/functions/api-handler/index.py index a1f76d29..cbe82c92 100644 --- a/lib/chatbot-api/functions/api-handler/index.py +++ b/lib/chatbot-api/functions/api-handler/index.py @@ -7,6 +7,7 @@ from pydantic import ValidationError from genai_core.types import CommonError +from genai_core.parameters import load_all_from_ssm from routes.health import router as health_router from routes.embeddings import router as embeddings_router from routes.cross_encoders import router as cross_encoders_router @@ -44,7 +45,9 @@ ) @tracer.capture_lambda_handler def handler(event: dict, context: LambdaContext) -> dict: + try: + load_all_from_ssm() logger.info( "Incoming request for " + event["info"]["fieldName"], arguments=event["arguments"], diff --git a/lib/chatbot-api/rest-api.ts b/lib/chatbot-api/rest-api.ts index 946af150..b2afa38f 100644 --- a/lib/chatbot-api/rest-api.ts +++ b/lib/chatbot-api/rest-api.ts @@ -40,6 +40,36 @@ export class ApiResolvers extends Construct { vpc: props.shared.vpc, }); + // Lambda has a size limit of 4KB in the env variables. + // To reduce the size, store verbose values in SSM Parameter store. + // Only a subset is using this method because env varibale are faster + const parameterStores: { [key: string]: string } = { + AURORA_DB_HOST: + props.ragEngines?.auroraPgVector?.database?.clusterEndpoint?.hostname ?? + "None", + DELETE_WORKSPACE_WORKFLOW_ARN: + props.ragEngines?.deleteWorkspaceWorkflow?.stateMachineArn ?? "None", + DELETE_DOCUMENT_WORKFLOW_ARN: + props.ragEngines?.deleteDocumentWorkflow?.stateMachineArn ?? "None", + CREATE_AURORA_WORKSPACE_WORKFLOW_ARN: + props.ragEngines?.auroraPgVector?.createAuroraWorkspaceWorkflow + ?.stateMachineArn ?? "None", + CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN: + props.ragEngines?.openSearchVector?.createOpenSearchWorkspaceWorkflow + ?.stateMachineArn ?? "None", + CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN: + props.ragEngines?.kendraRetrieval?.createKendraWorkspaceWorkflow + ?.stateMachineArn ?? "None", + }; + + const ssmPrefix = "/" + props.config.prefix + "/GraphQLApiHandler/"; + + for (const parameter in parameterStores) { + new ssm.StringParameter(this, parameter, { + parameterName: ssmPrefix + parameter, + stringValue: parameterStores[parameter], + }); + } const appSyncLambdaResolver = new lambda.Function( this, "GraphQLApiHandler", @@ -62,8 +92,21 @@ export class ApiResolvers extends Construct { vpc: props.shared.vpc, securityGroups: [apiSecurityGroup], vpcSubnets: props.shared.vpc.privateSubnets as ec2.SubnetSelection, + paramsAndSecrets: lambda.ParamsAndSecretsLayerVersion.fromVersion( + lambda.ParamsAndSecretsVersions.V1_0_103, + { + cacheSize: 500, + logLevel: lambda.ParamsAndSecretsLogLevel.INFO, + } + ), environment: { ...props.shared.defaultEnvironmentVariables, + LOAD_FROM_SSM_PREFIX: ssmPrefix, + LOAD_FROM_SSM: Object.keys(parameterStores).join(","), + AURORA_DB_USER: AURORA_DB_USERS.READ_ONLY.toString(), + AURORA_DB_PORT: + props.ragEngines?.auroraPgVector?.database?.clusterEndpoint?.port + + "", CONFIG_PARAMETER_NAME: props.shared.configParameter.parameterName, MODELS_PARAMETER_NAME: props.modelsParameter.parameterName, X_ORIGIN_VERIFY_SECRET_ARN: @@ -76,13 +119,6 @@ export class ApiResolvers extends Construct { CHATBOT_FILES_BUCKET_NAME: props.filesBucket.bucketName, PROCESSING_BUCKET_NAME: props.ragEngines?.processingBucket?.bucketName ?? "", - AURORA_DB_USER: AURORA_DB_USERS.READ_ONLY, - AURORA_DB_HOST: - props.ragEngines?.auroraPgVector?.database?.clusterEndpoint - ?.hostname ?? "", - AURORA_DB_PORT: - props.ragEngines?.auroraPgVector?.database?.clusterEndpoint?.port + - "", WORKSPACES_TABLE_NAME: props.ragEngines?.workspacesTable.tableName ?? "", WORKSPACES_BY_OBJECT_TYPE_INDEX_NAME: @@ -96,19 +132,6 @@ export class ApiResolvers extends Construct { SAGEMAKER_RAG_MODELS_ENDPOINT: props.ragEngines?.sageMakerRagModels?.model?.endpoint ?.attrEndpointName ?? "", - DELETE_WORKSPACE_WORKFLOW_ARN: - props.ragEngines?.deleteWorkspaceWorkflow?.stateMachineArn ?? "", - DELETE_DOCUMENT_WORKFLOW_ARN: - props.ragEngines?.deleteDocumentWorkflow?.stateMachineArn ?? "", - CREATE_AURORA_WORKSPACE_WORKFLOW_ARN: - props.ragEngines?.auroraPgVector?.createAuroraWorkspaceWorkflow - ?.stateMachineArn ?? "", - CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN: - props.ragEngines?.openSearchVector - ?.createOpenSearchWorkspaceWorkflow?.stateMachineArn ?? "", - CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN: - props.ragEngines?.kendraRetrieval?.createKendraWorkspaceWorkflow - ?.stateMachineArn ?? "", FILE_IMPORT_WORKFLOW_ARN: props.ragEngines?.fileImportWorkflow?.stateMachineArn ?? "", WEBSITE_CRAWLING_WORKFLOW_ARN: @@ -130,6 +153,20 @@ export class ApiResolvers extends Construct { }, } ); + + appSyncLambdaResolver.addToRolePolicy( + new iam.PolicyStatement({ + actions: ["ssm:GetParameter"], + resources: [ + `arn:aws:ssm:${cdk.Stack.of(scope).region}:${ + cdk.Stack.of(scope).account + }:parameter` + + ssmPrefix + + "*", + ], + }) + ); + this.appSyncLambdaResolver = appSyncLambdaResolver; function addPermissions(apiHandler: lambda.Function) { diff --git a/lib/shared/layers/python-sdk/python/genai_core/aurora/connection.py b/lib/shared/layers/python-sdk/python/genai_core/aurora/connection.py index b9b23651..6e6b6328 100644 --- a/lib/shared/layers/python-sdk/python/genai_core/aurora/connection.py +++ b/lib/shared/layers/python-sdk/python/genai_core/aurora/connection.py @@ -8,7 +8,6 @@ client = boto3.client("rds") AURORA_DB_USER = os.environ.get("AURORA_DB_USER") -AURORA_DB_HOST = os.environ.get("AURORA_DB_HOST") AURORA_DB_PORT = os.environ.get("AURORA_DB_PORT") AURORA_DB_REGION = os.environ.get("AWS_REGION") @@ -18,6 +17,7 @@ class AuroraConnection(object): token_refresh = datetime.now() - timedelta(minutes=1) def __init__(self, autocommit=True): + aurora_db_host = os.environ.get("AURORA_DB_HOST") now = datetime.now() if AuroraConnection.token_refresh < now: AuroraConnection.token_refresh = now + timedelta( @@ -26,14 +26,14 @@ def __init__(self, autocommit=True): # Base on # https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.Python.html AuroraConnection.token = client.generate_db_auth_token( - DBHostname=AURORA_DB_HOST, + DBHostname=aurora_db_host, Port=AURORA_DB_PORT, DBUsername=AURORA_DB_USER, Region=AURORA_DB_REGION, ) self.autocommit = autocommit - self.dbhost = AURORA_DB_HOST + self.dbhost = aurora_db_host self.dbport = AURORA_DB_PORT self.dbuser = AURORA_DB_USER self.dbpass = AuroraConnection.token diff --git a/lib/shared/layers/python-sdk/python/genai_core/documents.py b/lib/shared/layers/python-sdk/python/genai_core/documents.py index 81e8d679..0e52917f 100644 --- a/lib/shared/layers/python-sdk/python/genai_core/documents.py +++ b/lib/shared/layers/python-sdk/python/genai_core/documents.py @@ -27,7 +27,6 @@ "DEFAULT_KENDRA_S3_DATA_SOURCE_BUCKET_NAME" ) -DELETE_DOCUMENT_WORKFLOW_ARN = os.environ.get("DELETE_DOCUMENT_WORKFLOW_ARN") RSS_FEED_INGESTOR_FUNCTION = os.environ.get("RSS_FEED_INGESTOR_FUNCTION", "") RSS_FEED_SCHEDULE_ROLE_ARN = os.environ.get("RSS_FEED_SCHEDULE_ROLE_ARN", "") DOCUMENTS_BY_STATUS_INDEX = os.environ.get("DOCUMENTS_BY_STATUS_INDEX", "") @@ -196,7 +195,7 @@ def delete_document(workspace_id: str, document_id: str): raise genai_core.types.CommonError("Document not ready for deletion") response = sfn_client.start_execution( - stateMachineArn=DELETE_DOCUMENT_WORKFLOW_ARN, + stateMachineArn=os.environ.get("DELETE_DOCUMENT_WORKFLOW_ARN"), input=json.dumps( { "workspace_id": workspace_id, diff --git a/lib/shared/layers/python-sdk/python/genai_core/parameters.py b/lib/shared/layers/python-sdk/python/genai_core/parameters.py index b7eb65a4..37323c2b 100644 --- a/lib/shared/layers/python-sdk/python/genai_core/parameters.py +++ b/lib/shared/layers/python-sdk/python/genai_core/parameters.py @@ -1,4 +1,6 @@ import os +import urllib +import json from aws_lambda_powertools.utilities import parameters X_ORIGIN_VERIFY_SECRET_ARN = os.environ.get("X_ORIGIN_VERIFY_SECRET_ARN") @@ -7,6 +9,32 @@ MODELS_PARAMETER_NAME = os.environ.get("MODELS_PARAMETER_NAME") +def load_all_from_ssm(): + # Load all the Parameters and assigned them to an env variable + # This is done using the Lambda extensions for parameter store + load_from_ssm = os.environ.get("LOAD_FROM_SSM") + load_from_ssm_prefix = os.environ.get("LOAD_FROM_SSM_PREFIX") + token = os.environ.get("AWS_SESSION_TOKEN") + + if not token or not load_from_ssm or not load_from_ssm_prefix: + raise Exception("Please make sure env variables are set.") + + for var in load_from_ssm.split(","): + if var not in os.environ: + os.environ[var] = get_ssm_parameter(load_from_ssm_prefix + var, token) + + +def get_ssm_parameter(ssm_parameter_path: str, token: str): + # https://docs.aws.amazon.com/systems-manager/latest/userguide/ps-integration-lambda-extensions.html#ps-integration-lambda-extensions-how-it-works + params = urllib.parse.urlencode({"name": ssm_parameter_path}) + url = "http://localhost:2773/systemsmanager/parameters/get/?%s" % params + request = urllib.request.Request(url) + request.add_header("X-Aws-Parameters-Secrets-Token", token) + # Bandit false positive. The url used cannot use a different scheme + config = json.loads(urllib.request.urlopen(request).read()) # nosec + return config["Parameter"]["Value"] + + def get_external_api_key(name: str): api_keys = parameters.get_secret(API_KEYS_SECRETS_ARN, transform="json", max_age=60) diff --git a/lib/shared/layers/python-sdk/python/genai_core/workspaces.py b/lib/shared/layers/python-sdk/python/genai_core/workspaces.py index 56a71a11..59fc4a8f 100644 --- a/lib/shared/layers/python-sdk/python/genai_core/workspaces.py +++ b/lib/shared/layers/python-sdk/python/genai_core/workspaces.py @@ -16,16 +16,6 @@ WORKSPACES_BY_OBJECT_TYPE_INDEX_NAME = os.environ.get( "WORKSPACES_BY_OBJECT_TYPE_INDEX_NAME" ) -CREATE_AURORA_WORKSPACE_WORKFLOW_ARN = os.environ.get( - "CREATE_AURORA_WORKSPACE_WORKFLOW_ARN" -) -CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN = os.environ.get( - "CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN" -) -CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN = os.environ.get( - "CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN" -) -DELETE_WORKSPACE_WORKFLOW_ARN = os.environ.get("DELETE_WORKSPACE_WORKFLOW_ARN") WORKSPACE_OBJECT_TYPE = "workspace" @@ -147,7 +137,7 @@ def create_workspace_aurora( ddb_response = table.put_item(Item=item) response = sfn_client.start_execution( - stateMachineArn=CREATE_AURORA_WORKSPACE_WORKFLOW_ARN, + stateMachineArn=os.environ.get("CREATE_AURORA_WORKSPACE_WORKFLOW_ARN"), input=json.dumps( { "workspace_id": workspace_id, @@ -217,7 +207,7 @@ def create_workspace_open_search( ddb_response = table.put_item(Item=item) response = sfn_client.start_execution( - stateMachineArn=CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN, + stateMachineArn=os.environ.get("CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN"), input=json.dumps( { "workspace_id": workspace_id, @@ -263,7 +253,7 @@ def create_workspace_kendra( ddb_response = table.put_item(Item=item) response = sfn_client.start_execution( - stateMachineArn=CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN, + stateMachineArn=os.environ.get("CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN"), input=json.dumps( { "workspace_id": workspace_id, @@ -325,7 +315,7 @@ def delete_workspace(workspace_id: str): raise genai_core.types.CommonError("Workspace not ready for deletion") response = sfn_client.start_execution( - stateMachineArn=DELETE_WORKSPACE_WORKFLOW_ARN, + stateMachineArn=os.environ.get("DELETE_WORKSPACE_WORKFLOW_ARN"), input=json.dumps( { "workspace_id": workspace_id, diff --git a/tests/__snapshots__/cdk-app.test.ts.snap b/tests/__snapshots__/cdk-app.test.ts.snap index b4a98941..ee745bbd 100644 --- a/tests/__snapshots__/cdk-app.test.ts.snap +++ b/tests/__snapshots__/cdk-app.test.ts.snap @@ -3144,6 +3144,19 @@ schema { }, "Type": "AWS::Lambda::EventSourceMapping", }, + "ChatBotApiRestApiAURORADBHOST50DD50E7": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/AURORA_DB_HOST", + "Type": "String", + "Value": { + "Fn::GetAtt": [ + "RagEnginesAuroraPgVectorAuroraDatabase2A003265", + "Endpoint.Address", + ], + }, + }, + "Type": "AWS::SSM::Parameter", + }, "ChatBotApiRestApiApiSecurityGroupC0E40B67": { "Properties": { "GroupDescription": "prefixGenAIChatBotStack/ChatBotApi/RestApi/ApiSecurityGroup", @@ -3160,6 +3173,56 @@ schema { }, "Type": "AWS::EC2::SecurityGroup", }, + "ChatBotApiRestApiCREATEAURORAWORKSPACEWORKFLOWARN71570127": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/CREATE_AURORA_WORKSPACE_WORKFLOW_ARN", + "Type": "String", + "Value": { + "Ref": "RagEnginesAuroraPgVectorCreateAuroraWorkspace50EFF4E7", + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "ChatBotApiRestApiCREATEKENDRAWORKSPACEWORKFLOWARN5C545985": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN", + "Type": "String", + "Value": { + "Ref": "RagEnginesKendraRetrievalCreateKendraWorkspace5D8DE7EF", + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "ChatBotApiRestApiCREATEOPENSEARCHWORKSPACEWORKFLOWARNE33DBA7F": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN", + "Type": "String", + "Value": { + "Ref": "RagEnginesOpenSearchVectorCreateOpenSearchWorkspace2B2FCA5B", + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "ChatBotApiRestApiDELETEDOCUMENTWORKFLOWARN85E09161": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/DELETE_DOCUMENT_WORKFLOW_ARN", + "Type": "String", + "Value": { + "Ref": "RagEnginesWorkspacesDeleteDocumentA1FD6471", + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "ChatBotApiRestApiDELETEWORKSPACEWORKFLOWARN64B2371C": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/DELETE_WORKSPACE_WORKFLOW_ARN", + "Type": "String", + "Value": { + "Ref": "RagEnginesWorkspacesDeleteWorkspace6908C6DA", + }, + }, + "Type": "AWS::SSM::Parameter", + }, "ChatBotApiRestApiGraphQLApiHandler140797C1": { "DependsOn": [ "ChatBotApiRestApiGraphQLApiHandlerServiceRoleDefaultPolicy409D1897", @@ -3185,12 +3248,6 @@ schema { "API_KEYS_SECRETS_ARN": { "Ref": "SharedApiKeysSecret9EA666ED", }, - "AURORA_DB_HOST": { - "Fn::GetAtt": [ - "RagEnginesAuroraPgVectorAuroraDatabase2A003265", - "Endpoint.Address", - ], - }, "AURORA_DB_PORT": { "Fn::GetAtt": [ "RagEnginesAuroraPgVectorAuroraDatabase2A003265", @@ -3205,15 +3262,6 @@ schema { "CONFIG_PARAMETER_NAME": { "Ref": "SharedConfig358B4A20", }, - "CREATE_AURORA_WORKSPACE_WORKFLOW_ARN": { - "Ref": "RagEnginesAuroraPgVectorCreateAuroraWorkspace50EFF4E7", - }, - "CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN": { - "Ref": "RagEnginesKendraRetrievalCreateKendraWorkspace5D8DE7EF", - }, - "CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN": { - "Ref": "RagEnginesOpenSearchVectorCreateOpenSearchWorkspace2B2FCA5B", - }, "DEFAULT_KENDRA_INDEX_ID": { "Fn::GetAtt": [ "RagEnginesKendraRetrievalIndex922B65FC", @@ -3230,12 +3278,6 @@ schema { "Id", ], }, - "DELETE_DOCUMENT_WORKFLOW_ARN": { - "Ref": "RagEnginesWorkspacesDeleteDocumentA1FD6471", - }, - "DELETE_WORKSPACE_WORKFLOW_ARN": { - "Ref": "RagEnginesWorkspacesDeleteWorkspace6908C6DA", - }, "DOCUMENTS_BY_COMPOUND_KEY_INDEX_NAME": "by_compound_key_idx", "DOCUMENTS_BY_STATUS_INDEX": "by_status_idx", "DOCUMENTS_TABLE_NAME": { @@ -3244,6 +3286,8 @@ schema { "FILE_IMPORT_WORKFLOW_ARN": { "Ref": "RagEnginesDataImportFileImportWorkflowFileImportStateMachine398F0217", }, + "LOAD_FROM_SSM": "AURORA_DB_HOST,DELETE_WORKSPACE_WORKFLOW_ARN,DELETE_DOCUMENT_WORKFLOW_ARN,CREATE_AURORA_WORKSPACE_WORKFLOW_ARN,CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN,CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN", + "LOAD_FROM_SSM_PREFIX": "/prefix/GraphQLApiHandler/", "LOG_LEVEL": "INFO", "MODELS_PARAMETER_NAME": { "Ref": "ModelsModelsParameter4A14799B", @@ -3254,6 +3298,11 @@ schema { "CollectionEndpoint", ], }, + "PARAMETERS_SECRETS_EXTENSION_CACHE_ENABLED": "true", + "PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE": "500", + "PARAMETERS_SECRETS_EXTENSION_HTTP_PORT": "2773", + "PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL": "info", + "PARAMETERS_SECRETS_EXTENSION_MAX_CONNECTIONS": "3", "POWERTOOLS_DEV": "false", "POWERTOOLS_LOGGER_LOG_EVENT": "false", "POWERTOOLS_SERVICE_NAME": "chatbot", @@ -3273,10 +3322,14 @@ schema { "EndpointName", ], }, + "SECRETS_MANAGER_TIMEOUT_MILLIS": "0", + "SECRETS_MANAGER_TTL": "300", "SESSIONS_BY_USER_ID_INDEX_NAME": "byUserId", "SESSIONS_TABLE_NAME": { "Ref": "ChatBotApiChatDynamoDBTablesSessionsTable92B891E3", }, + "SSM_PARAMETER_STORE_TIMEOUT_MILLIS": "0", + "SSM_PARAMETER_STORE_TTL": "300", "UPLOAD_BUCKET_NAME": { "Ref": "RagEnginesDataImportUploadBucket061D697E", }, @@ -3316,6 +3369,7 @@ schema { { "Ref": "SharedCommonLayerFC89CBCE", }, + "arn:aws:lambda:us-east-1:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", ], "LoggingConfig": { "LogFormat": "JSON", @@ -3475,6 +3529,11 @@ schema { "Properties": { "PolicyDocument": { "Statement": [ + { + "Action": "ssm:GetParameter", + "Effect": "Allow", + "Resource": "arn:aws:ssm:us-east-1:111111111:parameter/prefix/GraphQLApiHandler/*", + }, { "Action": [ "kms:Decrypt", diff --git a/tests/chatbot-api/__snapshots__/chatbot-api-construct.test.ts.snap b/tests/chatbot-api/__snapshots__/chatbot-api-construct.test.ts.snap index d7b672bf..6aeef043 100644 --- a/tests/chatbot-api/__snapshots__/chatbot-api-construct.test.ts.snap +++ b/tests/chatbot-api/__snapshots__/chatbot-api-construct.test.ts.snap @@ -209,6 +209,98 @@ exports[`snapshot test 1`] = ` "value": "nodejs20.x", }, }, + "ParamsandsecretslayerMap": { + "af-south-1": { + "1x0x103xx86x64": "arn:aws:lambda:af-south-1:317013901791:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "ap-east-1": { + "1x0x103xx86x64": "arn:aws:lambda:ap-east-1:768336418462:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "ap-northeast-1": { + "1x0x103xx86x64": "arn:aws:lambda:ap-northeast-1:133490724326:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "ap-northeast-2": { + "1x0x103xx86x64": "arn:aws:lambda:ap-northeast-2:738900069198:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "ap-northeast-3": { + "1x0x103xx86x64": "arn:aws:lambda:ap-northeast-3:576959938190:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "ap-south-1": { + "1x0x103xx86x64": "arn:aws:lambda:ap-south-1:176022468876:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "ap-south-2": { + "1x0x103xx86x64": "arn:aws:lambda:ap-south-2:070087711984:layer:AWS-Parameters-and-Secrets-Lambda-Extension:1", + }, + "ap-southeast-1": { + "1x0x103xx86x64": "arn:aws:lambda:ap-southeast-1:044395824272:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "ap-southeast-2": { + "1x0x103xx86x64": "arn:aws:lambda:ap-southeast-2:665172237481:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "ap-southeast-3": { + "1x0x103xx86x64": "arn:aws:lambda:ap-southeast-3:490737872127:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "ca-central-1": { + "1x0x103xx86x64": "arn:aws:lambda:ca-central-1:200266452380:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "cn-north-1": { + "1x0x103xx86x64": "arn:aws-cn:lambda:cn-north-1:287114880934:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "cn-northwest-1": { + "1x0x103xx86x64": "arn:aws-cn:lambda:cn-northwest-1:287310001119:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "eu-central-1": { + "1x0x103xx86x64": "arn:aws:lambda:eu-central-1:187925254637:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "eu-central-2": { + "1x0x103xx86x64": "arn:aws:lambda:eu-central-2:772501565639:layer:AWS-Parameters-and-Secrets-Lambda-Extension:1", + }, + "eu-north-1": { + "1x0x103xx86x64": "arn:aws:lambda:eu-north-1:427196147048:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "eu-south-1": { + "1x0x103xx86x64": "arn:aws:lambda:eu-south-1:325218067255:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "eu-south-2": { + "1x0x103xx86x64": "arn:aws:lambda:eu-south-2:524103009944:layer:AWS-Parameters-and-Secrets-Lambda-Extension:1", + }, + "eu-west-1": { + "1x0x103xx86x64": "arn:aws:lambda:eu-west-1:015030872274:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "eu-west-2": { + "1x0x103xx86x64": "arn:aws:lambda:eu-west-2:133256977650:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "eu-west-3": { + "1x0x103xx86x64": "arn:aws:lambda:eu-west-3:780235371811:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "me-central-1": { + "1x0x103xx86x64": "arn:aws:lambda:me-central-1:858974508948:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "me-south-1": { + "1x0x103xx86x64": "arn:aws:lambda:me-south-1:832021897121:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "sa-east-1": { + "1x0x103xx86x64": "arn:aws:lambda:sa-east-1:933737806257:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "us-east-1": { + "1x0x103xx86x64": "arn:aws:lambda:us-east-1:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "us-east-2": { + "1x0x103xx86x64": "arn:aws:lambda:us-east-2:590474943231:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "us-gov-east-1": { + "1x0x103xx86x64": "arn:aws-us-gov:lambda:us-gov-east-1:129776340158:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "us-gov-west-1": { + "1x0x103xx86x64": "arn:aws-us-gov:lambda:us-gov-west-1:127562683043:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "us-west-1": { + "1x0x103xx86x64": "arn:aws:lambda:us-west-1:997803712105:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + "us-west-2": { + "1x0x103xx86x64": "arn:aws:lambda:us-west-2:345057560386:layer:AWS-Parameters-and-Secrets-Lambda-Extension:4", + }, + }, "RagEnginesSageMakerModelImageRepositoryCfnMappingF3891114": { "af-south-1": { "account": "626614931356", @@ -3235,6 +3327,19 @@ schema { }, "Type": "AWS::Lambda::EventSourceMapping", }, + "ChatBotApiConstructRestApiAURORADBHOST81276288": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/AURORA_DB_HOST", + "Type": "String", + "Value": { + "Fn::GetAtt": [ + "RagEnginesAuroraPgVectorAuroraDatabase2A003265", + "Endpoint.Address", + ], + }, + }, + "Type": "AWS::SSM::Parameter", + }, "ChatBotApiConstructRestApiApiSecurityGroup01DF524F": { "Properties": { "GroupDescription": "Default/ChatBotApiConstruct/RestApi/ApiSecurityGroup", @@ -3251,6 +3356,56 @@ schema { }, "Type": "AWS::EC2::SecurityGroup", }, + "ChatBotApiConstructRestApiCREATEAURORAWORKSPACEWORKFLOWARN377682C7": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/CREATE_AURORA_WORKSPACE_WORKFLOW_ARN", + "Type": "String", + "Value": { + "Ref": "RagEnginesAuroraPgVectorCreateAuroraWorkspace50EFF4E7", + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "ChatBotApiConstructRestApiCREATEKENDRAWORKSPACEWORKFLOWARN870B17B3": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN", + "Type": "String", + "Value": { + "Ref": "RagEnginesKendraRetrievalCreateKendraWorkspace5D8DE7EF", + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "ChatBotApiConstructRestApiCREATEOPENSEARCHWORKSPACEWORKFLOWARN306193C2": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN", + "Type": "String", + "Value": { + "Ref": "RagEnginesOpenSearchVectorCreateOpenSearchWorkspace2B2FCA5B", + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "ChatBotApiConstructRestApiDELETEDOCUMENTWORKFLOWARN95F1EED0": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/DELETE_DOCUMENT_WORKFLOW_ARN", + "Type": "String", + "Value": { + "Ref": "RagEnginesWorkspacesDeleteDocumentA1FD6471", + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "ChatBotApiConstructRestApiDELETEWORKSPACEWORKFLOWARN2BE6FC41": { + "Properties": { + "Name": "/prefix/GraphQLApiHandler/DELETE_WORKSPACE_WORKFLOW_ARN", + "Type": "String", + "Value": { + "Ref": "RagEnginesWorkspacesDeleteWorkspace6908C6DA", + }, + }, + "Type": "AWS::SSM::Parameter", + }, "ChatBotApiConstructRestApiGraphQLApiHandlerA19E8192": { "DependsOn": [ "ChatBotApiConstructRestApiGraphQLApiHandlerServiceRoleDefaultPolicyFF371064", @@ -3276,12 +3431,6 @@ schema { "API_KEYS_SECRETS_ARN": { "Ref": "SharedApiKeysSecret9EA666ED", }, - "AURORA_DB_HOST": { - "Fn::GetAtt": [ - "RagEnginesAuroraPgVectorAuroraDatabase2A003265", - "Endpoint.Address", - ], - }, "AURORA_DB_PORT": { "Fn::GetAtt": [ "RagEnginesAuroraPgVectorAuroraDatabase2A003265", @@ -3296,15 +3445,6 @@ schema { "CONFIG_PARAMETER_NAME": { "Ref": "SharedConfig358B4A20", }, - "CREATE_AURORA_WORKSPACE_WORKFLOW_ARN": { - "Ref": "RagEnginesAuroraPgVectorCreateAuroraWorkspace50EFF4E7", - }, - "CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN": { - "Ref": "RagEnginesKendraRetrievalCreateKendraWorkspace5D8DE7EF", - }, - "CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN": { - "Ref": "RagEnginesOpenSearchVectorCreateOpenSearchWorkspace2B2FCA5B", - }, "DEFAULT_KENDRA_INDEX_ID": { "Fn::GetAtt": [ "RagEnginesKendraRetrievalIndex922B65FC", @@ -3321,12 +3461,6 @@ schema { "Id", ], }, - "DELETE_DOCUMENT_WORKFLOW_ARN": { - "Ref": "RagEnginesWorkspacesDeleteDocumentA1FD6471", - }, - "DELETE_WORKSPACE_WORKFLOW_ARN": { - "Ref": "RagEnginesWorkspacesDeleteWorkspace6908C6DA", - }, "DOCUMENTS_BY_COMPOUND_KEY_INDEX_NAME": "by_compound_key_idx", "DOCUMENTS_BY_STATUS_INDEX": "by_status_idx", "DOCUMENTS_TABLE_NAME": { @@ -3335,6 +3469,8 @@ schema { "FILE_IMPORT_WORKFLOW_ARN": { "Ref": "RagEnginesDataImportFileImportWorkflowFileImportStateMachine398F0217", }, + "LOAD_FROM_SSM": "AURORA_DB_HOST,DELETE_WORKSPACE_WORKFLOW_ARN,DELETE_DOCUMENT_WORKFLOW_ARN,CREATE_AURORA_WORKSPACE_WORKFLOW_ARN,CREATE_OPEN_SEARCH_WORKSPACE_WORKFLOW_ARN,CREATE_KENDRA_WORKSPACE_WORKFLOW_ARN", + "LOAD_FROM_SSM_PREFIX": "/prefix/GraphQLApiHandler/", "LOG_LEVEL": "INFO", "MODELS_PARAMETER_NAME": { "Ref": "ModelsModelsParameter4A14799B", @@ -3345,6 +3481,11 @@ schema { "CollectionEndpoint", ], }, + "PARAMETERS_SECRETS_EXTENSION_CACHE_ENABLED": "true", + "PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE": "500", + "PARAMETERS_SECRETS_EXTENSION_HTTP_PORT": "2773", + "PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL": "info", + "PARAMETERS_SECRETS_EXTENSION_MAX_CONNECTIONS": "3", "POWERTOOLS_DEV": "false", "POWERTOOLS_LOGGER_LOG_EVENT": "false", "POWERTOOLS_SERVICE_NAME": "chatbot", @@ -3364,10 +3505,14 @@ schema { "EndpointName", ], }, + "SECRETS_MANAGER_TIMEOUT_MILLIS": "0", + "SECRETS_MANAGER_TTL": "300", "SESSIONS_BY_USER_ID_INDEX_NAME": "byUserId", "SESSIONS_TABLE_NAME": { "Ref": "ChatBotApiConstructChatDynamoDBTablesSessionsTableD81EF9A7", }, + "SSM_PARAMETER_STORE_TIMEOUT_MILLIS": "0", + "SSM_PARAMETER_STORE_TTL": "300", "UPLOAD_BUCKET_NAME": { "Ref": "RagEnginesDataImportUploadBucket061D697E", }, @@ -3407,6 +3552,15 @@ schema { { "Ref": "SharedCommonLayerFC89CBCE", }, + { + "Fn::FindInMap": [ + "ParamsandsecretslayerMap", + { + "Ref": "AWS::Region", + }, + "1x0x103xx86x64", + ], + }, ], "LoggingConfig": { "LogFormat": "JSON", @@ -3529,6 +3683,26 @@ schema { "Properties": { "PolicyDocument": { "Statement": [ + { + "Action": "ssm:GetParameter", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":parameter/prefix/GraphQLApiHandler/*", + ], + ], + }, + }, { "Action": [ "dynamodb:BatchGetItem",