in packages/constructs/L3/ai/gaia-l3-construct/lib/rag-engines/kendra-retrieval/index.ts [29:201]
constructor(scope: Construct, id: string, props: KendraRetrievalProps) {
super(scope, id, props);
const createWorkflow = new CreateKendraWorkspace(this, 'CreateKendraWorkspace', {
...props,
config: props.config,
shared: props.shared,
ragDynamoDBTables: props.ragDynamoDBTables,
});
if (props.config.rag?.engines.kendra?.createIndex) {
const indexName = props.naming.resourceName('gaiachatbot-workspaces');
const customDataSource = props.config.rag?.engines.kendra?.s3DataSourceConfig;
let dataBucket: s3.IBucket;
if (customDataSource !== undefined) {
dataBucket = s3.Bucket.fromBucketName(this, 'CustomKedraDataBucket', customDataSource.bucketName);
} else {
dataBucket = new MdaaBucket(this, 'KendraDataBucket', {
encryptionKey: props.encryptionKey,
naming: props.naming,
bucketName: `${props.naming.props.org}-${props.naming.props.domain}-${props.naming.props.env}-kendra-default-source-bucket`,
});
}
MdaaNagSuppressions.addCodeResourceSuppressions(
dataBucket,
[
{ id: 'NIST.800.53.R5-S3BucketReplicationEnabled', reason: 'MDAA does not enforce bucket replication.' },
{ id: 'HIPAA.Security-S3BucketReplicationEnabled', reason: 'MDAA does not enforce bucket replication.' },
{ id: 'PCI.DSS.321-S3BucketReplicationEnabled', reason: 'MDAA does not enforce bucket replication.' },
],
true,
);
const kendraRole = new MdaaRole(this, 'KendraRole', {
naming: props.naming,
assumedBy: new iam.ServicePrincipal('kendra.amazonaws.com'),
roleName: 'KendraRole',
});
kendraRole.addToPolicy(
new iam.PolicyStatement({
actions: ['logs:*', 'cloudwatch:*'],
resources: [`arn:aws:logs:${this.region}:${this.account}:log-group:/aws/kendra/*`],
}),
);
dataBucket.grantRead(kendraRole);
const kendraIndex = new kendra.CfnIndex(this, 'Index', {
edition: 'DEVELOPER_EDITION',
name: indexName,
roleArn: kendraRole.roleArn,
serverSideEncryptionConfiguration: {
kmsKeyId: props.encryptionKey.keyId,
},
documentMetadataConfigurations: [
{
name: 'workspace_id',
type: 'STRING_VALUE',
search: {
displayable: true,
facetable: true,
searchable: true,
},
},
{
name: 'document_type',
type: 'STRING_VALUE',
search: {
displayable: true,
facetable: true,
searchable: true,
},
},
],
});
let s3DataSource: kendra.CfnDataSource;
if (customDataSource !== undefined) {
s3DataSource = new kendra.CfnDataSource(this, 'CustomKendraS3DataSource', {
type: 'S3',
name: 'CustomKendraS3DataSource',
indexId: kendraIndex.ref,
description: `S3 Data Source for Kendra Index for bucket ${customDataSource.bucketName}`,
dataSourceConfiguration: {
s3Configuration: {
bucketName: customDataSource.bucketName,
inclusionPrefixes: customDataSource.includedDirectories,
documentsMetadataConfiguration: {
s3Prefix:
customDataSource?.metadataDirectory !== undefined ? customDataSource.metadataDirectory : 'metadata',
},
},
},
roleArn: kendraRole.roleArn,
});
kendraRole.addToPolicy(
new iam.PolicyStatement({
actions: ['kms:Decrypt', 'kms:GenerateDataKey', 'kms:DescribeKey'],
resources: [customDataSource.kmsKeyArn],
}),
);
} else {
s3DataSource = new kendra.CfnDataSource(this, 'DefaultKendraS3DataSource', {
type: 'S3',
name: 'DefaultKendraS3DataSource',
indexId: kendraIndex.ref,
description: 'S3 Data Source for Kendra Index',
dataSourceConfiguration: {
s3Configuration: {
bucketName: dataBucket.bucketName,
inclusionPrefixes: ['documents'],
documentsMetadataConfiguration: {
s3Prefix: 'metadata',
},
},
},
roleArn: kendraRole.roleArn,
});
}
kendraRole.addToPolicy(
new iam.PolicyStatement({
actions: ['kendra:BatchDeleteDocument'],
resources: [kendraIndex.attrArn, s3DataSource.attrArn],
}),
);
MdaaNagSuppressions.addCodeResourceSuppressions(
kendraRole,
[
{
id: 'AwsSolutions-IAM5',
reason:
'DDB index names not known at deployment time. KMS Permissions are appropriately scoped. S3 Bucket managed and dedicated to Kendra index',
},
{
id: 'NIST.800.53.R5-IAMNoInlinePolicy',
reason: 'Permissions are role specific. Inline policy use appropriate.',
},
{
id: 'HIPAA.Security-IAMNoInlinePolicy',
reason: 'Permissions are role specific. Inline policy use appropriate.',
},
{
id: 'PCI.DSS.321-IAMNoInlinePolicy',
reason: 'Permissions are role specific. Inline policy use appropriate.',
},
{
id: 'NIST.800.53.R5-IAMPolicyNoStatementsWithFullAccess',
reason: 'Permission bound by cloudwatch namespace. Other policies further restrict log group access',
},
{
id: 'HIPAA.Security-IAMPolicyNoStatementsWithFullAccess',
reason: 'Permission bound by cloudwatch namespace. Other policies further restrict log group access',
},
{
id: 'PCI.DSS.321-IAMPolicyNoStatementsWithFullAccess',
reason: 'Permission bound by cloudwatch namespace. Other policies further restrict log group access',
},
],
true,
);
this.kendraIndex = kendraIndex;
this.kendraS3DataSource = s3DataSource;
this.kendraS3DataSourceBucket = dataBucket;
}
this.createKendraWorkspaceWorkflow = createWorkflow.stateMachine;
}