import * as aws from "@pulumi/aws"; import * as esbuild from "esbuild"; import * as pulumi from "@pulumi/pulumi"; import * as common from "./common"; const tags = common.tags; const prefix = `${common.prefix}-backend`; console.log("building backend..."); esbuild.buildSync({ entryPoints: ["../backend/src/index.ts"], outfile: "../backend/dist/index.js", bundle: true, platform: "node", target: "node18", minify: true, }); // ---- Lambda ---- const lambdaRole = new aws.iam.Role(`${prefix}-lambda-role`, { tags, assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({ Service: "lambda.amazonaws.com", }), }); new aws.iam.RolePolicyAttachment(`${prefix}-lambda-role-exec`, { role: lambdaRole.name, policyArn: aws.iam.ManagedPolicies.AWSLambdaBasicExecutionRole, }); const lambda = new aws.lambda.Function(`${prefix}-lambda`, { tags, runtime: "nodejs18.x", handler: "index.main", role: lambdaRole.arn, code: new pulumi.asset.AssetArchive({ ".": new pulumi.asset.FileArchive("../backend/dist/"), }), }); new aws.cloudwatch.LogGroup(`${prefix}-lambda-log-group`, { name: pulumi.interpolate`/aws/lambda/${lambda.name}`, retentionInDays: 7, }); // ---- API Gateway ---- const api = new aws.apigatewayv2.Api(`${prefix}-api`, { tags, protocolType: "WEBSOCKET", routeSelectionExpression: "$request.body.action", }); const integration = new aws.apigatewayv2.Integration(`${prefix}-api-integ-lambda`, { apiId: api.id, integrationType: "AWS_PROXY", integrationUri: pulumi.interpolate`arn:aws:apigateway:${aws.config.region}:lambda:path/2015-03-31/functions/${lambda.arn}/invocations`, integrationMethod: "POST", }); ["$connect", "$disconnect", "$default"].map( routeKey => new aws.apigatewayv2.Route(`${prefix}-api-route-${routeKey}`, { apiId: api.id, routeKey, target: pulumi.interpolate`integrations/${integration.id}`, })); new aws.apigatewayv2.Stage(`${prefix}-api-stage-v1`, { tags, apiId: api.id, name: "v1", autoDeploy: true, }); new aws.lambda.Permission(`${prefix}-api-permission`, { action: "lambda:InvokeFunction", function: lambda.name, principal: "apigateway.amazonaws.com", sourceArn: pulumi.interpolate`${api.executionArn}/*/*`, }); new aws.iam.RolePolicy(`${prefix}-api-role-policy`, { role: lambdaRole.id, policy: pulumi.interpolate`{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": "execute-api:ManageConnections", "Resource": "arn:aws:execute-api:*:*:*/*/@connections/*" }] }`, }); export const endpoint = pulumi.interpolate`${api.apiEndpoint}`;