1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

EC2にデプロイしたDjangoからAWS SESを使う

Posted at

はじめに

EC2からメールを送信する方法はいくつかあります。
自分用メモとして、その中でも一番メジャーであろうSESを使ったメール送信について残しておきます。

ドメインの取得

メールを送信するためにはドメインが必要となります。(~@mail.comの部分ですね)
こちらは以下のサイト参照で取得しておきましょう。

Route53から直接購入する場合

「ドメインのRoute 53への登録」までですね。
https://dev.classmethod.jp/articles/relaxing-send-limit-and-removing-sandbox-restriction-in-ses/

他のサービスを使う

ドメインはRoute53で買わずとも、他のドメイン登録サービスを使うこともできます。
有名なのはお名前.comですね。
先にドメインを取得しておいて、お名前.comの設定ページのネームサーバー欄にRoute53のNSレコードを貼り付けたら完了です。
お名前.comで取得するとキャンペーンとかで安くなる事が多いのでおすすめです。

こちらもDevelopersIOさんのサイトを貼っておきますね。
https://dev.classmethod.jp/articles/route53-domain-onamae/

Django側

django-sesのインストール

ドメインの取得ができたら次はDjango側での作業です。
DjangoではDjango-sesをインストールすることで簡単にDjangoからSESを操作する事ができます。

pip install django-ses

django-sesではbotoというpythonライブラリとAWSサービスをつなぐものを必要としますので、こちらもインストールが必要です。

pip install boto3

これにより、Djangoの標準からSESを使う事ができるようになりました。

setting.pyの修正

setting.pyを開いて以下のように修正しましょう。
なお、...は省略の意味です。

INSTALLED_APPS = [
    ...
    'django_ses' #追加する

]
...
AWS_SES_REGION_NAME="ap-northeast-1" #追加する
AWS_SES_REGION_ENDPOINT="email.ap-northeast-1.amazonaws.com" #追加する
EMAIL_BACKEND="django_ses.SESBackend" #追加する
DEFAULT_FROM_EMAIL = "no-reply@mail.com" #追加する、@の後ろは取得したドメイン

各項目について簡単にメモしておきます。
とは言っても名前でなんとなくわかりますけどね。

AWS_SES_REGION_NAME
SESを動かしているリージョンを選択します。東京リージョンなら例の通りです。

AWS_SES_REGION_ENDPOINT
SESのエンドポイントです。Djangoはここにアクセスします。
似たようなものにSMTP endpointがあります。こちらではないのでご注意ください。

自分の認識だと、AWSサービスとしてではなくシンプルにSMTPサーバーとしてSESを使いたいときに使うものだと思ってます。

EMAIL_BACKEND
その名の通り、Django内でEmailサービスの根幹となるアプリケーションを選択します。
デフォルトでは以下の様になっていると思います。

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

これはSMTPサーバーを指定してDjangoからメールを送るときのデフォルトのバックエンドです。
setting.py内でSMTPサーバーの設定をすれば、このデフォルトのバックエンドでメール送信をする事ができますが、今回はdjango-sesのバックエンドを指定しておきましょう。

DEFAULT_FROM_EMAIL
メールの送信元を設定します。
これを設定しないとデフォルトでwebmaster@localhostが送信元に設定されてしまいます。
SESにlocalhostのドメインはないのでエラーが出ます。

Django側の設定は以上で終了です。

EC2側

続きましてEC2側の設定です。
Djangoが動いているEC2とSES間の認証にはIAMロールを使用します。

先程のsetting.py内に

AWS_ACCESS_KEY_ID = "***********************"

AWS_SECRET_ACCESS_KEY = "***********************"

のようにIAMユーザーのアクセスキーとシークレットアクセスキーを入力することでも認証することは可能です。
ただ、環境変数ならまだしもアクセスキーをプログラム中に書くのはまずいのでIAMロールを使用します。

ポリシーを作成する

IAMのコンソール画面からポリシーをクリックして、ポリシーを作成をクリックしましょう。

ポリシーを入力

ビジュアルエディタから入力しても良いですが、とくにこだわりがなければJSONでこの3つを書いておけばいいかと思います。

↓コピー用

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

GetSendQuotaですが、SESには送信できる上限値があって、GetSendQuotaで知ることができるみたいです。
そのためロールにこれがないとエラーとなります。
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/manage-sending-quotas-monitor.html

あとは画面にしたがって進んでいきましょう。
途中で名前を設定する画面がありますが、この名前はあとで使うので覚えておきましょう。

スクリーンショット 2022-04-29 0.10.48.png

これでポリシーは完成しました。

ポリシーをアタッチしてIAMロールを作成

次にいま作成したポリシーをIAMロールを作成してアタッチします。
ロールをクリックしましょう・
スクリーンショット 2022-04-15 23.44.01.png

ロールを作成をクリック

スクリーンショット 2022-04-15 23.44.21.png

エンティティ選択

今回はAWSサービスにIAMロールをつけるので、AWSサービスを選びます。
ユースケースはEC2を選んで次へいきましょう。
スクリーンショット 2022-04-15 23.44.52.png

アタッチするポリシーを選択

続いて作成中のロールにアタッチするポリシーを選択します。
ここには自分が作ったポリシーだけでなく、AWS側で最初から用意されているポリシーも表示されています。
先ほどポリシー作成時につけた名前「SES_SendMail」で検索しましょう。

見つかったらチェックを入れて次へ進んでください。
スクリーンショット 2022-04-29 0.16.07.png

名前を入力して作成完了

最後にこのロールの名前を入力して作成ボタンを押しておきましょう。

お疲れ様でした!これでロールの作成まで完成しました。
スクリーンショット 2022-04-29 0.16.53.png

EC2にアタッチ

ここまでくればあともう少しです!

IAMロールを変更をクリック

スクリーンショット 2022-04-29 0.24.34.png

ロールを選択して保存

ここで先程作成したロールを選択してください。
もし、さきほどロールを作成する先にエンティティでEC2を選んでないとここに表示されないので注意しましよう。
スクリーンショット 2022-04-29 0.24.59.png

Django側の設定

こんな関数を作っておいて、呼び出してやればメールを送る事ができます。

from django.core.mail import EmailMultiAlternatives

def send_email(subject,text_content,html_content,from_email,to_emails):
    msg = EmailMultiAlternatives(subject, text_content, from_email, [to_emails])
    msg.attach_alternative(html_content, "text/html")
    msg.send()

https://docs.djangoproject.com/ja/4.0/topics/email/
詳しくは、Djangoの公式ドキュメントに書いてありますが簡単に説明しますと、
subject:メールタイトル
text_content:プレーンテキストのメール本文(受信者がHTMLメールに対応してない場合に表示する用)
html_content:HTMLで書かれたメール本文
from_email:送信元
to_emails:送信先(リストで指定できます。)

ちなみに試してはいませんが、HTMLメールを送る必要がない場合はこれだけでも送れるみたいです。

from django.core.mail import send_mail

send_mail(
    'Subject here',
    'Here is the message.',
    'from@example.com',
    ['to@example.com'],
    fail_silently=False,
)

まとめ

いかがでしょうか。
AWSではEC2にメールサーバーを建てなくても、マネージドサービスで簡単にメールを送信することができます。
しかも、今回のようにEC2にホストされているアプリケーションからSESを使ってメール送信した場合には、62,000通/月まで無期限無料枠があるので個人開発だとほぼ無料枠に収まるのではないでしょうか。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?