imbusy/infra/backend.ts

95 lines
2.6 KiB
TypeScript

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}`;