I previously wrote about integrating AWS SES with Rails using the aws-sdk-rails gem. While that approach works fine, I've since discovered an even simpler method - you don't need any AWS SDK gems at all. Rails' built-in SMTP support works perfectly with SES.
Hat tip to Justin Searls' excellent post on this topic, which I stumbled upon while researching this.
Step 1: Configure Production (AWS SES via SMTP)
Open config/environments/production.rb and add the SMTP configuration:
# config/environments/production.rb
Rails.application.configure do
# ... existing config ...
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
# Will vary by region (e.g. "email-smtp.us-east-1.amazonaws.com")
address: ENV["AWS_SMTP_ENDPOINT"],
# Create an SMTP user: https://docs.aws.amazon.com/ses/latest/dg/smtp-credentials.html
user_name: ENV["AWS_SMTP_USERNAME"],
password: ENV["AWS_SMTP_PASSWORD"],
# Encrypt via STARTTLS. See: https://docs.aws.amazon.com/ses/latest/dg/smtp-connect.html
enable_starttls: true,
port: 587,
# :login authentication encodes the password in base64
authentication: :login
}
endStep 2: Get Your SMTP Credentials from AWS
Unlike the AWS SDK approach, SMTP credentials are different from your regular IAM access keys.
- Go to the AWS Console and navigate to Amazon SES.
- In the left sidebar, click SMTP settings.
- Note your SMTP endpoint (e.g.,
email-smtp.eu-central-1.amazonaws.com). - Click Create SMTP credentials.
- This creates a special IAM user for SMTP. Give it a name like
ses-smtp-user. - Download or copy the SMTP username and password immediately - you won't see the password again!
Step 3: Add Environment Variables
Add these to your production environment (Heroku, Railway, or your server):
AWS_SMTP_ENDPOINT=email-smtp.eu-central-1.amazonaws.com
AWS_SMTP_USERNAME=AKIA...............
AWS_SMTP_PASSWORD=BK9E...........................Step 4: Configure Local Development
For local development, you don't want to send real emails. Use letter_opener to preview emails in your browser instead.
First, add the gem to your Gemfile:
# Gemfile
group :development do
# Preview email in the browser instead of sending
gem "letter_opener"
endRun the installation:
bundle installThen configure your development environment in config/environments/development.rb:
# config/environments/development.rb
Rails.application.configure do
# ... existing config ...
# Use letter_opener to preview emails in browser
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
endNow when you send an email in development, it will automatically open in your browser instead of being sent.
Step 5: Update Your Mailer
Make sure your mailers use a verified domain or email address:
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: "[email protected]" # Must be verified in SES
layout "mailer"
endTesting in Production (Rails Console)
Once deployed, you can test from the Rails console:
ActionMailer::Base.mail(
from: "[email protected]",
to: "[email protected]",
subject: "Hello from Rails & SES",
body: "This is a test email sent via AWS SES SMTP."
).deliver_nowIf it returns a <Mail::Message> object without errors, check your inbox!
Why SMTP Instead of the SDK?
- No additional dependencies - Uses Rails' built-in SMTP support
- Simpler configuration - Just environment variables, no gem setup
- Easier debugging - Standard SMTP errors are well-documented
- Works everywhere - Any hosting platform that allows outbound SMTP
Important Notes
-
SES Sandbox: New SES accounts start in sandbox mode. You can only send to verified email addresses until you request production access.
-
Verify your domain: Go to SES > Verified identities and add your domain. You'll need to add DNS records to prove ownership.
-
SMTP credentials are NOT IAM credentials: The SMTP username/password are specifically generated for SMTP access and are different from your regular AWS access keys.
-
Regional endpoints: Make sure your SMTP endpoint matches the region where you verified your domain.