towerops/AWS_SES_SETUP.md
2026-01-09 16:52:11 -06:00

4.1 KiB

Amazon SES Configuration

This document describes how to configure Amazon SES for outbound email in Towerops.

Required Environment Variables

The following environment variables must be set in production:

# AWS Credentials (required)
AWS_ACCESS_KEY_ID=your-access-key-id
AWS_SECRET_ACCESS_KEY=your-secret-access-key

# AWS Region (optional, defaults to us-east-1)
AWS_REGION=us-east-1

AWS IAM Permissions

The IAM user or role needs the following SES permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ses:SendEmail",
        "ses:SendRawEmail"
      ],
      "Resource": "*"
    }
  ]
}

SES Setup Steps

  1. Verify Your Domain in SES

    • Go to AWS Console > SES > Verified identities
    • Click "Create identity" > Domain
    • Add your domain (e.g., towerops.net)
    • Add the required DNS records (DKIM, MAIL FROM)
    • Wait for verification (can take up to 72 hours)
  2. Verify the From Email Address

    • In SES Console, verify hi@towerops.net (or your chosen from address)
    • Check the verification email and click the confirmation link
  3. Move Out of SES Sandbox (Production)

    • By default, SES is in sandbox mode (can only send to verified addresses)
    • Request production access: AWS Console > SES > Account dashboard > Request production access
    • Fill out the form with your use case
    • Approval typically takes 24 hours
  4. Create IAM User for Towerops

    aws iam create-user --user-name towerops-ses
    aws iam attach-user-policy --user-name towerops-ses --policy-arn arn:aws:iam::aws:policy/AmazonSESFullAccess
    aws iam create-access-key --user-name towerops-ses
    

    Save the AccessKeyId and SecretAccessKey from the output.

Configuration in Towerops

The from email address is configured via application config (not environment variable):

In config/runtime.exs or config/prod.exs:

config :towerops, :mailer_from, {"Towerops", "hi@towerops.net"}

Or set it dynamically via environment variable by adding to config/runtime.exs:

config :towerops, :mailer_from, 
  {System.get_env("MAILER_FROM_NAME") || "Towerops",
   System.get_env("MAILER_FROM_EMAIL") || "hi@towerops.net"}

Testing Email Configuration

In Development (using IEx)

# Start the application
iex -S mix

# Test sending an email
alias Towerops.Accounts.UserNotifier
user = %{email: "test@example.com"}
UserNotifier.deliver_update_email_instructions(user, "http://example.com/test")

In Production

Check the logs for successful delivery:

[info] User email sent to test@example.com: Update email instructions

Or check for errors:

[error] Failed to send user email to test@example.com: <reason>

Monitoring

  • Monitor bounce rates in AWS SES Console
  • Set up SNS notifications for bounces and complaints
  • Check CloudWatch metrics for email sending

Troubleshooting

"Email address not verified" error

  • Ensure the from address is verified in SES
  • If in sandbox mode, ensure recipient is also verified

"Access denied" error

  • Check IAM permissions
  • Verify AWS credentials are correct
  • Ensure credentials have SES permissions

"MessageRejected" error

  • Check SES sending limits
  • Verify domain DKIM records are set up
  • Check if account is in sandbox mode

"Throttling" error

  • SES has sending limits (default: 1 email/second)
  • Request limit increase in AWS Console

Current Configuration

Adapter: Swoosh.Adapters.ExAwsSES
Default Region: us-east-1
Default From: {"Towerops", "hi@towerops.net"}

Alternative: SMTP Configuration

If you prefer SMTP over API (not recommended), you can use:

config :towerops, Towerops.Mailer,
  adapter: Swoosh.Adapters.SMTP,
  relay: "email-smtp.us-east-1.amazonaws.com",
  port: 587,
  username: System.get_env("SES_SMTP_USERNAME"),
  password: System.get_env("SES_SMTP_PASSWORD"),
  tls: :always,
  auth: :always

SMTP credentials can be generated in AWS Console > SES > SMTP settings.

Note: API method is preferred as it's more reliable and doesn't require managing SMTP credentials.