Skip to content

Instantly share code, notes, and snippets.

@recursivecodes
Created June 15, 2023 14:10
Show Gist options
  • Select an option

  • Save recursivecodes/296abd02411a3dc017d31c414672085a to your computer and use it in GitHub Desktop.

Select an option

Save recursivecodes/296abd02411a3dc017d31c414672085a to your computer and use it in GitHub Desktop.
import * as cdk from 'aws-cdk-lib';
import { LambdaRestApi } from 'aws-cdk-lib/aws-apigateway';
import { Rule } from 'aws-cdk-lib/aws-events';
import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets';
import { Effect, PolicyStatement, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
import { Architecture, Code, Function, LayerVersion, Runtime } from 'aws-cdk-lib/aws-lambda';
import { ApiEventSource } from 'aws-cdk-lib/aws-lambda-event-sources';
import { Construct } from 'constructs';
export class IvsRekognitionCdkStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const lambdaLayer = new LayerVersion(this, 'LambdaLayer', {
layerVersionName: 'ApiLayer',
compatibleRuntimes: [
Runtime.NODEJS_18_X,
],
code: Code.fromAsset('./resources/dependencies/nodejs'),
});
const streamModerationHandler = new Function(this, 'StreamModerationHandler', {
runtime: Runtime.NODEJS_18_X,
code: Code.fromAsset('resources'),
handler: 'index.moderateImage',
layers: [lambdaLayer],
environment: {
DEMO_CHAT_ARN: '',
DEMO_CHANNEL_ARN: '',
},
architecture: Architecture.ARM_64,
timeout: cdk.Duration.seconds(5),
});
// allow moderation handler lambda to invoke s3, ivs, and rekognition APIs
const streamModerationHandlerPolicy = new PolicyStatement({
effect: Effect.ALLOW,
resources: ['*'],
actions: [
's3:GetObject',
's3:GetObjectAcl',
'ivschat:SendEvent',
'ivs:StopStream',
'rekognition:DetectModerationLabels',
'rekognition:DetectLabels'
],
});
streamModerationHandler.addToRolePolicy(streamModerationHandlerPolicy);
// lambda function to stop an ivs stream
const stopStreamHandler = new Function(this, 'StopStreamHandler', {
runtime: Runtime.NODEJS_18_X,
code: Code.fromAsset('resources'),
handler: 'index.stopStream',
environment: {
DEMO_CHAT_ARN: '',
DEMO_CHANNEL_ARN: '',
},
layers: [lambdaLayer],
architecture: Architecture.ARM_64,
timeout: cdk.Duration.seconds(5),
});
stopStreamHandler.addEventSource(new ApiEventSource('GET', '/stop-stream'));
// allow stop stream lambda to invoke ivs APIs
const stopStreamHandlerPolicy = new PolicyStatement({
effect: Effect.ALLOW,
resources: ['*'],
actions: [
'ivs:StopStream',
],
});
stopStreamHandler.addToRolePolicy(stopStreamHandlerPolicy);
// expose stop stream handler via API gateway
const stopStreamApi = new LambdaRestApi(this, 'StopStreamApiEndpoint', {
handler: stopStreamHandler,
defaultCorsPreflightOptions: {
allowOrigins: ['*'],
allowHeaders: ['Content-Type'],
allowMethods: ['GET'],
maxAge: cdk.Duration.seconds(600),
}
});
// api access policy
const apiAccessPolicy = new PolicyStatement({
effect: Effect.ALLOW,
resources: ['*'],
actions: [
'sts:AssumeRole'
]
});
streamModerationHandler.addToRolePolicy(apiAccessPolicy);
// EventBridge rule to listen for new thumbnails created in S3
const objectCreatedRule = new Rule(this, 'ObjectCreatedRule', {
description: 'Rule to handle new thumbnails recorded from an Amazon IVS stream',
ruleName: 'ivs-thumbnail-needs-moderation',
eventPattern: {
source: ['aws.s3'],
detailType: ['Object Created'],
detail: {
bucket: {
name: ['ivs-demo-channel-stream-archive']
},
object: {
key: [{ suffix: '.jpg' }]
}
}
},
targets: [new LambdaFunction(streamModerationHandler)],
});
// permission for event rule to invoke lambda
streamModerationHandler.addPermission('PermitStreamModerationInvoke', {
principal: new ServicePrincipal('events.amazonaws.com'),
sourceArn: objectCreatedRule.ruleArn,
});
// output url for stop stream handler
new cdk.CfnOutput(this, 'StopStreamHandlerUrl', {
description: 'The URL to invoke the stop stream handler',
value: stopStreamApi.url,
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment