constructor()

in infra/resources/api.ts [42:238]


    constructor(scope: Construct, id: string, props: EKYCApiConstructProps) {
        super(scope, id);

        const backendFn = new lambda.Function(this, "ekyc-proxy-handler", {
            runtime: lambda.Runtime.DOTNET_CORE_3_1,
            handler: "ekyc-api::ekyc_api.LambdaEntryPoint::FunctionHandlerAsync",
            code: lambda.Code.fromAsset(
                "../packages/ekyc-api/src/ekyc-api/bin/Debug/netcoreapp3.1"
            ),
            timeout: Duration.seconds(30),
            memorySize: 1024,
            environment: {
                StorageBucket: props.storageBucket.bucketName,
                SessionTable: props.sessionsTable.tableName,
                VerificationHistoryTable: props.verificationHistoryTable.tableName,
                AWSAccount: Stack.of(this).account,
                AWSRegion: Stack.of(this).region,
                CognitoPoolId: props.cognitoUserPool.userPoolId,
                CognitoAppClientId: props.cognitoAppClient.userPoolClientId,
                DataRequestsTable: props.dataRequestsTable.tableName,
                ApprovalsSnsTopic: props.approvalsTopic.topicArn,
                RekognitionCustomLabelsProjectVersionArnParameterName:props.RekognitionCustomLabelsProjectVersionArnParameter.parameterName,
                RekognitionCustomLabelsProjectArnParameterName:props.RekognitionCustomLabelsProjectArnParameter.parameterName,
                UseFieldCoordinatesExtractionMethodParameterName: props.useFieldCoordinatesExtractionMethodParameter.parameterName,
                OriginDistributionDomain: props.jsCloudFrontDistribution.distributionDomainName,
                TrainingBucket: props.trainingBucket.bucketName,
                TrainingTableName: props.trainingTable.tableName,
                GroundTruthRoleArn: props.groundTruthRole.roleArn,
                GroundTruthWorkTeam: `arn:aws:sagemaker:${Stack.of(this).region}:${Stack.of(this).account}:workteam/private-crowd/${props.workTeam.workteamName}`,
                GroundTruthUiTemplateS3Uri: `s3://${props.trainingBucket.bucketName}/template/labellers.html`,
            },
            tracing: Tracing.ACTIVE
        });

        const lambdaRole = backendFn.role;

        backendFn.grantInvoke(new ServicePrincipal("apigateway.amazonaws.com"));

        if (lambdaRole) {


            permissionUtils.addDynamoDbPermissions(props.sessionsTable,lambdaRole)

            permissionUtils.addDynamoDbPermissions(props.verificationHistoryTable,lambdaRole)

            permissionUtils.addDynamoDbPermissions(props.trainingTable,lambdaRole)

            permissionUtils.addDynamoDbPermissions(props.dataRequestsTable,lambdaRole)

            permissionUtils.addDynamoDbPermissions(props.dataRequestsTable,lambdaRole)

            props.storageBucket.grantReadWrite(lambdaRole);

            props.trainingBucket.grantReadWrite(lambdaRole);

            lambdaRole?.addToPrincipalPolicy(
                new PolicyStatement({
                    resources: [props.approvalsTopic.topicArn],
                    actions: ["sns:Publish"],
                })
            );

            /*lambdaRole?.addToPrincipalPolicy(
                new PolicyStatement({
                    resources: ["*"],
                    actions: ["lambda:InvokeFunction"],
                })
            );*/

            lambdaRole?.addToPrincipalPolicy(
                new PolicyStatement({
                    resources: [
                        `arn:aws:ssm:${Stack.of(this).region}:${
                            Stack.of(this).account
                        }:parameter/CFN-parametersekyc*`
                    ],
                    actions: [
                        "ssm:GetParameter",
                        "ssm:DescribeParameters",
                        "ssm:GetParameters",
                        "ssm:GetParametersByPath",
                    ],
                })
            );

            lambdaRole.addManagedPolicy(
                ManagedPolicy.fromAwsManagedPolicyName(
                    "service-role/AWSLambdaBasicExecutionRole"
                )
            );

            lambdaRole.addManagedPolicy(
                ManagedPolicy.fromAwsManagedPolicyName("AmazonSageMakerFullAccess")
            )

            lambdaRole.addManagedPolicy(
                ManagedPolicy.fromAwsManagedPolicyName("AmazonRekognitionFullAccess")
            );

            lambdaRole.addManagedPolicy(
                ManagedPolicy.fromAwsManagedPolicyName("AmazonTextractFullAccess")
            );

            lambdaRole.addManagedPolicy(
                ManagedPolicy.fromAwsManagedPolicyName("AWSXrayFullAccess")
            );
        }

        const nodeId = this.node.addr;

        const auth = new apigateway.CognitoUserPoolsAuthorizer(
            this,
            "ekycAuthorizer",
            {
                cognitoUserPools: [props.cognitoUserPool],
                identitySource: "method.request.header.Authorization",
            }
        );

        this.api = new apigateway.LambdaRestApi(this, `ekyc-data-api-${nodeId}`, {
            handler: backendFn,
            defaultCorsPreflightOptions: {
                allowOrigins: apigateway.Cors.ALL_ORIGINS,
                allowMethods: apigateway.Cors.ALL_METHODS,
                allowCredentials: true,
                allowHeaders: [
                    "Content-Type",
                    "X-Amz-Date",
                    "Authorization",
                    "X-Api-Key",
                    "X-Amz-Security-Token",
                    "X-Amz-User-Agent",
                ],
                statusCode:200
            },
            apiKeySourceType: ApiKeySourceType.HEADER,
            defaultMethodOptions: {
                apiKeyRequired: false,
                authorizer: auth,
                authorizationType: AuthorizationType.COGNITO,
            },
            endpointTypes: [apigateway.EndpointType.REGIONAL],
            proxy: true,
            deployOptions: {
                loggingLevel: apigateway.MethodLoggingLevel.INFO,
                dataTraceEnabled: true,
            },
        });

        // This workaround needed to avoid CORS preflight requests being blocked by the authorizer
        this.api.methods
            .filter((method) => method.httpMethod === "OPTIONS")
            .forEach((method) => {
                const methodCfn = method.node.defaultChild as apigateway.CfnMethod;
                methodCfn.authorizationType = apigateway.AuthorizationType.NONE;
                methodCfn.authorizerId = undefined;
            });

        const deployment = new apigateway.Deployment(this, "ekyc-api-deployment", {
            api: this.api,
        });

        const stages = ["dev", "test", "uat"].map(
            (item) =>
                new apigateway.Stage(this, `${item}_stage`, {
                    deployment,
                    stageName: item,
                })
        );

        const [devStage, testStage, uatStage] = stages;

        this.api.deploymentStage = uatStage;

        new CfnOutput(this, "Data-API", {
            value: this.api.restApiId,
            description: "Data-API ID",
            exportName: "DataAPIId",
        });

       
        const apiArn = Arn.format(
            {
                resource: "apis",
                service: "apigateway",
                resourceName: this.api.restApiId,
            },
            Stack.of(this)
        );

        console.log(`Api ARN: ${apiArn}`);

        // Create the WAF
        this.createWAF(this.api.node.addr);

        stages.map((item) => this.addWAFtoStage(this.api, item));
    }