Skip to content

Commit 771eeff

Browse files
feat(ses): maximum delivery time for emails (#32102)
### Issue # (if applicable) None ### Reason for this change Amazon Simple Email Service (SES) offers a [new delivery option that allows us to set a custom maximum delivery time for our emails at Oct 15, 2024](https://aws.amazon.com/about-aws/whats-new/2024/10/amazon-ses-configurability-maximum-delivery-time-emails/?nc1=h_ls) Cfn documentation: <https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ses-configurationset-deliveryoptions.html#cfn-ses-configurationset-deliveryoptions-maxdeliveryseconds> ### Description of changes Add `maxDeliveryDuration` to `ConfigurationSetProps`. ### Description of how you validated changes Add both unit and integ tests. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 6820c62 commit 771eeff

11 files changed

+110
-52
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-ses/test/integ.configuration-set.js.snapshot/ConfigurationSetIntegDefaultTestDeployAssert9B6AD46A.assets.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ses/test/integ.configuration-set.js.snapshot/cdk-ses-configuration-set-integ.assets.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ses/test/integ.configuration-set.js.snapshot/cdk-ses-configuration-set-integ.template.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
{
22
"Resources": {
33
"ConfigurationSet3DD38186": {
4-
"Type": "AWS::SES::ConfigurationSet"
4+
"Type": "AWS::SES::ConfigurationSet",
5+
"Properties": {
6+
"DeliveryOptions": {
7+
"MaxDeliverySeconds": 600
8+
}
9+
}
510
},
611
"ConfigurationSetSns63B38980": {
712
"Type": "AWS::SES::ConfigurationSetEventDestination",

packages/@aws-cdk-testing/framework-integ/test/aws-ses/test/integ.configuration-set.js.snapshot/cdk.out

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ses/test/integ.configuration-set.js.snapshot/integ.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ses/test/integ.configuration-set.js.snapshot/manifest.json

+6-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ses/test/integ.configuration-set.js.snapshot/tree.json

+41-37
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-ses/test/integ.configuration-set.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { App, Stack, StackProps } from 'aws-cdk-lib';
1+
import { App, Duration, Stack, StackProps } from 'aws-cdk-lib';
22
import * as integ from '@aws-cdk/integ-tests-alpha';
33
import { Construct } from 'constructs';
44
import * as ses from 'aws-cdk-lib/aws-ses';
@@ -8,7 +8,9 @@ class TestStack extends Stack {
88
constructor(scope: Construct, id: string, props?: StackProps) {
99
super(scope, id, props);
1010

11-
const configurationSet = new ses.ConfigurationSet(this, 'ConfigurationSet');
11+
const configurationSet = new ses.ConfigurationSet(this, 'ConfigurationSet', {
12+
maxDeliveryDuration: Duration.minutes(10),
13+
});
1214

1315
const topic = new sns.Topic(this, 'Topic');
1416

@@ -32,5 +34,3 @@ const app = new App();
3234
new integ.IntegTest(app, 'ConfigurationSetInteg', {
3335
testCases: [new TestStack(app, 'cdk-ses-configuration-set-integ')],
3436
});
35-
36-
app.synth();

packages/aws-cdk-lib/aws-ses/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,19 @@ set to an email, all of the rules in that configuration set are applied to the e
134134
Use the `ConfigurationSet` construct to create a configuration set:
135135

136136
```ts
137+
import { Duration } from 'aws-cdk-lib';
138+
137139
declare const myPool: ses.IDedicatedIpPool;
138140

139141
new ses.ConfigurationSet(this, 'ConfigurationSet', {
140142
customTrackingRedirectDomain: 'track.cdk.dev',
141143
suppressionReasons: ses.SuppressionReasons.COMPLAINTS_ONLY,
142144
tlsPolicy: ses.ConfigurationSetTlsPolicy.REQUIRE,
143145
dedicatedIpPool: myPool,
146+
// Specify maximum delivery time
147+
// This configuration can be useful in such cases as time-sensitive emails (like those containing a one-time-password),
148+
// transactional emails, and email that you want to ensure isn't delivered during non-business hours.
149+
maxDeliveryDuration: Duration.minutes(10),
144150
});
145151
```
146152

packages/aws-cdk-lib/aws-ses/lib/configuration-set.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ConfigurationSetEventDestination, ConfigurationSetEventDestinationOptio
33
import { IDedicatedIpPool } from './dedicated-ip-pool';
44
import { undefinedIfNoKeys } from './private/utils';
55
import { CfnConfigurationSet } from './ses.generated';
6-
import { IResource, Resource } from '../../core';
6+
import { Duration, IResource, Resource, Token } from '../../core';
77

88
/**
99
* A configuration set
@@ -80,6 +80,15 @@ export interface ConfigurationSetProps {
8080
* @default - VDM options not configured at the configuration set level. In this case, use account level settings. (To set the account level settings using CDK, use the `VdmAttributes` Construct.)
8181
*/
8282
readonly vdmOptions?: VdmOptions;
83+
84+
/**
85+
* The maximum amount of time that Amazon SES API v2 will attempt delivery of email.
86+
*
87+
* This value must be greater than or equal to 5 minutes and less than or equal to 14 hours.
88+
*
89+
* @default undefined - SES defaults to 14 hours
90+
*/
91+
readonly maxDeliveryDuration?: Duration;
8392
}
8493

8594
/**
@@ -158,10 +167,20 @@ export class ConfigurationSet extends Resource implements IConfigurationSet {
158167
physicalName: props.configurationSetName,
159168
});
160169

170+
if (props.maxDeliveryDuration && !Token.isUnresolved(props.maxDeliveryDuration)) {
171+
if (props.maxDeliveryDuration.toMilliseconds() < Duration.minutes(5).toMilliseconds()) {
172+
throw new Error(`The maximum delivery duration must be greater than or equal to 5 minutes (300_000 milliseconds), got: ${props.maxDeliveryDuration.toMilliseconds()} milliseconds.`);
173+
}
174+
if (props.maxDeliveryDuration.toSeconds() > Duration.hours(14).toSeconds()) {
175+
throw new Error(`The maximum delivery duration must be less than or equal to 14 hours (50400 seconds), got: ${props.maxDeliveryDuration.toSeconds()} seconds.`);
176+
}
177+
}
178+
161179
const configurationSet = new CfnConfigurationSet(this, 'Resource', {
162180
deliveryOptions: undefinedIfNoKeys({
163181
sendingPoolName: props.dedicatedIpPool?.dedicatedIpPoolName,
164182
tlsPolicy: props.tlsPolicy,
183+
maxDeliverySeconds: props.maxDeliveryDuration?.toSeconds(),
165184
}),
166185
name: this.physicalName,
167186
reputationOptions: undefinedIfNoKeys({

0 commit comments

Comments
 (0)