import * as ses from 'aws-cdk-lib/aws-ses'; import * as sns from 'aws-cdk-lib/aws-sns'; import { Construct } from 'constructs'; export interface BounceThresholdsProps { readonly warning?: number; readonly critical?: number; } export interface ComplaintThresholdsProps { readonly warning?: number; readonly critical?: number; } export interface SesObservabilityProps { /** * The SES events to log. * * @defaultValue [EmailSendingEvent.DELIVERY, EmailSendingEvent.BOUNCE, EmailSendingEvent.COMPLAINT, EmailSendingEvent.REJECT] */ readonly loggedSesEvents?: ses.EmailSendingEvent[]; /** * The Thresholds for bounce rate Monitors. * * The default should only be overwritten, if there is really no possibility to reduce the bounce rate meaningfully. * If this metric reaches `10%` the email sending capability of your account will be disabled by AWS. * * @default { critical: 0.05, warning: 0.04 } */ readonly bounceThresholds?: BounceThresholdsProps; /** * The Thresholds for bounce rate Monitors. * * The default should only be overwritten, if there is really no possibility to reduce the bounce complaint meaningfully. * If this metric reaches `0.5%` the email sending capability of your account will be disabled by AWS. * * @default { critical: 0.001, warning: 0.0008 } */ readonly complaintThresholds?: ComplaintThresholdsProps; /** * Enable this if you want the Datadog monitors to create cases in Datadog when an alert is triggered. * * @defaultValue false */ readonly createCasesFromMonitors?: boolean; } /** * RioSesObservability * * This construct sets up observability for SES as defined by [ADR - SES domain reputation observability](https://confluence.collaboration-man.com/display/MAN/ADR+-+SES+domain+reputation+observability). * * # Warning * This construct results in logging all sent emails including the recipient address into CloudWatch logs. * As this is considered **PII**, this information MUST be handled accordingly. * In particular, logs **MUST NOT** be sent to further third party services (e.g. Datadog) and the retention period for logs **MUST NOT** be extended. * * # Usage * ## Default Configuration Set for Identity * * ```typescript * const rioSesObservability = new RioSesObservability(this, 'ConfigurationSet', {}) * const identity = new EmailIdentity(this, 'EmailIdentity', { * identity: Identity.domain('example.com'), * configurationSet: rioSesObservability.configurationSet, * }); * ``` * * ## Specifically using the configuration set per request * * This is ideal if you want to try out the construct first one some specific emails (e.g. during initial migration). * The configuration set name is exported as an SSM parameter `/rio/config/ses-observability/configuration-set-name`. * Thus, you can easily make it available as environment variable in your code. * * ```kotlin * import com.amazonaws.services.simpleemail.model.SendEmailRequest * * val request = SendEmailRequest() * .withConfigurationSetName(SSM_CONFIGURATION_SSM_PARAMETER_VALUE) * ... * ``` * * ## Automated event processing * * If you have specific needs for which you'd like to process the SNS events directly * (e.g. automatically creating a suppression list from bounces), you can subscribe to the SNS topic. * To enable this the SNS topic ARN is exported via Cloudformation as `RioSesObservabilityTopicArn`. * * # Notes * ## Add necessary permissions for fargate task to enable using ses configuration set * Make sure you have the following permissions in the task role of the fargate task, e.g.: * ```typescript * service.taskDefinition.taskRole.addToPrincipalPolicy( * new iam.PolicyStatement({ * actions: ['ses:sendEmail', 'ses:sendRawEmail'], * resources: [`arn:aws:ses:::configuration-set/`], * })); * ``` * * ## Watchful * It might be helpful to add watchful to your stack to * get notified if the ses-logger lambda fails. */ export declare class SesObservability extends Construct { static readonly CONFIGURATION_SET_NAME_SSM_PARAMETER = "/rio/config/ses-observability/configuration-set-name"; static readonly SNS_TOPIC_ARN_EXPORT_NAME = "RioSesObservabilityTopicArn"; readonly snsTopic: sns.Topic; readonly configurationSet: ses.ConfigurationSet; constructor(scope: Construct, id: string, props: SesObservabilityProps); /** * This function ensures that no PII is leaked to Datadog by adding a subscription filter to the log group of the lambda. */ private ensureNoSubscriptionFiltersOnLambdasLogGroup; }