aws-genai-llm-chatbot
147 строк · 4.9 Кб
1import * as path from "path";
2import * as cdk from "aws-cdk-lib";
3import { Construct } from "constructs";
4import { SystemConfig } from "../../shared/types";
5import { Shared } from "../../shared";
6import { RagDynamoDBTables } from "../rag-dynamodb-tables";
7import * as sfn from "aws-cdk-lib/aws-stepfunctions";
8import * as tasks from "aws-cdk-lib/aws-stepfunctions-tasks";
9import * as lambda from "aws-cdk-lib/aws-lambda";
10import * as logs from "aws-cdk-lib/aws-logs";
11import * as rds from "aws-cdk-lib/aws-rds";
12import { RemovalPolicy } from "aws-cdk-lib";
13
14export interface CreateAuroraWorkspaceProps {
15readonly config: SystemConfig;
16readonly shared: Shared;
17readonly ragDynamoDBTables: RagDynamoDBTables;
18readonly dbCluster: rds.DatabaseCluster;
19}
20
21export class CreateAuroraWorkspace extends Construct {
22public readonly stateMachine: sfn.StateMachine;
23
24constructor(scope: Construct, id: string, props: CreateAuroraWorkspaceProps) {
25super(scope, id);
26
27const createFunction = new lambda.Function(
28this,
29"CreateAuroraWorkspaceFunction",
30{
31vpc: props.shared.vpc,
32code: props.shared.sharedCode.bundleWithLambdaAsset(
33path.join(__dirname, "./functions/create-workflow/create")
34),
35runtime: props.shared.pythonRuntime,
36architecture: props.shared.lambdaArchitecture,
37handler: "index.lambda_handler",
38layers: [props.shared.powerToolsLayer, props.shared.commonLayer],
39timeout: cdk.Duration.minutes(5),
40logRetention: logs.RetentionDays.ONE_WEEK,
41environment: {
42...props.shared.defaultEnvironmentVariables,
43AURORA_DB_SECRET_ID: props.dbCluster.secret?.secretArn as string,
44WORKSPACES_TABLE_NAME:
45props.ragDynamoDBTables.workspacesTable.tableName,
46WORKSPACES_BY_OBJECT_TYPE_INDEX_NAME:
47props.ragDynamoDBTables.workspacesByObjectTypeIndexName,
48},
49}
50);
51
52props.dbCluster.secret?.grantRead(createFunction);
53props.dbCluster.connections.allowDefaultPortFrom(createFunction);
54props.ragDynamoDBTables.workspacesTable.grantReadWriteData(createFunction);
55
56const handleError = new tasks.DynamoUpdateItem(this, "HandleError", {
57table: props.ragDynamoDBTables.workspacesTable,
58key: {
59workspace_id: tasks.DynamoAttributeValue.fromString(
60sfn.JsonPath.stringAt("$.workspace_id")
61),
62object_type: tasks.DynamoAttributeValue.fromString("workspace"),
63},
64updateExpression: "set #status = :error",
65expressionAttributeNames: {
66"#status": "status",
67},
68expressionAttributeValues: {
69":error": tasks.DynamoAttributeValue.fromString("error"),
70},
71}).next(
72new sfn.Fail(this, "Fail", {
73cause: "Workspace creation failed",
74})
75);
76
77const setCreating = new tasks.DynamoUpdateItem(this, "SetCreating", {
78table: props.ragDynamoDBTables.workspacesTable,
79key: {
80workspace_id: tasks.DynamoAttributeValue.fromString(
81sfn.JsonPath.stringAt("$.workspace_id")
82),
83object_type: tasks.DynamoAttributeValue.fromString("workspace"),
84},
85updateExpression: "set #status=:statusValue",
86expressionAttributeNames: {
87"#status": "status",
88},
89expressionAttributeValues: {
90":statusValue": tasks.DynamoAttributeValue.fromString("creating"),
91},
92resultPath: sfn.JsonPath.DISCARD,
93});
94
95const setReady = new tasks.DynamoUpdateItem(this, "SetReady", {
96table: props.ragDynamoDBTables.workspacesTable,
97key: {
98workspace_id: tasks.DynamoAttributeValue.fromString(
99sfn.JsonPath.stringAt("$.workspace_id")
100),
101object_type: tasks.DynamoAttributeValue.fromString("workspace"),
102},
103updateExpression: "set #status=:statusValue",
104expressionAttributeNames: {
105"#status": "status",
106},
107expressionAttributeValues: {
108":statusValue": tasks.DynamoAttributeValue.fromString("ready"),
109},
110resultPath: sfn.JsonPath.DISCARD,
111});
112
113const createTask = new tasks.LambdaInvoke(this, "Create", {
114lambdaFunction: createFunction,
115resultPath: "$.createResult",
116}).addCatch(handleError, {
117errors: ["States.ALL"],
118resultPath: "$.createResult",
119});
120
121const workflow = setCreating
122.next(createTask)
123.next(setReady)
124.next(new sfn.Succeed(this, "Success"));
125
126const logGroup = new logs.LogGroup(
127this,
128"CreateAuroraWorkspaceSMLogGroup",
129{
130removalPolicy: RemovalPolicy.DESTROY,
131}
132);
133
134const stateMachine = new sfn.StateMachine(this, "CreateAuroraWorkspace", {
135definitionBody: sfn.DefinitionBody.fromChainable(workflow),
136timeout: cdk.Duration.minutes(5),
137comment: "Create Aurora Workspace Workflow",
138tracingEnabled: true,
139logs: {
140destination: logGroup,
141level: sfn.LogLevel.ALL,
142},
143});
144
145this.stateMachine = stateMachine;
146}
147}
148