Skip to content

Commit

Permalink
feat(aws-s3): do not poll by default in the CodePipeline source Action.
Browse files Browse the repository at this point in the history
  • Loading branch information
skinny85 committed Nov 29, 2018
1 parent 825e448 commit d9f060e
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 6 deletions.
37 changes: 37 additions & 0 deletions packages/@aws-cdk/aws-s3/lib/bucket.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import actions = require('@aws-cdk/aws-codepipeline-api');
import events = require('@aws-cdk/aws-events');
import iam = require('@aws-cdk/aws-iam');
import kms = require('@aws-cdk/aws-kms');
import { IBucketNotificationDestination } from '@aws-cdk/aws-s3-notifications';
Expand Down Expand Up @@ -131,6 +132,42 @@ export abstract class BucketRef extends cdk.Construct {
});
}

/**
* Defines a CloudWatch Event Rule that triggers upon putting an object into the Bucket.
*
* @param name the logical ID of the newly created Event Rule
* @param target the target of the Event Rule
* @param path the optional path inside the Bucket that will be watched for changes
* @returns a new {@link events.EventRule} instance
*/
public onObjectPut(name: string, target?: events.IEventRuleTarget, path?: string): events.EventRule {
const eventRule = new events.EventRule(this, name, {
eventPattern: {
source: [
'aws.s3',
],
detailType: [
'AWS API Call via CloudTrail',
],
detail: {
eventSource: [
's3.amazonaws.com',
],
eventName: [
'PutObject',
],
resources: {
ARN: [
path ? this.arnForObjects(path) : this.bucketArn,
],
},
},
},
});
eventRule.addTarget(target);
return eventRule;
}

/**
* Adds a statement to the resource policy for a principal (i.e.
* account/role/service) to perform actions on this bucket and/or it's
Expand Down
13 changes: 9 additions & 4 deletions packages/@aws-cdk/aws-s3/lib/pipeline-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ export interface CommonPipelineSourceActionProps extends codepipeline.CommonActi
*/
bucketKey: string;

// TODO: use CloudWatch events instead
/**
* Whether or not AWS CodePipeline should poll for source changes
* Whether AWS CodePipeline should poll for source changes.
* If this is `false`, the Pipeline will use CloudWatch Events to detect source changes instead.
*
* @default true
* @default false
*/
pollForSourceChanges?: boolean;
}
Expand All @@ -53,11 +53,16 @@ export class PipelineSourceAction extends codepipeline.SourceAction {
configuration: {
S3Bucket: props.bucket.bucketName,
S3ObjectKey: props.bucketKey,
PollForSourceChanges: props.pollForSourceChanges || true
PollForSourceChanges: props.pollForSourceChanges || false,
},
...props,
});

if (!props.pollForSourceChanges) {
props.bucket.onObjectPut(props.stage.pipeline.uniqueId + 'SourceEventRule',
props.stage.pipeline, props.bucketKey);
}

// pipeline needs permissions to read from the S3 bucket
props.bucket.grantRead(props.stage.pipeline.role);
}
Expand Down
4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-s3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
},
"dependencies": {
"@aws-cdk/aws-codepipeline-api": "^0.18.1",
"@aws-cdk/aws-events": "^0.18.1",
"@aws-cdk/aws-iam": "^0.18.1",
"@aws-cdk/aws-kms": "^0.18.1",
"@aws-cdk/aws-s3-notifications": "^0.18.1",
Expand All @@ -68,9 +69,10 @@
"homepage": "https://github.com/awslabs/aws-cdk",
"peerDependencies": {
"@aws-cdk/aws-codepipeline-api": "^0.18.1",
"@aws-cdk/aws-events": "^0.18.1",
"@aws-cdk/aws-iam": "^0.18.1",
"@aws-cdk/aws-kms": "^0.18.1",
"@aws-cdk/aws-s3-notifications": "^0.18.1",
"@aws-cdk/cdk": "^0.18.1"
}
}
}
47 changes: 46 additions & 1 deletion packages/@aws-cdk/aws-s3/test/test.notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,5 +298,50 @@ export = {
});

test.done();
}
},

'CloudWatch Events': {
'onPutItem contains the Bucket ARN itself when path is undefined'(test: Test) {
const stack = new cdk.Stack();
const bucket = s3.BucketRef.import(stack, 'Bucket', {
bucketName: 'MyBucket',
});
bucket.onObjectPut('PutRule');

expect(stack).to(haveResource('AWS::Events::Rule', {
"EventPattern": {
"source": [
"aws.s3",
],
"detail": {
"eventSource": [
"s3.amazonaws.com",
],
"eventName": [
"PutObject",
],
"resources": {
"ARN": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition",
},
":s3:::MyBucket",
],
],
},
],
},
},
},
"State": "ENABLED",
}));

test.done();
},
},
};

0 comments on commit d9f060e

Please sign in to comment.