Skip to content
This repository was archived by the owner on Oct 25, 2023. It is now read-only.
5 changes: 4 additions & 1 deletion deployment/document-understanding-solution.template
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,10 @@ Resources:
"iam:Get*",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:CreateServiceLinkedRole"
"iam:DeleteRolePolicy",
"iam:DetachRolePolicy",
"iam:CreateServiceLinkedRole",
"iam:DeleteServiceLinkedRole"
]
},
{
Expand Down
58 changes: 50 additions & 8 deletions source/lib/cdk-textract-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import { QueueEncryption } from "@aws-cdk/aws-sqs";
import { LogGroup } from "@aws-cdk/aws-logs";
import { LogGroupLogDestination } from "@aws-cdk/aws-apigateway";

const API_CONCURRENT_REQUESTS = 20; //approximate number of 1-2 page documents to be processed parallelly
const API_CONCURRENT_REQUESTS = 20; //approximate number of 1-2 page documents to be processed in parallell

export interface TextractStackProps {
email: string;
Expand Down Expand Up @@ -171,12 +171,14 @@ export class CdkTextractStack extends cdk.Stack {
behaviors: [{ isDefaultBehavior: true }],
},
],
errorConfigurations: [{
errorCode: 404,
responseCode: 200,
errorCachingMinTtl: 5,
responsePagePath: '/index.html'
}],
errorConfigurations: [
{
errorCode: 404,
responseCode: 200,
errorCachingMinTtl: 5,
responsePagePath: "/index.html",
},
],
priceClass: PriceClass.PRICE_CLASS_100,
httpVersion: HttpVersion.HTTP2,
enableIpV6: true,
Expand Down Expand Up @@ -324,12 +326,39 @@ export class CdkTextractStack extends cdk.Stack {
elasticSearch.node.addDependency(serviceLinkedRole);
}

const jobResultsKey = new kms.Key(
this,
this.resourceName("JobResultsKey"),
{
enableKeyRotation: true,
enabled: true,
trustAccountIdentities: true,
policy: new iam.PolicyDocument({
assignSids: true,
statements: [
new iam.PolicyStatement({
actions: ["kms:GenerateDataKey*", "kms:Decrypt"],
resources: ["*"], // Resource level permissions are not necessary in this policy statement, as it is automatically restricted to this key
effect: iam.Effect.ALLOW,
principals: [
new iam.ServicePrincipal("sns.amazonaws.com"),
new iam.ServicePrincipal("lambda.amazonaws.com"),
new iam.ServicePrincipal("textract.amazonaws.com"),
new iam.ServicePrincipal("sqs.amazonaws.com"),
],
}),
],
}),
}
);

// SNS Topic
const jobCompletionTopic = new sns.Topic(
this,
this.resourceName("JobCompletion"),
this.resourceName("JobCompletionTopic"),
{
displayName: "Job completion topic",
masterKey: jobResultsKey,
}
);

Expand All @@ -349,6 +378,13 @@ export class CdkTextractStack extends cdk.Stack {
resources: [jobCompletionTopic.topicArn],
})
);
textractServiceRole.addToPolicy(
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["kms:Decrypt", "kms:GenerateDataKey*"],
resources: [jobResultsKey.keyArn],
})
);

// DynamoDB tables
const outputTable = new ddb.Table(this, this.resourceName("OutputTable"), {
Expand Down Expand Up @@ -440,6 +476,7 @@ export class CdkTextractStack extends cdk.Stack {
{
visibilityTimeout: cdk.Duration.seconds(900),
retentionPeriod: cdk.Duration.seconds(1209600),
encryption: QueueEncryption.KMS_MANAGED,
}
);

Expand All @@ -449,12 +486,16 @@ export class CdkTextractStack extends cdk.Stack {
{
visibilityTimeout: cdk.Duration.seconds(900),
retentionPeriod: cdk.Duration.seconds(1209600),
encryption: QueueEncryption.KMS,
encryptionMasterKey: jobResultsKey,
dataKeyReuse: cdk.Duration.seconds(86400),
deadLetterQueue: {
maxReceiveCount: 3,
queue: jobResultsDLQueue,
},
}
);

// trigger
jobCompletionTopic.addSubscription(
new snsSubscriptions.SqsSubscription(jobResultsQueue)
Expand Down Expand Up @@ -874,6 +915,7 @@ export class CdkTextractStack extends cdk.Stack {
jobResultProcessor.addLayers(textractorLayer);
jobResultProcessor.addLayers(boto3Layer);
jobResultProcessor.addLayers(elasticSearchLayer);
jobResultsKey.grantEncryptDecrypt(jobResultProcessor);

// Triggers
jobResultProcessor.addEventSource(
Expand Down