import { Construct } from 'constructs'; import * as ecs from 'aws-cdk-lib/aws-ecs'; import * as ecr_assets from 'aws-cdk-lib/aws-ecr-assets'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as logs from 'aws-cdk-lib/aws-logs'; import * as path from 'path'; export interface SocketModeProps { vpc: ec2.IVpc; processorLambda: lambda.IFunction; appHomeLambda: lambda.IFunction; } export class SocketModeConstruct extends Construct { constructor(scope: Construct, id: string, props: SocketModeProps) { super(scope, id); const appTokenSecret = secretsmanager.Secret.fromSecretNameV2( this, 'AppTokenSecret', 'seahaven/slack/app-level-token', ); const cluster = new ecs.Cluster(this, 'Cluster', { clusterName: 'seahaven-socket-mode', vpc: props.vpc, }); const taskDef = new ecs.FargateTaskDefinition(this, 'TaskDef', { memoryLimitMiB: 512, cpu: 256, runtimePlatform: { cpuArchitecture: ecs.CpuArchitecture.ARM64, operatingSystemFamily: ecs.OperatingSystemFamily.LINUX, }, }); taskDef.addContainer('socket-mode', { image: ecs.ContainerImage.fromAsset( path.join(__dirname, '../../services/socket-mode'), { platform: ecr_assets.Platform.LINUX_ARM64 }, ), environment: { APP_TOKEN_SECRET_ARN: appTokenSecret.secretArn, PROCESSOR_FUNCTION_NAME: props.processorLambda.functionName, APP_HOME_FUNCTION_NAME: props.appHomeLambda.functionName, }, logging: ecs.LogDrivers.awsLogs({ streamPrefix: 'socket-mode', logRetention: logs.RetentionDays.TWO_MONTHS, }), }); appTokenSecret.grantRead(taskDef.taskRole); props.processorLambda.grantInvoke(taskDef.taskRole); props.appHomeLambda.grantInvoke(taskDef.taskRole); new ecs.FargateService(this, 'Service', { serviceName: 'seahaven-socket-mode', cluster, taskDefinition: taskDef, desiredCount: 1, minHealthyPercent: 100, maxHealthyPercent: 200, assignPublicIp: false, vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }, }); } }