From 93efb207ecf76d76b7e6bc67464583d2956699a9 Mon Sep 17 00:00:00 2001 From: Rafael Mosca Date: Tue, 15 Oct 2024 22:18:14 +0200 Subject: [PATCH] chore(bedrock): update bedrock --- .../namespaces/bedrock/classes/Guardrail.md | 20 +++ .../bedrock/classes/GuardrailBase.md | 20 +++ .../bedrock/interfaces/IGuardrail.md | 16 ++ src/cdk-lib/bedrock/guardrails/guardrails.ts | 16 ++ test/cdk-lib/bedrock/agent.test.ts | 139 +++++------------- 5 files changed, 107 insertions(+), 104 deletions(-) diff --git a/apidocs/namespaces/bedrock/classes/Guardrail.md b/apidocs/namespaces/bedrock/classes/Guardrail.md index cdd0b862..385f96a3 100644 --- a/apidocs/namespaces/bedrock/classes/Guardrail.md +++ b/apidocs/namespaces/bedrock/classes/Guardrail.md @@ -513,6 +513,26 @@ Commonly this is the resource's `ref`. *** +### grantApply() + +> **grantApply**(`grantee`): `Grant` + +Grant the given identity permissions to apply the guardrail. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` + +#### Inherited from + +[`GuardrailBase`](GuardrailBase.md).[`grantApply`](GuardrailBase.md#grantapply) + +*** + ### toString() > **toString**(): `string` diff --git a/apidocs/namespaces/bedrock/classes/GuardrailBase.md b/apidocs/namespaces/bedrock/classes/GuardrailBase.md index dc20ea04..bdb81341 100644 --- a/apidocs/namespaces/bedrock/classes/GuardrailBase.md +++ b/apidocs/namespaces/bedrock/classes/GuardrailBase.md @@ -273,6 +273,26 @@ Commonly this is the resource's `ref`. *** +### grantApply() + +> **grantApply**(`grantee`): `Grant` + +Grant the given identity permissions to apply the guardrail. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` + +#### Implementation of + +[`IGuardrail`](../interfaces/IGuardrail.md).[`grantApply`](../interfaces/IGuardrail.md#grantapply) + +*** + ### toString() > **toString**(): `string` diff --git a/apidocs/namespaces/bedrock/interfaces/IGuardrail.md b/apidocs/namespaces/bedrock/interfaces/IGuardrail.md index 35fb3c3d..aeaeefa7 100644 --- a/apidocs/namespaces/bedrock/interfaces/IGuardrail.md +++ b/apidocs/namespaces/bedrock/interfaces/IGuardrail.md @@ -109,3 +109,19 @@ account for data recovery and cleanup later (`RemovalPolicy.RETAIN`). #### Inherited from `IResource.applyRemovalPolicy` + +*** + +### grantApply() + +> **grantApply**(`grantee`): `Grant` + +Grant the given identity permissions to apply the guardrail. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` diff --git a/src/cdk-lib/bedrock/guardrails/guardrails.ts b/src/cdk-lib/bedrock/guardrails/guardrails.ts index c92dee05..db92e4fe 100644 --- a/src/cdk-lib/bedrock/guardrails/guardrails.ts +++ b/src/cdk-lib/bedrock/guardrails/guardrails.ts @@ -14,6 +14,7 @@ import * as fs from 'fs'; import { Arn, ArnFormat, IResolvable, IResource, Lazy, Resource, Stack } from 'aws-cdk-lib'; import * as bedrock from 'aws-cdk-lib/aws-bedrock'; +import * as iam from 'aws-cdk-lib/aws-iam'; import { IKey } from 'aws-cdk-lib/aws-kms'; import { md5hash } from 'aws-cdk-lib/core/lib/helpers-internal'; import { Construct } from 'constructs'; @@ -36,6 +37,10 @@ export interface IGuardrail extends IResource { * @example "yympzo398ipq" */ readonly guardrailId: string; + /** + * Grant the given identity permissions to apply the guardrail. + */ + grantApply(grantee: iam.IGrantable): iam.Grant; } /** @@ -51,6 +56,17 @@ export abstract class GuardrailBase extends Resource implements IGuardrail { * The ID of the guardrail. */ public abstract readonly guardrailId: string; + /** + * Grant the given identity permissions to apply the guardrail. + */ + public grantApply(grantee: iam.IGrantable): iam.Grant { + return iam.Grant.addToPrincipal({ + grantee, + resourceArns: [this.guardrailArn], + actions: ['bedrock:ApplyGuardrail'], + scope: this, + }); + } } /****************************************************************************** diff --git a/test/cdk-lib/bedrock/agent.test.ts b/test/cdk-lib/bedrock/agent.test.ts index c3c98016..6bde743c 100644 --- a/test/cdk-lib/bedrock/agent.test.ts +++ b/test/cdk-lib/bedrock/agent.test.ts @@ -13,6 +13,7 @@ import * as cdk from 'aws-cdk-lib'; import { Annotations, Match, Template } from 'aws-cdk-lib/assertions'; +import { Key } from 'aws-cdk-lib/aws-kms'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as s3 from 'aws-cdk-lib/aws-s3'; import { NagSuppressions } from 'cdk-nag'; @@ -133,19 +134,21 @@ describe('Agent with guardrails through addGuardrail', () => { name: 'my-custom-guardrail', blockedInputMessaging: 'Blocked input message', blockedOutputsMessaging: 'Blocked output message', - filtersConfig: [ + contentFilters: [ { - filtersConfigType: bedrock.FiltersConfigType.HATE, - inputStrength: bedrock.FiltersConfigStrength.HIGH, - outputStrength: bedrock.FiltersConfigStrength.HIGH, + type: bedrock.ContentFilterType.HATE, + inputStrength: bedrock.ContentFilterStrength.HIGH, + outputStrength: bedrock.ContentFilterStrength.HIGH, }, ], - kmsKeyArn: 'arn:aws:kms:region:XXXXX:key/12345678-1234-1234-1234-123456789012', + kmsKey: Key.fromKeyArn( + stack, + 'imported-key', + 'arn:aws:kms:region:XXXXX:key/12345678-1234-1234-1234-123456789012', + ), }); agent.addGuardrail(guardrail); - - }); test('Knowledge Base is created', () => { @@ -165,23 +168,16 @@ describe('Agent with guardrails through addGuardrail', () => { Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { Name: 'test-docs', KnowledgeBaseId: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('^KB'), - 'KnowledgeBaseId', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('^KB'), 'KnowledgeBaseId'], }, DataSourceConfiguration: { Type: 'S3', S3Configuration: { BucketArn: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('^DocBucket'), - 'Arn', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('^DocBucket'), 'Arn'], }, }, }, - }); }); @@ -222,14 +218,10 @@ describe('Agent with guardrails through addGuardrail', () => { }, GuardrailConfiguration: { GuardrailIdentifier: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('MyGuardrail'), 'GuardrailId', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('MyGuardrail'), 'GuardrailId'], }, GuardrailVersion: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('MyGuardrail'), 'Version', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('MyGuardrail'), 'Version'], }, }, }); @@ -244,9 +236,7 @@ describe('Agent with guardrails through addGuardrail', () => { }, Name: Match.stringLikeRegexp('KBteststack'), RoleArn: { - 'Fn::GetAtt': - [Match.stringLikeRegexp('KBRole'), 'Arn'], - + 'Fn::GetAtt': [Match.stringLikeRegexp('KBRole'), 'Arn'], }, Description: 'Documentation about CDK constructs.', @@ -256,7 +246,6 @@ describe('Agent with guardrails through addGuardrail', () => { test('Agent action group and ApiSchema from S3', () => { const template = Template.fromStack(stack); template.hasResourceProperties('AWS::Bedrock::Agent', { - ActionGroups: [ { ActionGroupName: 'UserInputAction', @@ -267,9 +256,7 @@ describe('Agent with guardrails through addGuardrail', () => { { ActionGroupExecutor: { Lambda: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('ActionGroupFunction'), 'Arn', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('ActionGroupFunction'), 'Arn'], }, }, ActionGroupName: 'test-action-group', @@ -285,7 +272,6 @@ describe('Agent with guardrails through addGuardrail', () => { }, ], }); - }); test('Guardrail is associated', () => { @@ -305,33 +291,22 @@ describe('Agent with guardrails through addGuardrail', () => { }, KmsKeyArn: 'arn:aws:kms:region:XXXXX:key/12345678-1234-1234-1234-123456789012', Name: 'my-custom-guardrail', - }, - ); - + }); }); test('Agent Alias is created', () => { Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::AgentAlias', { AgentId: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('^Agent'), - 'AgentId', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('^Agent'), 'AgentId'], }, AgentAliasName: 'prod', }); }); - test('No unsuppressed Errors', () => { - const errors = Annotations.fromStack(stack).findError( - '*', - Match.stringLikeRegexp('AwsSolutions-.*'), - ); + const errors = Annotations.fromStack(stack).findError('*', Match.stringLikeRegexp('AwsSolutions-.*')); expect(errors).toHaveLength(0); }); - - }); describe('Agent with guardrails through constructor', () => { @@ -433,7 +408,6 @@ describe('Agent with guardrails through constructor', () => { }); agent.addActionGroups([actiongroup]); - }); test('Knowledge Base is created', () => { @@ -453,23 +427,16 @@ describe('Agent with guardrails through constructor', () => { Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { Name: 'test-docs', KnowledgeBaseId: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('^KB'), - 'KnowledgeBaseId', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('^KB'), 'KnowledgeBaseId'], }, DataSourceConfiguration: { Type: 'S3', S3Configuration: { BucketArn: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('^DocBucket'), - 'Arn', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('^DocBucket'), 'Arn'], }, }, }, - }); }); @@ -520,9 +487,7 @@ describe('Agent with guardrails through constructor', () => { }, Name: Match.stringLikeRegexp('KBteststack'), RoleArn: { - 'Fn::GetAtt': - [Match.stringLikeRegexp('KBRole'), 'Arn'], - + 'Fn::GetAtt': [Match.stringLikeRegexp('KBRole'), 'Arn'], }, Description: 'Documentation about CDK constructs.', @@ -532,7 +497,6 @@ describe('Agent with guardrails through constructor', () => { test('Agent action group and ApiSchema from S3', () => { const template = Template.fromStack(stack); template.hasResourceProperties('AWS::Bedrock::Agent', { - ActionGroups: [ { ActionGroupName: 'UserInputAction', @@ -543,9 +507,7 @@ describe('Agent with guardrails through constructor', () => { { ActionGroupExecutor: { Lambda: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('ActionGroupFunction'), 'Arn', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('ActionGroupFunction'), 'Arn'], }, }, ActionGroupName: 'test-action-group', @@ -561,7 +523,6 @@ describe('Agent with guardrails through constructor', () => { }, ], }); - }); test('Guardrail is associated', () => { @@ -572,33 +533,22 @@ describe('Agent with guardrails through constructor', () => { GuardrailIdentifier: 'testId', GuardrailVersion: 'version1', }, - }, - ); - + }); }); test('Agent Alias is created', () => { Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::AgentAlias', { AgentId: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('^Agent'), - 'AgentId', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('^Agent'), 'AgentId'], }, AgentAliasName: 'prod', }); }); - test('No unsuppressed Errors', () => { - const errors = Annotations.fromStack(stack).findError( - '*', - Match.stringLikeRegexp('AwsSolutions-.*'), - ); + const errors = Annotations.fromStack(stack).findError('*', Match.stringLikeRegexp('AwsSolutions-.*')); expect(errors).toHaveLength(0); }); - - }); describe('Agent without guardrails', () => { @@ -696,7 +646,6 @@ describe('Agent without guardrails', () => { }); agent.addActionGroups([actiongroup]); - }); test('Knowledge Base is created', () => { @@ -716,23 +665,16 @@ describe('Agent without guardrails', () => { Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { Name: 'test-docs', KnowledgeBaseId: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('^KB'), - 'KnowledgeBaseId', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('^KB'), 'KnowledgeBaseId'], }, DataSourceConfiguration: { Type: 'S3', S3Configuration: { BucketArn: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('^DocBucket'), - 'Arn', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('^DocBucket'), 'Arn'], }, }, }, - }); }); @@ -783,9 +725,7 @@ describe('Agent without guardrails', () => { }, Name: Match.stringLikeRegexp('KBteststack'), RoleArn: { - 'Fn::GetAtt': - [Match.stringLikeRegexp('KBRole'), 'Arn'], - + 'Fn::GetAtt': [Match.stringLikeRegexp('KBRole'), 'Arn'], }, Description: 'Documentation about CDK constructs.', @@ -795,7 +735,6 @@ describe('Agent without guardrails', () => { test('Agent action group and ApiSchema from S3', () => { const template = Template.fromStack(stack); template.hasResourceProperties('AWS::Bedrock::Agent', { - ActionGroups: [ { ActionGroupName: 'UserInputAction', @@ -806,9 +745,7 @@ describe('Agent without guardrails', () => { { ActionGroupExecutor: { Lambda: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('ActionGroupFunction'), 'Arn', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('ActionGroupFunction'), 'Arn'], }, }, ActionGroupName: 'test-action-group', @@ -824,7 +761,6 @@ describe('Agent without guardrails', () => { }, ], }); - }); test('Guardrail should not be associated', () => { @@ -835,21 +771,14 @@ describe('Agent without guardrails', () => { test('Agent Alias is created', () => { Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::AgentAlias', { AgentId: { - 'Fn::GetAtt': [ - Match.stringLikeRegexp('^Agent'), - 'AgentId', - ], + 'Fn::GetAtt': [Match.stringLikeRegexp('^Agent'), 'AgentId'], }, AgentAliasName: 'prod', }); }); - test('No unsuppressed Errors', () => { - const errors = Annotations.fromStack(stack).findError( - '*', - Match.stringLikeRegexp('AwsSolutions-.*'), - ); + const errors = Annotations.fromStack(stack).findError('*', Match.stringLikeRegexp('AwsSolutions-.*')); expect(errors).toHaveLength(0); }); }); @@ -865,7 +794,9 @@ describe('Imports', () => { test('Agent Alias Import', () => { // GIVEN - const agentAlias = bedrock.AgentAlias.fromAliasArn(stack, 'alias', + const agentAlias = bedrock.AgentAlias.fromAliasArn( + stack, + 'alias', 'arn:aws:bedrock:us-east-1:123456789012:agent-alias/DNCJJYQKSU/TCLCITFZTN', );