-
Notifications
You must be signed in to change notification settings - Fork 249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(aws-s3-sns): created new construct #849
Changes from 2 commits
51db29c
ee52701
adf993d
70e8994
fa4eb4b
6ee16f9
69c6ba3
6a14de7
47a9399
b7aecd0
073b35b
b4b7c4a
a16048c
2a08f10
f0a0745
0288b6b
bace851
3ffe4b1
d330ada
7048e3f
1f6d9bc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,16 +64,15 @@ export interface S3ToSnsProps { | |
*/ | ||
readonly logS3AccessLogs?: boolean; | ||
/** | ||
* Existing SNS topic to be used instead of the default topic. Providing both this and `topicProps` will cause an error. | ||
* If the SNS Topic is encrypted, the KMS key utilized for encryption must be a customer managed KMS key and it must be | ||
* specified in the `existingTopicEncryptionKey` property. | ||
* An optional, existing SNS topic to be used instead of the default topic. Providing both this and `topicProps` will cause an error. | ||
* If the SNS Topic is encrypted with a Customer-Managed KMS Key, the key must be specified in the `existingTopicEncryptionKey` property. | ||
* | ||
* @default - Default props are used | ||
*/ | ||
readonly existingTopicObj?: sns.Topic; | ||
/** | ||
* If an existing topic is provided in the `existingTopicObj` property, and that topic is encrypted with a customer managed KMS key, | ||
* this property also needs to be set with same CMK. | ||
* If an existing topic is provided in the `existingTopicObj` property, and that topic is encrypted with a Customer-Managed KMS key, | ||
* this property also needs to be set with same key. | ||
* | ||
* @default - None | ||
*/ | ||
|
@@ -127,13 +126,8 @@ export class S3ToSns extends Construct { | |
super(scope, id); | ||
defaults.CheckProps(props); | ||
|
||
let bucket: s3.Bucket; | ||
let enableEncryptionParam = props.enableEncryptionWithCustomerManagedKey; | ||
|
||
if (props.enableEncryptionWithCustomerManagedKey === undefined || | ||
props.enableEncryptionWithCustomerManagedKey === true) { | ||
enableEncryptionParam = true; | ||
} | ||
// If the enableEncryptionWithCustomerManagedKey is undefined, default it to true | ||
const enableEncryptionParam = props.enableEncryptionWithCustomerManagedKey === false ? false : true; | ||
|
||
// Setup the S3 bucket | ||
if (!props.existingBucketObj) { | ||
|
@@ -142,42 +136,38 @@ export class S3ToSns extends Construct { | |
loggingBucketProps: props.loggingBucketProps, | ||
logS3AccessLogs: props.logS3AccessLogs | ||
}); | ||
bucket = this.s3Bucket; | ||
this.s3BucketInterface = this.s3Bucket; | ||
} else { | ||
bucket = props.existingBucketObj; | ||
this.s3BucketInterface = props.existingBucketObj; | ||
} | ||
|
||
this.s3BucketInterface = bucket; | ||
|
||
// Setup the topic | ||
[this.snsTopic, this.encryptionKey] = defaults.buildTopic(this, { | ||
existingTopicObj: props.existingTopicObj, | ||
existingTopicEncryptionKey: props.existingTopicEncryptionKey, | ||
topicProps: props.topicProps, | ||
enableEncryptionWithCustomerManagedKey: enableEncryptionParam, | ||
encryptionKey: props.encryptionKey, | ||
encryptionKeyProps: props.encryptionKeyProps | ||
}); | ||
|
||
if (props.existingTopicEncryptionKey) { | ||
this.encryptionKey = props.existingTopicEncryptionKey; | ||
} | ||
|
||
// Setup the S3 bucket event types | ||
const s3EventTypes = props.s3EventTypes ? props.s3EventTypes : defaults.defaultS3NotificationEventTypes; | ||
const s3EventTypes = props.s3EventTypes ?? defaults.defaultS3NotificationEventTypes; | ||
|
||
// Setup the S3 bucket event filters | ||
const s3Eventfilters = props.s3EventFilters ? props.s3EventFilters : []; | ||
const s3Eventfilters = props.s3EventFilters ?? []; | ||
|
||
// Setup the S3 bucket event notifications | ||
s3EventTypes.forEach(type => bucket.addEventNotification(type, new s3n.SnsDestination(this.snsTopic), ...s3Eventfilters)); | ||
s3EventTypes.forEach((type) => { | ||
const destination = new s3n.SnsDestination(this.snsTopic); | ||
this.s3BucketInterface.addEventNotification(type, destination, ...s3Eventfilters); | ||
}); | ||
|
||
// Grant S3 permission to use the topic's encryption key so it can publish messages to it | ||
if (this.encryptionKey) { | ||
this.encryptionKey.grant(new iam.ServicePrincipal("s3.amazonaws.com"), | ||
'kms:Decrypt', | ||
'kms:GenerateDataKey*', | ||
); | ||
} | ||
this.encryptionKey?.grant(new iam.ServicePrincipal("s3.amazonaws.com"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if the topic is not encrypted and this.encryptionKey is undefined, won't this break? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is using optional chaining in typescript, so if encryptionKey evaluates to null, it will immediately stop running the expression. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've created a new set of unit/integ tests to prove it out. |
||
'kms:Decrypt', | ||
'kms:GenerateDataKey*', | ||
); | ||
|
||
addCfnNagS3BucketNotificationRulesToSuppress(Stack.of(this), 'BucketNotificationsHandler050a0587b7544547bf325f094a3db834'); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really hate how dependent we are becoming on this paradigm of returning an array of anonymous values (there's a lot more of this in firehose-s3).
I think we need to start considering defining an interface for return values from our build* functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I love that idea too. I'd prefer to keep this PR for the new construct and then do that refactor as a quick follow-up. I've created #853 to track it.