【AWS】Amazon SES / Messaging・Route53を用いてドメインメールを送信する

# TL;DR;
Railsアプリケーションから、**noreply@my-domain.com**のような形式でドメインメールを送りたい．

- メールサーバーはAmazon SESを使用
- RailsアプリケーションからAmazon SES APIを用いてメール送信リクエストを送る
- DNSはRoute53を使用
- ドメインはお名前ドットコムで取得

今回はRailsアプリケーションからSDK経由でメール送信するが，他のアプリケーションでもAWSの設定は同じ．DNSやドメイン取得も他のサービス使ってもよい．

# ~~(追記)2017年8月現在 Messaging に名前が変更されてる~~

# (追記)2019年12月現在 CustomerEngagement に名前が変更されてる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31862/d9f8c87e-8a73-85ec-8e36-80e7a93b9321.png)


Simple Email Service > US West(Oregon) と選択していくと，今まで通りのSES画面に遷移する．


# 検証環境

- Rails 5.0.0.racecar1
- Ruby 2.3.1
  
# SES設定
![image](https://qiita-image-store.s3.amazonaws.com/0/31862/31113ec0-aae4-f2a8-12ba-63888e585b62.png)

## リージョン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31862/5cd12c4c-f87e-00b7-afdf-e8e768ee8b0e.png)

~~2016年7月現在，SESは下記3リージョンからしか選択できないので，Tokyoリージョンが使用できない．~~

2019年12月現在は，6つのリージョンが選択可能になっている．

今回は "US West (Oregon)" を使用する．

## ドメイン検証
SESのメールアドレス検証では，認証した任意のメールアドレスから送信を許可することができるが，メアドが変わる毎に認証しないといけないのと，登録したメールアドレスにAWSからのメールを受信して認証する必要があるため，送信専用メアドなどは登録できない．
そのため今回は，特定のドメインからであればどのようなアドレスでも送信できるようにドメイン検証をする．

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/39019696-d75f-5cb0-4301-2167f384ca16.png)


- Identity Management > Domains > Verify a New Domain
- ドメイン名に "my-domain.com" を入力し，Generate DKIM Settings にチェックを入れる．


![image](https://qiita-image-store.s3.amazonaws.com/0/31862/467a2e9d-85ae-4903-280f-51f035fd3389.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/01066b32-0772-b07e-7290-92ac8023e80e.png)

## 既にRoute53を設定している場合

`Use Route 53` ボタンが表示される.
このボタンをクリックすると，レコードの設定までを自動でやってくれる．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/7c42e67c-a5e5-ccd6-4cec-ebdfefc07fe8.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/727e54e5-032b-36ca-4356-0ebdfb8dbb48.png)


Identity Management > Domains > my-domain.com にアクセスすると，"Verification" と "DKIM" のStatusが "pending verification" になっている．

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/6f7d770a-91d2-34be-f4fb-906d2c9e14f7.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/6c1d2daa-a39a-9b73-72ea-a2c4ece689c2.png)


# ドメイン取得
今回は，お名前ドットコムでドメインを取得した．（Route53でドメイン取得してもいい）

# Route53設定
![image](https://qiita-image-store.s3.amazonaws.com/0/31862/07f72864-992d-8571-7c72-1689b49872e0.png)

## ドメイン設定

- Hosted zones > Create Hosted Zone からドメインを設定する．
- 作成すると，NSレコードとSOAレコードが作成される

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/1527273d-dff7-f20e-6f77-9e3b80cf44cf.png)

## NSレコード

NSレコードはお名前ドットコム側に設定する．


## TXTレコード・DKIMレコード設定

Route53にSESに設定したドメインと同じドメインを設定すると，下記のボタンが表示される．
"Verification", "DKIM" それぞれで Use Route 53 > Create Record Sets をクリックすると，Route53にTXTレコードとDKIMレコードが自動的に設定される（手動で表示されているレコードを設定するのと同じ結果になる）．

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/6b39cfe6-7955-827e-cc0a-b98788c5d476.png)

各レコードを設定後，最大72時間で "pending verification" -> "verified" に変わる．
（今回の検証だと1日かからなかった）

# サンドボックス状態を解除 (2017年9月現在、サンドボックス解除をしなくても設定が完了できる模様)

ここまで登録した状態だと，送信制限が掛かっているサンドボックス状態になっている．

Email Sending > Sending Statistics > Request a Sending Limit Increase から制限解除の申請をする．

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/2efca557-4b0b-2072-f6fc-086d44433b27.png)

Regardingが "Service Limit Increase"，Limit Type が "SES Sending Limits" の状態で，AWSのSupport Centerのページが表示される．
各項目適当な数値や説明文を追記して申請を完了する．

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/439477ce-6e63-ad45-c5a8-96ccbfc564ff.png)

1日くらいするとAWSからメールが届いて，制限解除が完了する．

# 設定完了

最終的に下記のような状態になっていればおｋ．

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/a9686d3d-9b69-a80d-ce8c-84d1c116339c.png)


# Test Mail が送信できることを確認

- Identiity Management > Domains > my-domain.com を選択 > Send a Test Email をクリック
- 適当な送信アドレスでメールが正常に送られることを確認

# AWS IAM 設定
![image](https://qiita-image-store.s3.amazonaws.com/0/31862/e29a0825-a881-9153-af35-f224a9ea0cc9.png)

AWS SDKで使用するアクセスキーを作成する．

## 新規ユーザー作成

IAM > Users > Create New Users から新規ユーザーを作成する．
作成後に生成される `Access Key Id`, `Secret Access Key` を後ほどSDKで使用する．
※ **Secret Access Key 新規ユーザー作成時にしか作成されないので，値を無くしたり，また，流出しないように注意**

なお，SES > Email Sending > SMTP Settings から SMTP Credentials も生成することができるが，credentialは今回は使わない．`Note:` にも記載があるように SMTP Credentialsは AWS access key とは別の識別子．

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/b8ef14fa-f16f-f30b-e4fa-cf56177afc79.png)


## 権限作成

作成したユーザーの詳細ページ > Permissions > Create User Policy > Policy Generator からSES用のPermissionをユーザーに割り当てる．

 ![image](https://qiita-image-store.s3.amazonaws.com/0/31862/b45f2293-af19-a502-ea03-14794c886952.png)

Add Statement > Next Step で下記が表示されるので Apply Policy で設定は完了．

 ![image](https://qiita-image-store.s3.amazonaws.com/0/31862/07b8c1b4-0176-f3d9-dea9-ecdea794afc3.png)


# Railsアプリケーション設定

## SDK
[aws-ses](https://github.com/drewblas/aws-ses)を使用する．
このgemでAWS SES API経由でメール送信する．

```rb:Gemfile
gem 'aws-ses', '~> 0.6'
```

## 設定ファイル

- initializersにaws用のファイルを追加
- `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`は IAMユーザー作成時の値を使用
- `server` は選択したリージョン毎に異なるので [Regions and Amazon SES](http://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html) から `API (HTTPS) endpoint` を確認（SDKのデフォルトは `email.us-east-1.amazonaws.com`）

```rb:config/initializers/aws.rb
ActionMailer::Base.add_delivery_method :ses,
                                       AWS::SES::Base,
                                       access_key_id: ENV['AWS_ACCESS_KEY_ID'],
                                       secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
                                       server: 'email.us-west-2.amazonaws.com'
```

ActionMailerのdelivery_methodに `:ses` を設定する．

```config/environments/development.rb
config.action_mailer.delivery_method = :ses
```


## メールクラス

RailsGeneratorで雛形を生成する．

```bash
$ rails g mailer custom test
```

`default from` を追加し， `mail to:` のメアドを受信可能なアドレスに変更する．

```rb:app/mailers/custom_mailer.rb
class CustomMailer < ApplicationMailer
  default from: 'MyDomain <noreply@my-domain.com>'

  # Subject can be set in your I18n file at config/locales/en.yml
  # with the following lookup:
  #
  #   en.custom_mailer.test.subject
  #
  def test
    @greeting = "Hi"

    mail to: "任意のメールアドレスに変更"
  end
end

```

## 送信確認

RailsConsoleからメール送信してメールを受信できれば完了
（迷惑メールBOXなどに入ってないことを確認）

```bash
$ rails c
irb(main):001:0> CustomMailer.test.deliver_now
```


# 参考資料
- [Amazon SES でのドメインの検証](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/verify-domain-procedure.html)
- [Amazon SES における DKIM を使った E メールの認証](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/dkim.html)
- [リージョンと Amazon SES](http://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/regions.html)
- [Amazon SESによるメール送信環境の構築と実践](http://dev.classmethod.jp/cloud/aws/amazon-ses-build-and-practice/)