Skip to content

emailDomain

View Source

Amazon SES (Simple Email Service) domain configuration enables sending transactional emails from your custom domain with full deliverability tracking. This component sets up domain verification, DKIM authentication, SPF/DMARC records, and event logging for production email sending.

import * as saws from "@stackattack/aws";
const ctx = saws.context();
const emailSetup = saws.emailDomain(ctx, {
domain: "mail.example.com",
dmarcInbox: "dmarc-reports@mail.example.com",
webhookUrl: "https://my-api.example.com/email/webhook" // Optional
});
export const configurationSet = emailSetup.configurationSet.name;

After deployment, send emails using the AWS SDK:

// Using AWS SDK
import { SESv2Client, SendEmailCommand } from "@aws-sdk/client-sesv2";
const client = new SESv2Client({ region: "us-east-1" });
await client.send(new SendEmailCommand({
FromEmailAddress: "noreply@mail.example.com",
Destination: { ToAddresses: ["user@mail.example.com"] },
Content: {
Simple: {
Subject: { Data: "Welcome!" },
Body: { Text: { Data: "Hello from SES!" } }
}
},
ConfigurationSetName: "my-email-config-set"
}));

See the AWS SDK Documentation for more details.

You will have to request production access for SES to be able to send to email addresses other than your verified identifies. The setup above will allow you to send emails to email addresses with the domain mail.example.com, e.g. user1@mail.example.com. It also requires that you have example.com as a hosted zone in Route53.

If you provide the webhookUrl parameter, you should also configure your API endpoint such that it confirms the webhook subscription. For example:

import { SNSClient, ConfirmSubscriptionCommand } from "@aws-sdk/client-sns";
// Express.js webhook handler
app.post('/email/webhook', express.raw({ type: 'text/plain' }), async (req, res) => {
const message = JSON.parse(req.body);
const messageType = req.headers['x-amz-sns-message-type'] || message.Type;
// Handle subscription confirmation programmatically
if (messageType === 'SubscriptionConfirmation') {
const sns = new SNSClient({ region: "us-east-1" });
await sns.send(new ConfirmSubscriptionCommand({
Token: message.Token,
AuthenticateOnUnsubscribe: 'true',
TopicArn: message.TopicArn
}));
return res.status(200).send('Subscription confirmed');
}
// Handle actual notifications
if (messageType === 'Notification') {
console.log('SNS Message:', message.Message);
// Process your webhook logic here
return res.status(200).send('OK');
}
res.status(400).send('Unknown message type');
});

The API above should be (publicly) available at https://my-api.example.com to confirm the subscription. Also ensure that your application is authenticated with AWS and has the sns:ConfirmSubscription permission.

The email domain component depends on:

  • topicWebhook - Used to set up a webhook subscription if webhookUrl is passes as a parameter.
  • Production Access: You must request production access in the AWS SES console to send emails to unverified addresses. This component sets up the domain but does not automatically grant production sending access.
  • Dedicated IP: This component does not include dedicated IP setup. For high-volume sending requiring dedicated IPs, additional configuration is needed.

SES pricing is usage-based with no upfront costs:

  • Free tier: 200 emails/day for applications hosted on AWS
  • Standard pricing: $0.10 per 1,000 emails sent
  • Dedicated IP: $24.95/month per IP (for high-volume senders, not included in this component)
  • Data transfer: Standard AWS rates for attachments

Cost optimization strategies:

  • Use SES configuration sets to track bounce/complaint rates and maintain sender reputation
  • Implement email validation to avoid sending to invalid addresses
  • Consider bulk sending features for newsletters vs transactional emails
  • Monitor sending quotas to avoid throttling in production

Sets up a complete email domain configuration with Amazon SES. This function creates domain identity, DKIM verification, SPF/DMARC records, configuration set, event logging, and optional S3 logging and webhooks.

function emailDomain(ctx: Context, args: EmailDomainArgs): EmailDomainOutput
  • ctx (Context) - The context for resource naming and tagging
  • args (EmailDomainArgs) - Configuration arguments for the email domain setup
  • (EmailDomainOutput) - Sets up a complete email domain configuration with Amazon SES. This function creates domain identity, DKIM verification, SPF/DMARC records, configuration set, event logging, and optional S3 logging and webhooks.

Creates an IAM policy document for email log delivery role that allows access to Kinesis Firehose. This policy grants permissions to put records into the specified Firehose delivery stream.

function emailLogRolePolicy(firehoseArn: Input<string>): Output<GetPolicyDocumentResult>
  • firehoseArn (Input<string>) - The ARN of the Kinesis Firehose delivery stream
  • (Output<GetPolicyDocumentResult>) - Creates an IAM policy document for email log delivery role that allows access to Kinesis Firehose. This policy grants permissions to put records into the specified Firehose delivery stream.

Creates an IAM policy document for SNS topic access by AWS services. This policy allows AWS services within the same account to interact with the SNS topic.

function emailLogSnsTopicPolicy(args: EmailSNSTopicPolicyArgs): Output<GetPolicyDocumentResult>
  • (Output<GetPolicyDocumentResult>) - Creates an IAM policy document for SNS topic access by AWS services. This policy allows AWS services within the same account to interact with the SNS topic.

Creates an SNS topic subscription that delivers email events to S3 via Kinesis Firehose. This function sets up the necessary IAM role and subscription to stream email events to S3.

function emailS3Log(ctx: Context, args: EmailS3LogArgs): TopicSubscription
  • ctx (Context) - The context for resource naming and tagging
  • args (EmailS3LogArgs) - Configuration arguments for the S3 log setup
  • (TopicSubscription) - Creates an SNS topic subscription that delivers email events to S3 via Kinesis Firehose. This function sets up the necessary IAM role and subscription to stream email events to S3.

Configuration arguments for setting up a complete email domain with SES.

  • dmarcInbox (Input<string>) - Email address to receive DMARC reports
  • domain (Input<string>) - The domain name to configure for email sending
  • logs? (S3FirehoseArgs) - Optional S3 logging configuration via Firehose
  • noPrefix? (boolean) - Whether to skip adding a prefix to resource names
  • noVerify? (boolean) - Whether to skip domain verification setup (DNS records)
  • nTokens? (number) - Number of DKIM tokens to create (defaults to 3)
  • webhookUrl? (Input<string>) - Optional webhook URL for email event notifications
  • zoneId? (Input<string>) - Optional Route53 hosted zone ID (will be auto-detected if not provided)

Outputs of the email domain component

  • configurationSet (ConfigurationSet) - Configuration set; if you send emails using this as a parameter (see example above), reputation metrics will be enabled meaning AWS cloudwatch metrics will be emitted that you can use to track bounce and complaint rates
  • logTopic (Topic) - SNS topic that events related to emails send through SES with this domain will be sent to. See the SES notification examples for more information.
  • webhookSubscription (null | TopicSubscription) - If you pass webhookUrl as an input parameter, this will contain the subscription object representing the connection between logTopic and your endpoint.

Configuration arguments for setting up email log delivery to S3 via Firehose.

  • emailLogTopicArn (Input<string>) - The ARN of the SNS topic that receives email events
  • firehoseArn (Input<string>) - The ARN of the Kinesis Firehose delivery stream for S3 logging
  • noPrefix? (boolean) - Whether to skip adding a prefix to resource names

Configuration arguments for creating an SNS topic policy for email logging.

  • accountId? (Input<string>) - The AWS account ID (optional, will be retrieved automatically if not provided)
  • topicArn (Input<string>) - The ARN of the SNS topic to create the policy for