Skip to content

Commit 836fa5f

Browse files
authored
Merge branch 'master' into c9-repo-support
2 parents 6f8f1a4 + dfdcd90 commit 836fa5f

File tree

18 files changed

+500
-100
lines changed

18 files changed

+500
-100
lines changed

packages/@aws-cdk/assets/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
"devDependencies": {
6666
"@aws-cdk/assert": "0.0.0",
6767
"@types/nodeunit": "^0.0.31",
68-
"@types/sinon": "^9.0.3",
68+
"@types/sinon": "^9.0.4",
6969
"aws-cdk": "0.0.0",
7070
"cdk-build-tools": "0.0.0",
7171
"cdk-integ-tools": "0.0.0",

packages/@aws-cdk/aws-cloudtrail/README.md

+125-63
Original file line numberDiff line numberDiff line change
@@ -13,101 +13,82 @@
1313
---
1414
<!--END STABILITY BANNER-->
1515

16-
Add a CloudTrail construct - for ease of setting up CloudTrail logging in your account
16+
## Trail
1717

18-
Example usage:
18+
AWS CloudTrail enables governance, compliance, and operational and risk auditing of your AWS account. Actions taken by
19+
a user, role, or an AWS service are recorded as events in CloudTrail. Learn more at the [CloudTrail
20+
documentation](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html).
1921

20-
```ts
21-
import * as cloudtrail from '@aws-cdk/aws-cloudtrail';
22+
The `Trail` construct enables ongoing delivery of events as log files to an Amazon S3 bucket. Learn more about [Creating
23+
a Trail for Your AWS Account](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-create-and-update-a-trail.html).
24+
The following code creates a simple CloudTrail for your account -
2225

26+
```ts
2327
const trail = new cloudtrail.Trail(this, 'CloudTrail');
2428
```
2529

26-
You can instantiate the CloudTrail construct with no arguments - this will by default:
30+
By default, this will create a new S3 Bucket that CloudTrail will write to, and choose a few other reasonable defaults
31+
such as turning on multi-region and global service events.
32+
The defaults for each property and how to override them are all documented on the `TrailProps` interface.
2733

28-
* Create a new S3 Bucket and associated Policy that allows CloudTrail to write to it
29-
* Create a CloudTrail with the following configuration:
30-
* Logging Enabled
31-
* Log file validation enabled
32-
* Multi Region set to true
33-
* Global Service Events set to true
34-
* The created S3 bucket
35-
* CloudWatch Logging Disabled
36-
* No SNS configuartion
37-
* No tags
38-
* No fixed name
34+
## Log File Validation
3935

40-
You can override any of these properties using the `CloudTrailProps` configuraiton object.
36+
In order to validate that the CloudTrail log file was not modified after CloudTrail delivered it, CloudTrail provides a
37+
digital signature for each file. Learn more at [Validating CloudTrail Log File
38+
Integrity](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-intro.html).
4139

42-
For example, to log to CloudWatch Logs
40+
This is enabled on the `Trail` construct by default, but can be turned off by setting `enableFileValidation` to `false`.
4341

4442
```ts
45-
46-
import * as cloudtrail from '@aws-cdk/aws-cloudtrail';
47-
4843
const trail = new cloudtrail.Trail(this, 'CloudTrail', {
49-
sendToCloudWatchLogs: true
44+
enableFileValidation: false,
5045
});
5146
```
5247

53-
This creates the same setup as above - but also logs events to a created CloudWatch Log stream.
54-
By default, the created log group has a retention period of 365 Days, but this is also configurable
55-
via the `cloudWatchLogsRetention` property. If you would like to specify the log group explicitly,
56-
use the `cloudwatchLogGroup` property.
48+
## Notifications
5749

58-
For using CloudTrail event selector to log specific S3 events,
59-
you can use the `CloudTrailProps` configuration object.
60-
Example:
50+
Amazon SNS notifications can be configured upon new log files containing Trail events are delivered to S3.
51+
Learn more at [Configuring Amazon SNS Notifications for
52+
CloudTrail](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/configure-sns-notifications-for-cloudtrail.html).
53+
The following code configures an SNS topic to be notified -
6154

6255
```ts
63-
import * as cloudtrail from '@aws-cdk/aws-cloudtrail';
56+
const topic = new sns.Topic(this, 'TrailTopic');
57+
const trail = new cloudtrail.Trail(this, 'CloudTrail', {
58+
snsTopic: topic,
59+
});
60+
```
6461

65-
const trail = new cloudtrail.Trail(this, 'MyAmazingCloudTrail');
62+
## Service Integrations
6663

67-
// Adds an event selector to the bucket magic-bucket.
68-
// By default, this includes management events and all operations (Read + Write)
69-
trail.logAllS3DataEvents();
64+
Besides sending trail events to S3, they can also be configured to notify other AWS services -
7065

71-
// Adds an event selector to the bucket foo
72-
trail.addS3EventSelector([{
73-
bucket: fooBucket // 'fooBucket' is of type s3.IBucket
74-
}]);
75-
```
66+
### Amazon CloudWatch Logs
7667

77-
For using CloudTrail event selector to log events about Lambda
78-
functions, you can use `addLambdaEventSelector`.
68+
CloudTrail events can be delivered to a CloudWatch Logs LogGroup. By default, a new LogGroup is created with a
69+
default retention setting. The following code enables sending CloudWatch logs but specifies a particular retention
70+
period for the created Log Group.
7971

8072
```ts
81-
import * as cloudtrail from '@aws-cdk/aws-cloudtrail';
82-
import * as lambda from '@aws-cdk/aws-lambda';
83-
84-
const trail = new cloudtrail.Trail(this, 'MyAmazingCloudTrail');
85-
const lambdaFunction = new lambda.Function(stack, 'AnAmazingFunction', {
86-
runtime: lambda.Runtime.NODEJS_10_X,
87-
handler: "hello.handler",
88-
code: lambda.Code.fromAsset("lambda"),
73+
const trail = new cloudtrail.Trail(this, 'CloudTrail', {
74+
sendToCloudWatchLogs: true,
75+
cloudWatchLogsRetention: logs.RetentionDays.FOUR_MONTHS,
8976
});
77+
```
9078

91-
// Add an event selector to log data events for all functions in the account.
92-
trail.logAllLambdaDataEvents();
79+
If you would like to use a specific log group instead, this can be configured via `cloudwatchLogGroup`.
9380

94-
// Add an event selector to log data events for the provided Lambda functions.
95-
trail.addLambdaEventSelector([lambdaFunction.functionArn]);
96-
```
81+
### Amazon EventBridge
9782

98-
Using the `Trail.onEvent()` API, an EventBridge rule can be created that gets triggered for
99-
every event logged in CloudTrail.
100-
To only use the events that are of interest, either from a particular service, specific account or
101-
time range, they can be filtered down using the APIs available in `aws-events`. The following code
102-
filters events for S3 from a specific AWS account and triggers a lambda function. See [Events delivered via
83+
Amazon EventBridge rules can be configured to be triggered when CloudTrail events occur using the `Trail.onEvent()` API.
84+
Using APIs available in `aws-events`, these events can be filtered to match to those that are of interest, either from
85+
a specific service, account or time range. See [Events delivered via
10386
CloudTrail](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html#events-for-services-not-listed)
10487
to learn more about the event structure for events from CloudTrail.
10588

106-
```ts
107-
import * as cloudtrail from '@aws-cdk/aws-cloudtrail';
108-
import * as eventTargets from '@aws-cdk/aws-events-targets';
109-
import * as lambda from '@aws-cdk/aws-lambda';
89+
The following code filters events for S3 from a specific AWS account and triggers a lambda function.
11090

91+
```ts
11192
const myFunctionHandler = new lambda.Function(this, 'MyFunction', {
11293
code: lambda.Code.fromAsset('resource/myfunction');
11394
runtime: lambda.Runtime.NODEJS_12_X,
@@ -123,3 +104,84 @@ eventRule.addEventPattern({
123104
source: 'aws.s3',
124105
});
125106
```
107+
108+
## Multi-Region & Global Service Events
109+
110+
By default, a `Trail` is configured to deliver log files from multiple regions to a single S3 bucket for a given
111+
account. This creates shadow trails (replication of the trails) in all of the other regions. Learn more about [How
112+
CloudTrail Behaves Regionally](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-regional-and-global-services)
113+
and about the [`IsMultiRegion`
114+
property](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudtrail-trail.html#cfn-cloudtrail-trail-ismultiregiontrail).
115+
116+
For most services, events are recorded in the region where the action occurred. For global services such as AWS IAM,
117+
AWS STS, Amazon CloudFront, Route 53, etc., events are delivered to any trail that includes global services. Learn more
118+
[About Global Service Events](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-global-service-events).
119+
120+
Events for global services are turned on by default for `Trail` constructs in the CDK.
121+
122+
The following code disables multi-region trail delivery and trail delivery for global services for a specific `Trail` -
123+
124+
```ts
125+
const trail = new cloudtrail.Trail(this, 'CloudTrail', {
126+
// ...
127+
isMultiRegionTrail: false,
128+
includeGlobalServiceEvents: false,
129+
});
130+
```
131+
132+
## Events Types
133+
134+
**Management events** provide information about management operations that are performed on resources in your AWS
135+
account. These are also known as control plane operations. Learn more about [Management
136+
Events](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-events).
137+
138+
By default, a `Trail` logs all management events. However, they can be configured to either be turned off, or to only
139+
log 'Read' or 'Write' events.
140+
141+
The following code configures the `Trail` to only track management events that are of type 'Read'.
142+
143+
```ts
144+
const trail = new cloudtrail.Trail(this, 'CloudTrail', {
145+
// ...
146+
managementEvents: ReadWriteType.READ_ONLY,
147+
});
148+
```
149+
150+
**Data events** provide information about the resource operations performed on or in a resource. These are also known
151+
as data plane operations. Learn more about [Data
152+
Events](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-events).
153+
By default, no data events are logged for a `Trail`.
154+
155+
AWS CloudTrail supports data event logging for Amazon S3 objects and AWS Lambda functions.
156+
157+
The `logAllS3DataEvents()` API configures the trail to log all S3 data events while the `addS3EventSelector()` API can
158+
be used to configure logging of S3 data events for specific buckets and specific object prefix. The following code
159+
configures logging of S3 data events for `fooBucket` and with object prefix `bar/`.
160+
161+
```ts
162+
import * as cloudtrail from '@aws-cdk/aws-cloudtrail';
163+
164+
const trail = new cloudtrail.Trail(this, 'MyAmazingCloudTrail');
165+
166+
// Adds an event selector to the bucket foo
167+
trail.addS3EventSelector([{
168+
bucket: fooBucket, // 'fooBucket' is of type s3.IBucket
169+
objectPrefix: 'bar/',
170+
}]);
171+
```
172+
173+
Similarly, the `logAllLambdaDataEvents()` configures the trail to log all Lambda data events while the
174+
`addLambdaEventSelector()` API can be used to configure logging for specific Lambda functions. The following code
175+
configures logging of Lambda data events for a specific Function.
176+
177+
```ts
178+
const trail = new cloudtrail.Trail(this, 'MyAmazingCloudTrail');
179+
const amazingFunction = new lambda.Function(stack, 'AnAmazingFunction', {
180+
runtime: lambda.Runtime.NODEJS_10_X,
181+
handler: "hello.handler",
182+
code: lambda.Code.fromAsset("lambda"),
183+
});
184+
185+
// Add an event selector to log data events for the provided Lambda functions.
186+
trail.addLambdaEventSelector([ lambdaFunction ]);
187+
```

packages/@aws-cdk/aws-cloudtrail/lib/cloudtrail.ts

+18-6
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export interface TrailProps {
4141
*
4242
* @param managementEvents the management configuration type to log
4343
*
44-
* @default - Management events will not be logged.
44+
* @default ReadWriteType.ALL
4545
*/
4646
readonly managementEvents?: ReadWriteType;
4747

@@ -131,7 +131,12 @@ export enum ReadWriteType {
131131
/**
132132
* All events
133133
*/
134-
ALL = 'All'
134+
ALL = 'All',
135+
136+
/**
137+
* No events
138+
*/
139+
NONE = 'None',
135140
}
136141

137142
/**
@@ -235,10 +240,17 @@ export class Trail extends Resource {
235240
}
236241

237242
if (props.managementEvents) {
238-
const managementEvent = {
239-
includeManagementEvents: true,
240-
readWriteType: props.managementEvents,
241-
};
243+
let managementEvent;
244+
if (props.managementEvents === ReadWriteType.NONE) {
245+
managementEvent = {
246+
includeManagementEvents: false,
247+
};
248+
} else {
249+
managementEvent = {
250+
includeManagementEvents: true,
251+
readWriteType: props.managementEvents,
252+
};
253+
}
242254
this.eventSelectors.push(managementEvent);
243255
}
244256

packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts

+16
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,22 @@ describe('cloudtrail', () => {
397397
],
398398
});
399399
});
400+
401+
test('managementEvents set to None correctly turns off management events', () => {
402+
const stack = getTestStack();
403+
404+
new Trail(stack, 'MyAmazingCloudTrail', {
405+
managementEvents: ReadWriteType.NONE,
406+
});
407+
408+
expect(stack).toHaveResourceLike('AWS::CloudTrail::Trail', {
409+
EventSelectors: [
410+
{
411+
IncludeManagementEvents: false,
412+
},
413+
],
414+
});
415+
});
400416
});
401417
});
402418

packages/@aws-cdk/aws-events-targets/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Currently supported are:
2222
* Start a StepFunctions state machine
2323
* Queue a Batch job
2424
* Make an AWS API call
25+
* Put a record to a Kinesis stream
2526

2627
See the README of the `@aws-cdk/aws-events` library for more information on
2728
CloudWatch Events.

packages/@aws-cdk/aws-events-targets/lib/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export * from './lambda';
88
export * from './ecs-task-properties';
99
export * from './ecs-task';
1010
export * from './state-machine';
11+
export * from './kinesis-stream';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import * as events from '@aws-cdk/aws-events';
2+
import * as iam from '@aws-cdk/aws-iam';
3+
import * as kinesis from '@aws-cdk/aws-kinesis';
4+
import { singletonEventRole } from './util';
5+
6+
/**
7+
* Customize the Kinesis Stream Event Target
8+
*/
9+
export interface KinesisStreamProps {
10+
/**
11+
* Partition Key Path for records sent to this stream
12+
*
13+
* @default - eventId as the partition key
14+
*/
15+
readonly partitionKeyPath?: string;
16+
17+
/**
18+
* The message to send to the stream.
19+
*
20+
* Must be a valid JSON text passed to the target stream.
21+
*
22+
* @default - the entire CloudWatch event
23+
*/
24+
readonly message?: events.RuleTargetInput;
25+
26+
}
27+
28+
/**
29+
* Use a Kinesis Stream as a target for AWS CloudWatch event rules.
30+
*
31+
* @example
32+
*
33+
* // put to a Kinesis stream every time code is committed
34+
* // to a CodeCommit repository
35+
* repository.onCommit(new targets.KinesisStream(stream));
36+
*
37+
*/
38+
export class KinesisStream implements events.IRuleTarget {
39+
40+
constructor(private readonly stream: kinesis.IStream, private readonly props: KinesisStreamProps = {}) {
41+
}
42+
43+
/**
44+
* Returns a RuleTarget that can be used to trigger this Kinesis Stream as a
45+
* result from a CloudWatch event.
46+
*/
47+
public bind(_rule: events.IRule, _id?: string): events.RuleTargetConfig {
48+
const policyStatements = [new iam.PolicyStatement({
49+
actions: ['kinesis:PutRecord', 'kinesis:PutRecords'],
50+
resources: [this.stream.streamArn],
51+
})];
52+
53+
return {
54+
id: '',
55+
arn: this.stream.streamArn,
56+
role: singletonEventRole(this.stream, policyStatements),
57+
input: this.props.message,
58+
targetResource: this.stream,
59+
kinesisParameters: this.props.partitionKeyPath ? { partitionKeyPath: this.props.partitionKeyPath } : undefined,
60+
};
61+
}
62+
63+
}

0 commit comments

Comments
 (0)