Email from Rails with SES on EC2
Amazon Simple Email Service (SES) is a high availability transactional email service. It is very inexpensive to send email with SES from an EC2 instance:
- $0 for the first 62,000 emails sent per month
- $0.10 per 1,000 emails sent thereafter
It is available in three AWS regions:
- eu-west-1 (Ireland)
- us-east-1 (Northern Virginia)
- us-west-2 (Oregon)
Configure AWS
If you have an AWS account, go to SES in your AWS console.
By default, SES in each region is in sandbox mode. Since sandbox mode only allows delivering to a whitelist of verified email addresses, it's unusable for a production web application.
To move out of sandbox mode, go to the "Sending Statistics" page and click "Request a Sending Limit Increase" to open a support request. It may take up to a day or so to be approved.
Once improved, the sending limit will increase from 200 emails/day to 50,000 emails/day and the restriction on delivering only to verified email addresses will be lifted.
Click "Email Addresses".
Click "Verify a New Email Address".
Enter an email such as support@example.com
.
Click the verification link that is emailed to the address.
This address is now allowed to deliver emails using SES.
If the Rails app is deployed to EC2,
the aws-sdk-*
gems will load credentials from the
EC2 instance's metadata.
The IAM role associated with the EC2 instance will be found.
Go to Policies in the IAM console. Click "Create policy". Choose "SES". Expand the "Write" section. Select "SendEmail" and "SendRawEmail". Create the policy.
Go to Roles in the IAM console. Find the role associated with the EC2 instance. Attach the policy.
Configure Rails
Install the official aws-sdk-rails gem.
It uses other aws-sdk-ruby gems
aws-sdk-ses
and aws-sdk-core
and adds an ActionMailer
delivery method.
# Gemfile
gem 'aws-sdk-rails'
# config/environments/production.rb
Aws::Rails.add_action_mailer_delivery_method(:aws_sdk, region: 'us-west-2')
config.action_mailer.delivery_method = :aws_sdk
# app/controllers/users_controller.rb
class UsersController < ApplicationController
def create
@user = User.new(email: params[:user][:email])
if @user.save
begin
Mailer.email_confirmation(@user).deliver_now
rescue Aws::SES::Errors::ServiceError => err
Rails.logger.info(err.message)
flash.now[:alert] = t('.failure')
render :new
end
else
flash.now[:alert] = t('.failure')
render :new
end
end
end
Once your sending limit has been increased, you can deploy.