import { Construct , CfnOutput } from '@aws-cdk/core' ; import { PolicyStatement , Effect } from '@aws-cdk/aws-iam' ; import { Function } from '@aws-cdk/aws-lambda' ; import { Table } from '@aws-cdk/aws-dynamodb' ; import WebCrawlerLambda from './web-crawler-lambda' ; import { KendraInfrastructureProps } from '../../stacks/web-crawler-stack' ; import ChromeLambdaLayer from './chrome-lambda-layer' ; export interface WebCrawlerStepLambdasProps { region : string ; contextTableNamePrefix : string ; createContextTablePolicy : ( actions : string [ ] ) => PolicyStatement ; kendra ? : KendraInfrastructureProps ; historyTable : Table ; webCrawlerStateMachineArn : string ; } export interface WebCrawlerSteps { startCrawl : Function ; crawlPageAndQueueUrls : Function ; readQueuedUrls : Function ; completeCrawl : Function ; continueExecution : Function ; } /**
 * Construct which creates all the necessary lambdas for our web crawler
 */ export default class WebCrawlerStepLambdas extends Construct { public readonly steps : WebCrawlerSteps ; constructor ( scope , id , props ) { super ( scope , id ) ; const { region } = props ; const environment = { CONTEXT_TABLE_NAME_PREFIX : props . contextTableNamePrefix , HISTORY_TABLE_NAME : props . historyTable . tableName , ... ( props . kendra ? { DATA_SOURCE_BUCKET_NAME : props . kendra . dataSourceBucket . bucketName , KENDRA_INDEX_ID : props . kendra . kendraIndex . attrId , KENDRA_DATA_SOURCE_ID : props . kendra . kendraDataSource . attrId , } : { } ) , } ; const chromeLayer = new ChromeLambdaLayer ( this , 'ChromeLayer' ) ; const buildLambda = ( id , handler ) => new WebCrawlerLambda ( this , id , { handler , environment , region , chromeLayer , } ) ; const startCrawl = buildLambda ( 'StartCrawlingLambda' , 'startCrawlHandler' ) ; props . historyTable . grantReadWriteData ( startCrawl ) ; startCrawl . addToRolePolicy ( props . createContextTablePolicy ( [ 'CreateTable' , 'DescribeTable' , 'PutItem' , 'GetItem' ] ) ) ; const crawlPageAndQueueUrls = buildLambda ( 'CrawlPageAndQueueUrlsLambda' , 'crawlPageAndQueueUrlsHandler' ) ; props . kendra && props . kendra . dataSourceBucket . grantWrite ( crawlPageAndQueueUrls ) ; crawlPageAndQueueUrls . addToRolePolicy ( props . createContextTablePolicy ( [ 'PutItem' , 'GetItem' , 'DeleteItem' ] ) ) ; const readQueuedUrls = buildLambda ( 'ReadQueuedUrlsLambda' , 'readQueuedUrlsHandler' ) ; props . historyTable . grantReadWriteData ( readQueuedUrls ) ; readQueuedUrls . addToRolePolicy ( props . createContextTablePolicy ( [ 'Query' ] ) ) ; const completeCrawl = buildLambda ( 'CompleteCrawlLambda' , 'completeCrawlHandler' ) ; props . historyTable . grantReadWriteData ( completeCrawl ) ; completeCrawl . addToRolePolicy ( props . createContextTablePolicy ( [ 'DeleteTable' ] ) ) ; props . kendra && completeCrawl . addToRolePolicy ( new PolicyStatement ( { effect : Effect . ALLOW , actions : [ 'kendra:StartDataSourceSyncJob' ] , resources : [ props . kendra . kendraIndex . attrArn , `${ props . kendra . kendraIndex . attrArn }/data-source/*` ] , } ) ) ; const continueExecution = buildLambda ( 'ContinueExecutionLambda' , 'continueExecutionHandler' ) ; continueExecution . addToRolePolicy ( new PolicyStatement ( { effect : Effect . ALLOW , actions : [ 'states:StartExecution' ] , resources : [ props . webCrawlerStateMachineArn ] , } ) ) ; props . historyTable . grantReadWriteData ( continueExecution ) ; this . steps = { startCrawl , crawlPageAndQueueUrls , readQueuedUrls , completeCrawl , continueExecution , } ; new CfnOutput ( this , 'StartCrawlFunctionArn' , { exportName : 'StartCrawlFunctionArn' , value : startCrawl . functionArn , } ) ; } }