SES activate rule set custom resource
Managing SES using CDK writing infrastructure proved incomplete. I used CDK custom resources to activate an SES ruleset. Read about the background of my problem or jump right to the solution chapter.
Some background on managing SES with CDK
Recently I needed to create a solution involving an SES-based email inbox. SES is a great tool to enable e-mail based integrations as a service. While there are of course 3rd party services that have more feature-rich services offering. I am sure on many occasions SES offers great functionality to integrate your cloud stack with. However, when creating this infrastructure as code I found there was no CDK construct to create an activated ruleset.
Searching for resources on this didn’t turn up the usual amount of resources. CDK offers a construct for creating an inbound email resource. In this example, I assume you already created a working e-mail domain. If you are new to that, please follow these steps.
After you have established your email domain. For incoming mail to be accepted you need a receipt rule set. This CDK construct will create a rule set on which you can add your desired rules.
const ruleSet = new ReceiptRuleSet(this, 'MyRuleSet', {
receiptRuleSetName: 'default',
rules: [
{
//some rule
},
]
});
Receipt rules are offered in many shapes. They all provide an interface on one of the AWS services to input the incoming e-mail. In my example, I used S3 as the destination.
const ruleSet = new ReceiptRuleSet(this, 'ArchivalRuleSet', {
receiptRuleSetName: 'my-rule-set',
rules: [
{
enabled: true,
actions: [
new actions.S3({
bucket: some-bucket-object,
objectKeyPrefix: 'emails/'
})
],
},
]
});
Weirdly enough this rule construct does contain an enabled flag, which for me would be something I searched for on the higher level receipt rule. However, this property is nonexistent. This is flagged also in this discussion.
The proposed solution here is to manually activate the ruleset once through the console. However, my production environment does not offer console intervention. And basically, I don’t like it. People will forget that this manual step was part of the process which will fail you at some point. The point of having everything ‘as code’ is that it's way better than any documented instruction.
Solution for activating the SES receipt ruleset
A solution for many things the AWS CDK is not readily supporting is to create a custom resource. In this case, the simplest way to do this is by wrapping an AWS service call.
// Actual service call that will activate our ruleconst awsSdkCall: AwsSdkCall = {
service: 'SES',
action: 'setActiveReceiptRuleSet',
physicalResourceId: PhysicalResourceId.of('DefaultSesCustomResource'),
parameters: {
RuleSetName: 'my-rule-set',
}
}// Execution context for this service callconst customResource: AwsCustomResource = new AwsCustomResource(this, "ses_default_rule_set_custom_resource", {
onCreate: awsSdkCall,
onUpdate: awsSdkCall,
logRetention: RetentionDays.ONE_WEEK,
policy: AwsCustomResourcePolicy.fromStatements([
new PolicyStatement({
sid: 'SesCustomResourceSetActiveReceiptRuleSet',
effect: Effect.ALLOW,
actions: ['ses:SetActiveReceiptRuleSet'],
resources: ['*']
})
]),
timeout: Duration.seconds(30)
}
);
There you go! Using this custom resource you will ensure activation of your freshly created rule set. I hope you enjoy using it.
If you need some additional context, or when you are (like me) not a big fan of only small code snippets I wrapped this example in an actual CDK Github example. Enjoy!