Skip to content

Commit 8134b6f

Browse files
committed
added logS3AccessLogs and S3BucketInterface to s3-stepfunctions
1 parent c8320bd commit 8134b6f

8 files changed

+72
-107
lines changed

source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/README.md

+11-9
Original file line numberDiff line numberDiff line change
@@ -59,25 +59,27 @@ _Parameters_
5959
|:-------------|:----------------|-----------------|
6060
|existingBucketObj?|[`s3.IBucket`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.IBucket.html)|Existing instance of S3 Bucket object. If this is provided, then also providing bucketProps is an error. |
6161
|bucketProps?|[`s3.BucketProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.BucketProps.html)|Optional user provided props to override the default props for the S3 Bucket.|
62-
|stateMachineProps|[`sfn.StateMachineProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-stepfunctions.StateMachineProps.html)|User provided props to override the default props for sfn.StateMachine|
63-
|eventRuleProps?|[`events.RuleProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.RuleProps.html)|Optional user provided eventRuleProps to override the defaults|
62+
|stateMachineProps|[`sfn.StateMachineProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-stepfunctions.StateMachineProps.html)|User provided props to override the default props for sfn.StateMachine.|
63+
|eventRuleProps?|[`events.RuleProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events.RuleProps.html)|Optional user provided eventRuleProps to override the defaults.|
6464
|deployCloudTrail?|`boolean`|Whether to deploy a Trail in AWS CloudTrail to log API events in Amazon S3. Defaults to `true`.|
65-
|createCloudWatchAlarms|`boolean`|Whether to create recommended CloudWatch alarms|
65+
|createCloudWatchAlarms|`boolean`|Whether to create recommended CloudWatch alarms.|
6666
|logGroupProps?|[`logs.LogGroupProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.LogGroupProps.html)|Optional user provided props to override the default props for for the CloudWatchLogs LogGroup.|
6767
|loggingBucketProps?|[`s3.BucketProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.BucketProps.html)|Optional user provided props to override the default props for the S3 Logging Bucket.|
68+
|logS3AccessLogs?| boolean|Whether to turn on Access Logging for the S3 bucket. Creates an S3 bucket with associated storage costs for the logs. Enabling Access Logging is a best practice. default - true|
6869

6970
## Pattern Properties
7071

7172
| **Name** | **Type** | **Description** |
7273
|:-------------|:----------------|-----------------|
73-
|stateMachine|[`sfn.StateMachine`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-stepfunctions.StateMachine.html)|Returns an instance of sfn.StateMachine created by the construct|
74-
|stateMachineLogGroup|[`logs.ILogGroup`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.ILogGroup.html)|Returns an instance of the ILogGroup created by the construct for StateMachine|
75-
|cloudwatchAlarms?|[`cloudwatch.Alarm[]`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cloudwatch.Alarm.html)|Returns a list of cloudwatch.Alarm created by the construct|
76-
|s3Bucket?|[`s3.Bucket`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.Bucket.html)|Returns an instance of the s3.Bucket created by the construct|
74+
|stateMachine|[`sfn.StateMachine`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-stepfunctions.StateMachine.html)|Returns an instance of sfn.StateMachine created by the construct.|
75+
|stateMachineLogGroup|[`logs.ILogGroup`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.ILogGroup.html)|Returns an instance of the ILogGroup created by the construct for StateMachine.|
76+
|cloudwatchAlarms?|[`cloudwatch.Alarm[]`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cloudwatch.Alarm.html)|Returns a list of cloudwatch.Alarm created by the construct.|
77+
|s3Bucket?|[`s3.Bucket`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.Bucket.html)|Returns an instance of the s3.Bucket created by the construct.|
7778
|s3LoggingBucket?|[`s3.Bucket`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.Bucket.html)|Returns an instance of s3.Bucket created by the construct as the logging bucket for the primary bucket.|
78-
|cloudtrail|[`cloudtrail.Trail`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cloudtrail.Trail.html)|Returns an instance of the cloudtrail.Trail created by the construct|
79-
|cloudtrailBucket|[`s3.Bucket`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.Bucket.html)|Returns an instance of the s3.Bucket created by the construct for CloudTrail|
79+
|cloudtrail|[`cloudtrail.Trail`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cloudtrail.Trail.html)|Returns an instance of the cloudtrail.Trail created by the construct.|
80+
|cloudtrailBucket|[`s3.Bucket`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.Bucket.html)|Returns an instance of the s3.Bucket created by the construct for CloudTrail.|
8081
|cloudtrailLoggingBucket|[`s3.Bucket`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.Bucket.html)|Returns an instance of s3.Bucket created by the construct as the logging bucket for the primary CloudTrail bucket.|
82+
|s3BucketInterface|[`s3.IBucket`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-s3.IBucket.html)|Returns an instance of s3.IBucket created by the construct.|
8183

8284
## Default settings
8385

source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/lib/index.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ export interface S3ToStepfunctionsProps {
7474
* @default - Default props are used
7575
*/
7676
readonly loggingBucketProps?: s3.BucketProps
77+
/**
78+
* Whether to turn on Access Logs for the S3 bucket with the associated storage costs.
79+
* Enabling Access Logging is a best practice.
80+
*
81+
* @default - true
82+
*/
83+
readonly logS3AccessLogs?: boolean;
7784
}
7885

7986
export class S3ToStepfunctions extends Construct {
@@ -85,6 +92,7 @@ export class S3ToStepfunctions extends Construct {
8592
public readonly cloudtrail?: cloudtrail.Trail;
8693
public readonly cloudtrailBucket?: s3.Bucket;
8794
public readonly cloudtrailLoggingBucket?: s3.Bucket;
95+
public readonly s3BucketInterface: s3.IBucket;
8896

8997
/**
9098
* @summary Constructs a new instance of the S3ToStepfunctions class.
@@ -99,20 +107,19 @@ export class S3ToStepfunctions extends Construct {
99107

100108
let bucket: s3.IBucket;
101109

102-
if (props.existingBucketObj && props.bucketProps) {
103-
throw new Error('Cannot specify both bucket properties and an existing bucket');
104-
}
105-
106110
if (!props.existingBucketObj) {
107111
[this.s3Bucket, this.s3LoggingBucket] = defaults.buildS3Bucket(this, {
108112
bucketProps: props.bucketProps,
109-
loggingBucketProps: props.loggingBucketProps
113+
loggingBucketProps: props.loggingBucketProps,
114+
logS3AccessLogs: props.logS3AccessLogs
110115
});
111116
bucket = this.s3Bucket;
112117
} else {
113118
bucket = props.existingBucketObj;
114119
}
115120

121+
this.s3BucketInterface = bucket;
122+
116123
if (props.deployCloudTrail === undefined || props.deployCloudTrail) {
117124
[this.cloudtrailBucket, this.cloudtrailLoggingBucket] = defaults.buildS3Bucket(this, {}, 'CloudTrail');
118125

source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/integ.customLoggingBucket.expected.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,8 @@
441441
"Properties": {
442442
"LogGroupName": "/aws/vendedlogs/states/customloggingbuckettests3stepfunctionseventrulestepfunctionconstructstatemachineloga4e9bc58c9e9"
443443
},
444-
"UpdateReplacePolicy": "Retain",
445-
"DeletionPolicy": "Retain",
444+
"UpdateReplacePolicy": "Delete",
445+
"DeletionPolicy": "Delete",
446446
"Metadata": {
447447
"cfn_nag": {
448448
"rules_to_suppress": [

source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/integ.customLoggingBucket.ts

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ new S3ToStepfunctions(stack, 'test-s3-stepfunctions', {
3737
bucketName: 'custom-logging-bucket',
3838
encryption: BucketEncryption.S3_MANAGED,
3939
versioned: true
40+
},
41+
logGroupProps: {
42+
removalPolicy: RemovalPolicy.DESTROY
4043
}
4144
});
4245
app.synth();

source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/integ.pre-existing-bucket.ts

+2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ const props: S3ToStepfunctionsProps = {
3535
logGroupProps: {
3636
removalPolicy: RemovalPolicy.DESTROY
3737
},
38+
logS3AccessLogs: false
3839
};
3940

4041
new S3ToStepfunctions(stack, 'test-s3-stepfunctions-pre-existing-bucket-construct', props);
42+
4143
app.synth();

source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/integ.s3-stepfunctions-no-argument.expected.json

+11-90
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,5 @@
11
{
22
"Resources": {
3-
"tests3stepfunctionsconstructS3LoggingBucket706AEC25": {
4-
"Type": "AWS::S3::Bucket",
5-
"Properties": {
6-
"AccessControl": "LogDeliveryWrite",
7-
"BucketEncryption": {
8-
"ServerSideEncryptionConfiguration": [
9-
{
10-
"ServerSideEncryptionByDefault": {
11-
"SSEAlgorithm": "AES256"
12-
}
13-
}
14-
]
15-
},
16-
"PublicAccessBlockConfiguration": {
17-
"BlockPublicAcls": true,
18-
"BlockPublicPolicy": true,
19-
"IgnorePublicAcls": true,
20-
"RestrictPublicBuckets": true
21-
},
22-
"VersioningConfiguration": {
23-
"Status": "Enabled"
24-
}
25-
},
26-
"UpdateReplacePolicy": "Delete",
27-
"DeletionPolicy": "Delete",
28-
"Metadata": {
29-
"cfn_nag": {
30-
"rules_to_suppress": [
31-
{
32-
"id": "W35",
33-
"reason": "This S3 bucket is used as the access logging bucket for another bucket"
34-
}
35-
]
36-
}
37-
}
38-
},
39-
"tests3stepfunctionsconstructS3LoggingBucketPolicy4FEACD99": {
40-
"Type": "AWS::S3::BucketPolicy",
41-
"Properties": {
42-
"Bucket": {
43-
"Ref": "tests3stepfunctionsconstructS3LoggingBucket706AEC25"
44-
},
45-
"PolicyDocument": {
46-
"Statement": [
47-
{
48-
"Action": "*",
49-
"Condition": {
50-
"Bool": {
51-
"aws:SecureTransport": "false"
52-
}
53-
},
54-
"Effect": "Deny",
55-
"Principal": {
56-
"AWS": "*"
57-
},
58-
"Resource": [
59-
{
60-
"Fn::Join": [
61-
"",
62-
[
63-
{
64-
"Fn::GetAtt": [
65-
"tests3stepfunctionsconstructS3LoggingBucket706AEC25",
66-
"Arn"
67-
]
68-
},
69-
"/*"
70-
]
71-
]
72-
},
73-
{
74-
"Fn::GetAtt": [
75-
"tests3stepfunctionsconstructS3LoggingBucket706AEC25",
76-
"Arn"
77-
]
78-
}
79-
],
80-
"Sid": "HttpsOnly"
81-
}
82-
],
83-
"Version": "2012-10-17"
84-
}
85-
}
86-
},
873
"tests3stepfunctionsconstructS3Bucket78CA0724": {
884
"Type": "AWS::S3::Bucket",
895
"Properties": {
@@ -109,11 +25,6 @@
10925
}
11026
]
11127
},
112-
"LoggingConfiguration": {
113-
"DestinationBucketName": {
114-
"Ref": "tests3stepfunctionsconstructS3LoggingBucket706AEC25"
115-
}
116-
},
11728
"PublicAccessBlockConfiguration": {
11829
"BlockPublicAcls": true,
11930
"BlockPublicPolicy": true,
@@ -125,7 +36,17 @@
12536
}
12637
},
12738
"UpdateReplacePolicy": "Delete",
128-
"DeletionPolicy": "Delete"
39+
"DeletionPolicy": "Delete",
40+
"Metadata": {
41+
"cfn_nag": {
42+
"rules_to_suppress": [
43+
{
44+
"id": "W35",
45+
"reason": "This S3 bucket is created for unit/ integration testing purposes only."
46+
}
47+
]
48+
}
49+
}
12950
},
13051
"tests3stepfunctionsconstructS3BucketPolicyC7A413B9": {
13152
"Type": "AWS::S3::BucketPolicy",

source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/integ.s3-stepfunctions-no-argument.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import { App, Stack, RemovalPolicy } from "@aws-cdk/core";
1616
import { S3ToStepfunctions, S3ToStepfunctionsProps } from "../lib";
1717
import * as stepfunctions from '@aws-cdk/aws-stepfunctions';
1818
import { generateIntegStackName } from '@aws-solutions-constructs/core';
19+
import * as s3 from '@aws-cdk/aws-s3';
20+
import * as defaults from '@aws-solutions-constructs/core';
1921

2022
const app = new App();
2123
const stack = new Stack(app, generateIntegStackName(__filename));
@@ -32,7 +34,15 @@ const props: S3ToStepfunctionsProps = {
3234
logGroupProps: {
3335
removalPolicy: RemovalPolicy.DESTROY
3436
},
37+
logS3AccessLogs: false
3538
};
3639

37-
new S3ToStepfunctions(stack, 'test-s3-stepfunctions-construct', props);
40+
const construct = new S3ToStepfunctions(stack, 'test-s3-stepfunctions-construct', props);
41+
const s3Bucket = construct.s3Bucket as s3.Bucket;
42+
43+
defaults.addCfnSuppressRules(s3Bucket, [
44+
{ id: 'W35',
45+
reason: 'This S3 bucket is created for unit/ integration testing purposes only.' },
46+
]);
47+
3848
app.synth();

source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/s3-stepfunctions.test.ts

+20
Original file line numberDiff line numberDiff line change
@@ -202,4 +202,24 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => {
202202
Ref: "tests3stepfunctionsS3LoggingBucketF7586A92"
203203
}
204204
});
205+
});
206+
207+
// --------------------------------------------------------------
208+
// s3 bucket with one content bucket and no logging bucket
209+
// --------------------------------------------------------------
210+
test('s3 bucket with no logging bucket', () => {
211+
const stack = new cdk.Stack();
212+
const startState = new sfn.Pass(stack, 'StartState');
213+
214+
const construct = new S3ToStepfunctions(stack, 's3-stepfunctions', {
215+
stateMachineProps: {
216+
definition: startState
217+
},
218+
bucketProps: {
219+
removalPolicy: cdk.RemovalPolicy.DESTROY,
220+
},
221+
logS3AccessLogs: false
222+
});
223+
224+
expect(construct.s3LoggingBucket).toEqual(undefined);
205225
});

0 commit comments

Comments
 (0)