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