diff --git a/packages/@aws-cdk/integ-tests/README.md b/packages/@aws-cdk/integ-tests/README.md index 17e3419c286ca..b27610cbd531f 100644 --- a/packages/@aws-cdk/integ-tests/README.md +++ b/packages/@aws-cdk/integ-tests/README.md @@ -264,6 +264,34 @@ integ.assertions.awsApiCall('SQS', 'receiveMessage', { }); ``` +By default, the `AwsApiCall` construct will automatically add the correct IAM policies +to allow the Lambda function to make the API call. It does this based on the `service` +and `api` that is provided. In the above example the service is `SQS` and the api is +`receiveMessage` so it will create a policy with `Action: 'sqs:ReceiveMessage`. + +There are some cases where the permissions do not exactly match the service/api call, for +example the S3 `listObjectsV2` api. In these cases it is possible to add the correct policy +by accessing the `provider` object. + +```ts +declare const app: App; +declare const stack: Stack; +declare const integ: IntegTest; + +const apiCall = integ.assertions.awsApiCall('S3', 'listObjectsV2', { + Bucket: 'mybucket', +}); + +apiCall.provider.addToRolePolicy({ + Effect: 'Allow', + Action: ['s3:GetObject', 's3:ListBucket'], + Resource: ['*'], +}); +``` + +Note that addToRolePolicy() uses direct IAM JSON policy blobs, not a iam.PolicyStatement +object like you will see in the rest of the CDK. + ### EqualsAssertion This library currently provides the ability to assert that two values are equal diff --git a/packages/@aws-cdk/integ-tests/lib/assertions/providers/provider.ts b/packages/@aws-cdk/integ-tests/lib/assertions/providers/provider.ts index 1b4c64e963646..5a5e3378fa4fa 100644 --- a/packages/@aws-cdk/integ-tests/lib/assertions/providers/provider.ts +++ b/packages/@aws-cdk/integ-tests/lib/assertions/providers/provider.ts @@ -134,6 +134,24 @@ class SingletonFunction extends Construct { return new LambdaFunctionProvider(Stack.of(this), constructName); } + /** + * Add an IAM policy statement to the inline policy of the + * lambdas function's role + * + * **Please note**: this is a direct IAM JSON policy blob, *not* a `iam.PolicyStatement` + * object like you will see in the rest of the CDK. + * + * + * singleton.addToRolePolicy({ + * Effect: 'Allow', + * Action: 's3:GetObject', + * Resources: '*', + * }); + */ + public addToRolePolicy(statement: any): void { + this.policies.push(statement); + } + /** * Create a policy statement from a specific api call */ @@ -216,6 +234,26 @@ export class AssertionsProvider extends Construct { public addPolicyStatementFromSdkCall(service: string, api: string, resources?: string[]): void { this.handler.addPolicyStatementFromSdkCall(service, api, resources); } + + /** + * Add an IAM policy statement to the inline policy of the + * lambdas function's role + * + * **Please note**: this is a direct IAM JSON policy blob, *not* a `iam.PolicyStatement` + * object like you will see in the rest of the CDK. + * + * + * @example + * declare const provider: AssertionsProvider; + * provider.addToRolePolicy({ + * Effect: 'Allow', + * Action: 's3:GetObject', + * Resources: '*', + * }); + */ + public addToRolePolicy(statement: any): void { + this.handler.addToRolePolicy(statement); + } } function slugify(x: string): string { diff --git a/packages/@aws-cdk/integ-tests/lib/assertions/sdk.ts b/packages/@aws-cdk/integ-tests/lib/assertions/sdk.ts index a7322738fa8d9..97972e4c568ba 100644 --- a/packages/@aws-cdk/integ-tests/lib/assertions/sdk.ts +++ b/packages/@aws-cdk/integ-tests/lib/assertions/sdk.ts @@ -9,6 +9,20 @@ import { AssertionsProvider, SDK_RESOURCE_TYPE_PREFIX } from './providers'; * an API call using the AWS SDK */ export interface IAwsApiCall extends IConstruct { + /** + * access the AssertionsProvider. This can be used to add additional IAM policies + * the the provider role policy + * + * @example + * declare const apiCall: AwsApiCall; + * apiCall.provider.addToRolePolicy({ + * Effect: 'Allow', + * Action: ['s3:GetObject'], + * Resource: ['*'], + * }); + */ + readonly provider: AssertionsProvider; + /** * Returns the value of an attribute of the custom resource of an arbitrary * type. Attributes are returned from the custom resource provider through the @@ -110,7 +124,7 @@ export class AwsApiCall extends Construct implements IAwsApiCall { private flattenResponse: string = 'false'; private readonly name: string; - protected provider: AssertionsProvider; + public readonly provider: AssertionsProvider; constructor(scope: Construct, id: string, props: AwsApiCallProps) { super(scope, id); diff --git a/packages/@aws-cdk/integ-tests/rosetta/default.ts-fixture b/packages/@aws-cdk/integ-tests/rosetta/default.ts-fixture index 847ddd48128e2..7cf368abcf6db 100644 --- a/packages/@aws-cdk/integ-tests/rosetta/default.ts-fixture +++ b/packages/@aws-cdk/integ-tests/rosetta/default.ts-fixture @@ -11,6 +11,7 @@ import { AssertionType, LambdaInvokeFunction, Match, + AssertionsProvider, } from '@aws-cdk/integ-tests'; import { Construct } from 'constructs'; import { diff --git a/packages/@aws-cdk/integ-tests/test/assertions/sdk.test.ts b/packages/@aws-cdk/integ-tests/test/assertions/sdk.test.ts index d8d3d70ec1694..7be64290b1b01 100644 --- a/packages/@aws-cdk/integ-tests/test/assertions/sdk.test.ts +++ b/packages/@aws-cdk/integ-tests/test/assertions/sdk.test.ts @@ -44,6 +44,55 @@ describe('AwsApiCall', () => { param2: 2, }, }); + + }); + + test('add policy to provider', () => { + // GIVEN + const app = new App(); + const deplossert = new DeployAssert(app); + + // WHEN + const apiCall = deplossert.awsApiCall('MyService', 'MyApi', { + param1: 'val1', + param2: 2, + }); + apiCall.provider.addToRolePolicy({ + Effect: 'Allow', + Action: ['s3:GetObject'], + Resource: ['*'], + }); + + Template.fromStack(deplossert.scope).hasResourceProperties('AWS::IAM::Role', { + Policies: [ + { + PolicyName: 'Inline', + PolicyDocument: { + Version: '2012-10-17', + Statement: [ + { + Action: [ + 'myservice:MyApi', + ], + Effect: 'Allow', + Resource: [ + '*', + ], + }, + { + Action: [ + 's3:GetObject', + ], + Effect: 'Allow', + Resource: [ + '*', + ], + }, + ], + }, + }, + ], + }); }); describe('get attribute', () => {