頭の中は異空間

ものづくり中心

SESで受信したメールをLambdaを通して転送&S3に保存 - Lambda(Python)/S3/SES

 

SESを設定することでメール送受信が可能になります。ここでは受信したメールをS3に保存し、更に中身を転送してみます。

 

SES

ここではオレゴンのリージョンを選択します。認証済みドメインであればどんなメールアドレスでも使えます。ドメインの認証方法は

notwodaily.hatenablog.com

などを参照。

認証済みドメインを用いて、SESでメール受信する際にS3へ保存するトリガーを設定します。詳細なやり方は

docs.aws.amazon.com

に倣ってできます。

 

S3

メールを保存するためのバケットを用意します。LambdaのIAMで参照出来るようにプロパティでバケットポリシーを設定(Principalを"*"とか設定すればOK)。

この時点で、SESで認証済みのドメインにメールを何かしら送信すればS3に内容が保存されます。実際に試してみると、

f:id:notwo:20170101191043p:plain

 このようになるはずです。

 

Lambda(Python)

S3にメールが保存されたというトリガーを設定してその都度Lambdaの処理を走らせるようにfunctionを作成します。

function

f:id:notwo:20170101192409p:plain
f:id:notwo:20170101192415p:plain

上画像の通りに設定。

ここではS3から保存されたメールのオブジェクトを取得→中身を解析→SESで送信の流れで処理を書きます。解析でやることは主にread()したあとにsubject, body(plain text), body(html), fromの中身を取得することです。html形式とplain text形式の両方が含まれます(相手が対応していない場合はhtmlはないかもしれません)。

メール転送はsend_mailだけ、中身は単純です。ここで注意しないといけないのは、replyおよびSourceにはSESで認証済みドメインしか使えないということ。このため、もしfrom情報を含めたければsubjectかbodyのどちらかに仕込むことになります。

コードは下記。

 

code

from __future__ import print_function

import json
import urllib
import base64
import boto3

s3 = boto3.client('s3')

EMAIL_TO = "送信先アドレス"

def send_mail(from_address, reply, subject, body, html_body):
    client = boto3.client('ses', region_name='us-west-2')
    client.send_email(
        Source="noreplyなど、送信専用アドレス",
        Destination={
            'ToAddresses': [
                EMAIL_TO,
            ]
        },
        Message={
            'Subject': {
                'Data': subject,
            },
            'Body': {
                'Text': {
                    'Data': 'from: ' + from_address + '\n' + 'body: ' + body + '\n' + 'html_body: ' + html_body,
                },
            }
        },
        ReplyToAddresses=[
            reply,
        ],
        ReturnPath="noreplyなど、送信専用アドレス"
    )

def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8'))
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        mail = response['Body'].read().replace('\n','').replace('\r','')

        from_address = mail.split('envelope-from=')[1].split(';')[0]
        subject = mail.split('Subject: ')[1].split('To: ')[0]
        body = base64.b64decode(mail.split('base64')[1].split('--')[0])
        html_body = base64.b64decode(mail.split('base64')[2].split('--')[0])
        reply = "noreplyなど、送信専用アドレス"
        send_mail(from_address, reply, subject, body, html_body)
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e

以上です。細かく解説すると、

bucket = event['Records'][0]['s3']['bucket']['name']

でバケット名を、

key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8'))

でファイル名を取得しています。LambdaのトリガーにS3を設定した場合必ずこれで取得できる構造になっています。

肝心の内容は

response = s3.get_object(Bucket=bucket, Key=key)
mail = response['Body'].read().replace('\n','').replace('\r','')

でメールオブジェクトを読み取ったあと、それぞれ

from_address = mail.split('envelope-from=')[1].split(';')[0]
subject = mail.split('Subject: ')[1].split('To: ')[0]
body = base64.b64decode(mail.split('base64')[1].split('--')[0])
html_body = base64.b64decode(mail.split('base64')[2].split('--')[0])

で送信元、タイトル(subject)、本文(body)、本文HTMLの4つを取得しています。元々のメールオブジェクトの中身は改行付きで1つの文字列として扱っておりわかりづらいので、mail = の行で改行を削除しています。そのうえで、ほしい情報を前後の文字列を見てsplit関数でうまいこと取り出しています。ゴリ押しですね...

S3のメールをダウンロードして中身のテキストを確認するとわかりますが、bodyの文字列がbase64エンコードされています。これをbase64デコードするために

base64.b64decode

を用いています。そのため、頭の

import base64

を忘れないこと!

これ以外の情報がほしければ、同様にsplitを使って文字列を切り出して取得する。

 

ここではS3にメールを保存しっぱなしにしていますが、メールが溜まってきたら容量は圧迫されるので、転送完了後に削除しちゃっても良いかもしれません。

俺は資産1兆円の植物人間な人生よりも、資産100万円でも健康な人生を選ぶ。

 

タイトルの意味

別に資産100万円しかなくても満足って言いたいわけではありません(笑)もちろん金は必要ですが、それ以上に健康さが大事ということが言いたいです。健康体ならいくらでも稼げるので。

私は結構な数のサプリを買って食事もなるべく決めたものを食っています。月1~2万円くらいはサプリ代で平均的に消えていきます。サプリとかそんなにたくさん買って高いでしょ?なんて言われるかもしれませんが、今は高く感じても後々になれば気にならなくなります。寧ろ不健康で医者にかかり続けるほうがどれだけ医療費で家計を圧迫することか。

将来的に、というより老後はあきらかに体力が衰えて怪我をしやすく病気になりやすくなるのに、なぜ若いうちに対策してる人が少ないか、理解に苦しみます。

別にサプリ買わなくていいんじゃん?と言う人もいますが、アルギニンやビタミン○○などサプリがないと不足しがちな栄養素もあるのも(おそらく)知らず、しかもそういう人に限って普段の食事がデタラメだったり。笑わせるなと。

 

健康は長期的に見れば得だらけ。

 これを「それは知っている」といえる人はほとんどいないはず。なぜなら大抵はそういう行動をしていないので...身体を見ればそんな人は。面倒だけど、絶対若いうちから対策した方が良い。ずっと怠けてた人が老後から対策する余裕ないと思いますし。

健康でいることに普段は得に思わないかもしれませんが、病気になれば嫌でも気づきます。いや、高熱を出して身動き取れなくなった経験でも同様。辛い。苦しい。社会人なら働けないうちは金が入らない(有給使えば一時しのぎは出来る)。

金が入らないどころか医療費で金は出ていくばかりで、損しかしてない。 それがなければ痛い思いも辛い思いもしなくて済むしなにより金が浮くので、健康的でいることによって結果的に得しかしてません。

 

日本はサプリ後進国

発展途上国と言ってもいいかもしれません。国産どころか海外の(主にアメリカ製)サプリなんて持ってる人はレアでしょう。統計を見たわけではありませんが、おそらく人口の1割未満な気がします。1割と言っても、日本の総人口1億2千万(2016/12現在)、その1/10だから1,200万人。成人は1億人、この1/10なら1,000万。キリの良い数字ですが、なんだかこれでも実感より結構多く感じますね?正しい知識を持ってる人がこんなに多いとはとても思えません...

それと比較してアメリカはサプリ大国ですが、これは文化の違いが大きそうです。

news.livedoor.com

確かに、病気になったら医者に行こう、ではないアメリカ的な考えなら当然かもしれませんね。医療費がシャレになりません。

そして含有量も違います。成分表記があるのは当然として、具体的な量を計算、比較してみれば一目瞭然です。やってみましょう。

国内で売られている某サプリは商品1つ約250円で1回15mg, 計20粒の亜鉛が入っています。これをすべて摂れば、亜鉛は計15mg x 20 + 300摂取できる。

それに対して例えば私が以前買ったCountry LifeのCalcium Magnesium Zincは割引なし(iHerbなら割引されることが多い)で約2400円で1回3個分で50mg, 3計250 Tabletsなので 50mg x 250 / 3 ≒ 4166mg.

個数を合わせて比較すると、250 / 20 = 12.5だから、某サプリのほうは250 x 12.5 = 3700円にもなります!海外製に比べて1000円以上高い。。。

しかも後者の海外製は名前の通りカルシウム、マグネシウムも一緒に入っており、こちらはそれぞれ1回につき1000mg, 500mgも摂れてしまいます。ついでにL-グルタミン酸100mgも。圧倒的に破格だと思いませんか。

というわけで、サプリ先進国なアメリカから仕入れるのはおすすめです。サプリの種類も含有量も間違いなく勝っている。種類が多すぎて、逆に何買ったらいいか分からない、となるかもしれませんが(笑)

毎日摂取するとなるとそれなりに値段も張るし、別にサプリを買ってなくても健康な人はいると思いますが、そういう人は生活習慣が優れているので、そんな人達の食事を一朝一夕で素人が真似できるものではないと思います。仮にその人が毎日野菜を○○g食ってるし筋トレストレッチしてる、酒は週1回限り、睡眠時間は6時間確保していると言われたとして、真似できるでしょうか。

 

老後はロボットがいれば安心か?

安心ではないんじゃないでしょうか?

ロボットが今後増えてくれば直接動けなくても日常生活くらいはなんとかなるかもしれませんが、それって俺にとっては幸せではないです。

仮に資産が1兆円超えしていようが、病院でずっと何本もの管を刺されて身動きすら取れないまま何年も生きたとしても、それは生物学上は「生きている」ですが私にとっては「死んでいる」です。希望を持てないまま過ごすのなんてそんなもので、価値が無いと思っています。所詮は個人的な意見ですが。だから、自分がそうなったら延命はやらないでくれと家族に言っています。そもそも延命は無料ではないので、やりたくても出来ない可能性も高いのですが。

「ロボットがいてくれたほうが凄く助かる」は良いとしても、「ロボットがいないと何も出来ない」は違う。それだとまさにのび太です。ドラえもんも言ってるでしょう、日本中がのび太だらけになったら国が滅ぶと(笑)

 

健康は金で買う

タイトルと矛盾しそうですが、つまり金は健康のために使うのがベストと言いたいです。まず健康第一、余裕があればその他に、という優先順位です。カネを使わなくても運動は自力でできますが金をかけたほうが手っ取り早く肉体強化出来るし、知識を仕入れるには本を読む、プロと知り合うなどする必要があるのでただでなんでも出来るとは思いません。生きるのにも金がかかりますね。。。

 

まとめると

日常的に思っていることをざざっとまとめました。一昨年までは堕落した生活を送ってきたからこそ、心機一転、これからは健やかに生きようと思ってこんな生意気なことを書いています。でも、この考え方は中々理解されないんだろうなあ(;´∀`)少なくとも、国内でずっと右へ倣えしていたら絶対にこうはなりません(確信)私が偉そうに評価できることではないですが、周りに合わせることに一生懸命な人を遠目で見れるようになったら、なんとなく及第点な気がします。

ところで、タイトルは漫画「沈黙の艦隊」の海江田四郎のセリフ

牢獄の庭を歩く自由より 嵐の海だがどこまでも泳げる自由を
私なら選ぶ!!

をもじりました。元ネタはかつてない名言と思ったので、未だにお気に入りです(笑)この考え方が正しいかどうかはともかく、保守的な人間には一生言えないセリフです。これからリスキーな生き方をしていく自分にとって、何より励みになるし、大事なことだから心に留めておく必要があると思います。

というわけで今年も無事生き抜きます。

AWSでのサービス制作(申し込みフォーム) - AWS Lambda/API Gateway/S3/DynamoDB/SES/CloudFront/ACM/Route 53

 

f:id:notwo:20161222223656p:plain

概要

最初に紹介した記事

notwodaily.hatenablog.com

および、前回作ったテストアプリ

notwodaily.hatenablog.com

から一転して、本命のアプリを制作します。ここまで得た知識+αを総動員してその集大成を見せるときが来ました。大まかな図はdraw.ioで作りました。

 

IAM Role準備

ユーザー作成

ここでは開発者ということでdeveloperとでもします。

以下でdevelopersグループを作成してそこにユーザを紐付けて、作成

作成が終わったら、実際にS3やDynamoDBで操作ができるか、適当に触って確認してみましょう。

 

グループ作成

ダイアログでグループ名をdevelopersにします。Roleは

  • IAMFullAccess
  • AWSCertificateManagerFullAccess
  • AmazonS3FullAccess
  • CloudFrontFullAccess
  • AmazonDynamoDBFullAccess
  • AWSLambdaFullAccess
  • AmazonAPIGatewayAdministrator
  • AWSKeyManagementServicePowerUser
  • AmazonRoute53FullAccess
  • AmazonRoute53DomainsFullAccess

にチェックを入れて確認。最大10個までしか作れないので、一度設定して不要になったら権限を一部放棄しても問題ないです。アタッチ、デタッチは何度でも出来ますので。

これでもまだ権限的に相当強いですが、細かく設定するのが単に面倒なだけで。。本来は必要最小限にとどめたほうが良いのは言うまでもないです。

 

IAM Roleでログイン

上記まではroot相当の権限で操作していたはずですので、一旦ログアウトして、さっき作ったroleでログインし直します。

 

独自ドメイン取得/SSL準備

やり方は少し長くなるので別記事にまとめました。

notwodaily.hatenablog.com

 

API形だけ作成

Lambda関数作成に必要です。先にAPI名だけ用意します。

ここでのAPI名は制作するアプリ名としてちゃんとしたものをつけてあげましょう。

 

実データ配置(S3)

S3に必要なファイルを配置します。具体的にはLambda関数用のファイル(.py)をZIPで、他HTML/CSS/JavaScript/Image/Text(mail)をそれぞれ配置します。今回はこの方法で行きます。

その他、Lambda関数用ファイル(.py)と依存ライブラリをZIPにして別途LambdaへアップロードしてS3へPUTする方法もあります。

それについては

dev.classmethod.jp

の解説を見れば分かりやすいです。

 

バケットを作成してLambda関数用ZIPファイルを配備し、プロパティを覗いた例です。

f:id:notwo:20161127200352p:plain

S3へは直接アクセスさせずにCloudFrontを介する構成にしているので、ここでは公開後にプロパティのURLを叩いてもAccess Deniedエラーになります。

 

S3へのPOSTアクセス

これは禁止されているっぽく、実際にアクセスしてもMethodNotAllowedエラーが出ます。CORS設定してようが拒否られます。

stackoverflow.com

なのでPOSTしたいけどどうしてもS3のオブジェクトが欲しいって時はapi gateway経由で取得すると良い。

 

キャッシュコントロール

デフォルトでは設定がありませんがキャッシュが効いており、JSなど更新しても反映されるまでに時間がかかりすぎます。invalidationというのを使うらしい...

CloudFrontのDistributionsから該当のdistributionを選び、Invalidationsタブをクリックして、Create Invalidation

ここでパスを設定すればまとめてキャッシュを削除できます。毎回ここで消さないといけないのが面倒っちゃ面倒ですが。。

よく編集するJS, HTML, CSSは頻繁にアップすることになるので、まとめて

  /js/*
  /css/*
  /*.html

などして消せるようにしておくと楽です。

 

テーブル用意

DynamoDBにテーブルを用意します。データ構造を設計時に考えておくべきです。

セッションの永続化のためのテーブルを用意することも出来ますが、今回は単純な申込みフォームを用意するだけなので手を出しません。

noSQLなので複雑なオブジェクトも保存可能。だからこそあまり自由に作りすぎて後で階層が深すぎて取り出しに苦労する、なんてマヌケなことにならないように注意。

 

 

Lambda関数作成

必要なLambda関数を作成してAPIから叩けるようにします。

早速作ります。blueprintはBlank Functionを選択して最低限作ってもいいですが予めS3やDynamoDBを使うとわかっているので、それ用のblueprintを利用して書き換えたほうが楽でしょう。

runtimeをPython2.7に変更し、filterにとdynamodbと入れて出て来るmicroservice-http-endpoint-pythonを選択してNext

 

Configure triggers

API name:事前に作成したAPIの名前

Deployment stage:prod(最初のデプロイでは他にステージがないので選択出来ません)

Security:Open with access key(keyは未設定ですが、後でAPIコンソールで編集します)

 

Configure function

Name:実際に作るアプリに関する分かりやすい、愛のある名前をつけてあげましょう。

Description:どんな機能なのかを書いたらいいと思います。

Runtime:Python2.7

 

 

Lambda function code

Code entry type:Upload a file from Amazon S3

S3 link URL:別でS3に配備したLambda関数用ファイル(.py)のパス(https://s3.amazonaws.com/作成したバケット名/ファイル名)

 

Lambda function handler and role

HandlerAPIからLambda関数がコールされたときのエントリポイント。これの名前.pyがLambda関数のファイル名です。デフォルトのままでもいいです。こだわりがなければね。

Role:Create new role from template(s)

Role name:必要なroleは勝手に追加されていくので、ここではfunction名を決めるときの様に愛のある名前を!

 

HandlerはPythonのコード上ではデフォルトで

def lambda_handler(event, context):

となっている部分のことです。

ほかはデフォルトのままで。

Lambda関数はアップロード後にLambdaコンソール(画面)から修正できます。

 

Lambda関数作成後にエラーが出たら?

Create Function後は何かエラーが有る場合は下画像のようなwarningが出ます。 

f:id:notwo:20161127124957p:plain

Trigger作成に失敗しましたと言っています。Lambda関数作成時にTriggerにAPI Gatewayを指定したうえで、TriggerにまだAPIにリソースを追加していないからですね。メソッドをAPIのリソース直下に作成まで終わったらLambdaコンソール上でTriggerタブ→Add triggerからAPI Gatewayを追加すればOKです。さっきと同じ設定でいきましょう。すると作成したリソース直下に新たにANYメソッドが出来ているはずです。

 

IAM role違いによるエラー!?

後でAPI Gatewayを編集していくとわかりますが、Lambdaでは独自のIAMロールを用いるので、api gateway経由でPOSTすると

The role defined for the function cannot be assumed by Lambda

とか怒られるので、Lambda側で開発に用いているIAMユーザを許可させてやる必要があります。そこで、

dev.classmethod.jp

リソースベースのポリシー

の部分から下に倣うと出来ます。一緒にやってしまおう。

 

API作成

今回は予約フォームのために必要なAPIを準備します。

API名だけは先に用意してあるので、その中身を埋める作業です。まずルートリソース直下にリソースを作成します。次にそのリソース直下にメソッドを作成します。メソッドはLambda関数のTrigger設定時にANYが作成されているはずです。が、これは使いません。自分で新たにGETなりPOSTなり作成します。

 

API Key設定

dev.classmethod.jp

の通りの設定で大丈夫です(一部UIが異なりますが)。

ただし

docs.aws.amazon.com

にある通り、一度デプロイした後に出来るので、ここではまだ作らず先にデプロイまで進めたほうがいいですね。先に作成だけして無効にしておいてもいいですが。

 

CORS設定

後述するformとの連携のため(主にjqueryAPIの連携)、APIのCORS設定は必須です。

CORS設定は

qiita.com

とかを参考に。

はじめにAPIを作る時にCORS設定を同時に有効にしていなくても、後でリソースを選択してアクション→CORSの有効化、とすれば設定できます。しかもこちらならヘッダ情報も自動でつけてくれて大変便利!

統合リクエストのテンプレートマッピングも忘れずに。ここでどういう形式でLambdaにデータを渡すかを定義します。これがないとせっかくAjaxから渡したデータがlambda_handlerのeventに空で渡ってしまいます。

テンプレートマッピング公式ドキュメントを参考に。

 

フォーム作成

S3の実データ配置の一部ではありますが、制作するフォームについて補足します。

フォームの作りは

qiita.com

を参考にしました。API Gatewayへのアクセスは、すべてAjaxで行います。事前にgateway側でCORS設定をしておき、テンプレートマッピングも用意する必要があります。S3の項目で書きましたが、formを作成したとしてもmethodはgetのみです。で、

~~.on('click', function() {
  location.href="次画面のリンク";
}

みたいなことやれば出来ますが、かなりゴリ押し感もしますね。S3がただのストレージなので仕方ないといえば仕方ないのですが。

 

 

メール送信

SESの設定をします。それ用にドメインを持つ必要がありますが、

この辺は下記記事に別途まとめました。

notwodaily.hatenablog.com

 

ここまでで一通り完成です。とは言え、勿論まだ改善の余地だらけだし、正直これで無料期間終了したら月いくらになるのか計算もしてません。セキュリティ的にここがまずい、とか探せば出そうなのでこれを真似して作るなら注意。

 

作ってみてわかったこと

  1. とてもweb初心者には無理
  2. 言語そのものよりもインフラ、サーバ構築の知識が必要
  3. これ専用の学習コストは相当高い。Lambdaは利用できる言語にも縛られるので、すべてをAWS構築にする必要はないかもしれない。→今ではRubyC#も利用できるし、今後も追加されていくはずなので自由度は高くなる。
  4. 記事を書きながらだと理解が速い→おそらく正確に書くことが求められるから分からないところは調べざるを得なくなるので。

といった具合です。独自の用語を覚えたりどれとどれが組み合わせられるのか、その仕様までまず理解するところから始まります。何もwebを知らない初心者からすればただの迷宮です。

初年度無料は確かに魅力としてはでかいしスペックをほとんど気にせず使えるのはありがたいんですが、多機能なサービスには複雑さが伴うことは避けられないといえます。無理してこれを使うくらいなら、規模が小さいうちはサーバも全部自前で用意してCentOS7(本記事執筆時点での最新Ver)を入れるとか得意な言語によっては無料のサービス(Rubyが出来るならHeroku)があるのでそれをまず試してみるのもあり。

 

筆者自身この日までAWSド初心者でしたが、これで大凡の仕組みというか制作のキモくらいはわかったつもりです。これで堂々とAWS使えますって言える(;´∀`)

AWSでのメール設定/送信 - Lambda/SES (+お名前.com)

 

 

概要

Amazon SESを用いたメール送信について書きます。

業務用のメールアドレスなのでgmailよりは自分のドメインを持ったメールアドレスにしておいたほうが良いでしょう。ということで独自ドメインを取得したらメールアドレスもそこで受け取れるようにしておいて、かつ送信も出来るようにします。ここでは送信専用として

noreply@独自ドメイン

のメールアドレスを準備するとして進めます。
なお、SESはリージョンに東京がありません。今回はオレゴンを選択しています。

 

IAM

IAMグループに紐付ける権限は

AmazonSESFullAccess

をつけておけばいいでしょう。

 

SES

メールを自分とユーザの両方に飛ばします。スマホアプリの様にPush通知をするならSNSですが今回はPCも対応したいのと記録のためにメール送信としたいため、SESを用いることにしました。

全体的な流れは

qiita.com

で解説されているとおりです。

 

設定

操作方法は

docs.aws.amazon.com

に倣います。

  1. SES Home(Domains)にアクセス
  2. Verify a New Domainをクリック
  3. 独自ドメインなりメール送信に利用したいドメインを入力して、Generate DKIM Settingsにチェックし、Verify This Domainをクリック

ここまでで下画像の表示がされるので、指示に従って続きを進めます。

f:id:notwo:20161202160146p:plain

やることの概要としては、ドメインの発行元のDNSに、画像の中の設定(TXTレコード, CNAME, MXレコード)を追加しろと書いてあります。例えばお名前.comでドメインを取得したなら、お名前.comのドメインNaviから設定を入れてやればいいわけです。

その代わりにここでRoute 53にRecord Setを追加してやることで、ドメイン取得元に代わってSESでメールを受け取ることが出来るようになります。今回はSESでメールのやり取りをするので、上記画像ダイアログでUse Route 53をクリック。

→→※ただしこの場合はドメイン取得元でメールアドレスを受け取れなくなってしまいます。設定する場合は(英語ですが)説明文を注意深く読んでからやること。

チェックボックス全てにチェックが入っていることを確認して、Create Record Setsをクリック。

するとSESのDomainsにドメインが追加されたはずです。ただし今はまだpendingの状態です。この状態で数分待つとverifiedに変わります。筆者は30分くらい待ってやっと全部verifiedになりました。。

同時に、Route 53のHosted zoneを見ると確かにMXレコード等が追加されていますね。

f:id:notwo:20161202163721p:plain

次ですが受信ルールはRule SetsCreate a Recipt Ruleから作ります。

ここではドメインを入力して、次にEdit RuleでRule Setを設定するのですが、ここでは送信だけしたいので、特に触れません。

 

次に送信専用のメールアドレスを設定します。

docs.aws.amazon.com

に従います。

さっき認証が完了したドメインをクリックして出て来るMail From Domainをクリック→Set Mail From Domainをクリック。

Mail From Domain: 認証済みドメインサブドメインとしての名前をつけます。

Behavior if MX Record not found: Reject messageを選択

Set Mail From Domain

Publish Records Using Route 53をクリックしてMX, TXTレコードをRoute 53へ作成

SPFレコードにはチェックを入れず、他はチェックを入れてCreate Record Sets

これも数分(数十分?)かかるので待ちましょう。

ドメイン名がバッティングしてるとRoute 53にMXは作成されないので注意!作成時にエラーが出ないので、verifiedになる気配がなかったら、一度Route 53の設定を見てみると良いです。

SPF不要なのは

qiita.com

とかで解説されています。

 

サンドボックスからの脱出

SESをスタートしたばかりの時点ではサンドボックスの中にいるのでその制限を外してやります。

これ用にIAMは

SupportUser

があると良いでしょう。

テストメール送信も、これが完了してないと成功しないっぽいので、いち早く完了させてやるべきです。

docs.aws.amazon.com

に従います。応答があるまでしばらく時間がかかるので、その間は別の作業をするべし。

自分の場合は夜に申請して翌朝見たらサンドボックスから外しました的なメールが来ていてすぐにメール送信出来るようになりました。

 

SESでテスト送信

サンドボックスからの脱出が終わったら、Domainsから該当のドメインをチェックしてSend a Test Emailをクリックして、宛先を自分のアドレスにして送信してみましょう。エラーなく届くはずです。

 

Lambdaでテスト送信

これができればいよいよ好きな内容のメールを送れるようになります。

ただし、下記の通り、Lambda関数作成時に専用のroleを作成していると思います。このroleにはSESのSendEMail実行権限がないので、怒られます。

stackoverflow.com

ということでIAM Roleのポリシーを修正します。Lambdaで使用中のroleをIAMのAWS Console→ロールから探して、ポリシー名をクリック→ポリシードキュメントを編集して、"Action"の配列に"ses:SendEmail", "ses:SendRawEmail"もしくは"ses: *"を追加して保存しましょう。

f:id:notwo:20161217181451p:plain

設定が終わった後Testで送信すればエラーなく送信できるはずです。まずは自分宛てのメールを送信して試してみましょう。

 

S3にメール本文を配備

メール本文はコード上にあってもいいと思いますが、見やすさと再利用性のため分けたほうがbetterです。というのと上記スライドにある通り、添付ファイルとか容量の問題が出るためです。

というわけで配備しましょう。

配備するメール本文のファイルの形式をCloudFrontのBehaviorに設定するのも忘れずに!

それとメールはアップロードするだけでなく公開してないと読み込めません。

 

Lambdaと連携

API Gateway → Lambda → SESの連携をうまくやっている例は

raspi.seesaa.net

が分かりやすかったです。

宛先、Subjectなどは入力値や内部で用意した文字列を使って埋めていきます。

自分宛てに送信してみましょう。SESから送った場合、Lambdaに処理を書いて直接送った場合と同様、画面からAPIを叩いて送信出来るところまで確認できればOK。

 

動的なメッセージを送るには?

本文を動的に書き換える、例えば予約フォームに入れた氏名をメール本文に出したい場合はどうするか?といったものです。これは本文をS3に保存してLambdaで取り出して一部を書き換えて送信すればOK。

書き換えたいパラメータを何かしら分かりやすい変数名など埋め込んで用意し、Lambda内でbodyを読み込んで書き換えます。

Lambda(Python)からS3オブジェクトを取得するサンプルは

qiita.com

が参考になります。 

 

他には、HTMLメールとプレーンテキストメールどちらも送信出来るみたいですが、相手が受け付けているかわからないし、ここでは特に触れません。

SNSとかSQSも触って見たかったけど、今作ろうとしているサービスでは必要ないので、いったんこんな感じで締めくくります。

AWS上で独自ドメイン+SSLを実現 - S3/ACM/CloudFront/Route 53( + お名前.com)

 

概要

AWSで独自のサイトを作る際に、申し込みフォームや会員サイトを作りたい場合、SSLが必要です。その手続をCloudFrontを用いて安めにやってしまいましょう。特にHTML等をS3に配備してそれをSSL化するなら、絶対必要です。本家に記載されているとおり、請求額は実際のCloudFrontの利用料金となります。非常にリーズナブルですね。ここではその設定方法を調査し、実際にやってみたのでまとめました。

 

前提

独自ドメイン名とそのサブドメイン名が共に決まっている前提ですすめます。

 

独自ドメイン取得

お名前.comやムームードメインで、これから制作するサイト用の独自ドメインを取得します。AWSで使うために必要です。

登録が完了したら、メールアドレス設定します。ここではお名前.comの例で説明します。

ドメインNaviにログイン(お名前IDはメールに記載)して、オプション設定から、左サイドメニューのレンタルサーバー→メール専用サーバーのお申込みからメールサーバ申し込みします。
その後サーバーNaviにログインし、画面左のサイドバーからご利用サービス確認を開きます。

f:id:notwo:20161123170923p:plain


すると共用サーバーの欄にコントロールパネルのリンクがあるのでログインします。

※コントロールパネルをブックマークして直接そこからログインしようとしても弾かれます。サーバーNaviにログインしてそこから移動しましょう。
コントロールパネルに移動したらメール設定→メールアカウントから

qiita.com

に記載されている5つのメールアドレスを登録します(黒塗りの部分が、申請した独自ドメイン)。

f:id:notwo:20161123170753p:plain

これでメールが届くようになりました。しかしいちいちここにログインしていたら面倒なので、gmailに転送するように設定しました。転送するにはメール設定→メール転送をクリック。↑で登録した5つのメールアドレスは転送状態が無効になっているので、アクションの変更ボタンをクリックして普段使っているメールアドレスを入力します。

転送出来ることを、実際に上記いずれかのメールアドレスにテストメールを送って自分に届くことでチェックすること

ここまで問題なければACM申請に進みます。

 

SSL準備(ACM)

ACMの申請については事前に

qiita.com

ここを読み込んだ方がいいですね。証明書自体の料金は要らないらしい。

注意点として、この作業をrootアカウントでやってはいけません!CloudFrontで後で証明書を設定する時、選択できなくなります。予め、作る前に自分の権限がIAMで用意した権限になっていることを確認すること!

stackoverflow.com

確認できたら↓↓

 

申請はAWS Certificate Manager(簡単に SSL/TLS 証明書を作成、管理、配置) | AWSから。SSLをつける独自ドメインは事前取得が必要。

まだ発行済証明書がないので入力フォームが出るはずです。ドメイン名*に取得済みドメイン名を入力します。もし既存の証明書を利用するなら、証明書のインポートボタンをクリックします。ここでは新規で作ったドメインを利用する方向で進めます。

新たに取得したadmin@○○等のメールアドレスが有効になっていることが確認できているのなら、次へボタンを押して確定しちゃいましょう。

ここまでうまくいっていれば下画像の様なメールが来るはずです。

f:id:notwo:20161123172229p:plain

※ここでは5つのメルアドに届くメールすべて1つのgmailにまとめて転送させています。

メール(どれか1つで良い)に記載されているURLにアクセスして遷移先でI Approveをクリックすると下記画面が出て手続き完了です。

f:id:notwo:20161123172504p:plain

念のためCertificate Managerにアクセスしてみると、下記の通り証明書が発行されていることがわかります。

f:id:notwo:20161123172603p:plain

この証明書、画面からはダウンロードできないようです。

 

S3へバケット用意

お名前.comで用意した独自ドメインバケット名にして登録します。まだ実データは配備しなくて大丈夫です。ここの名前が間違っているとココから先の設定がうまくいきません。

 

CloudFrontへS3ドメインを設定

CloudFrontを開き、Webの方のGet Startedボタンをクリック。

Create Distributionの項目を下記の通り埋めていきます。

Origin Settings

Origin Domain Name:事前に作成したS3のバケット名(自動で出てくる)を選択します。

Origin ID:↑を入れれば自動で入力されます。

Restrict Bucket Access:Yes

今回はCloudFront以外からのS3へのアクセスを禁じるので、下記を参考にして設定しました。

qiita.com

dev.classmethod.jp

Origin Access Identity:Create a New Identity

Comment:何でもいいですが、ここではデフォルト入力例に従って「access-identity-バケット名」とでもしましょう。

Grant Read Permissions on Bucket:Yes, Update Bucket Policy

Alternate Domain Names:ここに独自ドメインを入れる。事前にACM申請の時設定したドメイン名がドロップダウンに表示されています。

Alternate Domain Namesサブドメインを含めた独自ドメイン

それ以外はデフォルトでOK

 

独自ドメインのための続きはRoute 53で設定します。

 

Default Cache Behavior Settings

ここは特段いじりません。

 

Distribution Settings

ここも特段いじりません。

オプションの項目にHTTP/2とかIPv6とか専門知識が出てきますが一応知識としてあったほうがいいので簡単に勉強を。

ISPのIPv6対応について

codezine.jp

入力が終わったらCreate Distributionボタンをクリック。

Behaviorsの設定もします。使うファイルはHTML/JS/CSS/画像(形式によって異なる)なので、それぞれ追加しましょう。HTTP to HTTPSのredirectを選択。

 

Route 53

tech.tanaka733.net

を参照して進めます。サービスからRoute53をクリックして、トップ画面からDNS managementをクリックし、Created Host Zoneをクリック。画面右側のフォームに下記の通り入力して、Createをクリック。

Domain Name:お名前.comで取得した独自ドメイン

comment:なんでもいいです。

Type:Public Hosted Zone

登録後の例↓

f:id:notwo:20161128075751p:plain

Route 53への登録が終わったら、今度はお名前.comのコントロールパネルまで移動して、NSレコード4つをDNS登録します。続きは↑の記事の通りで大丈夫です。

設定の反映に結構時間がかかるので、こういう設定は最初に一通り完了させておいたほうが気が楽です。

S3に配備したファイルのSSL化は以上となります。

 

念のため下記の通りになるかチェックを。

  • S3に何かファイルを配備して、プロパティに出るURLをクリックしてみましょう。中身が表示出来たはずです。
  • CloudFrontで設定した独自ドメイン/ファイル名のURLにアクセスしてみましょう。中身が表示出来たはずです。

 

 

API Gateway独自ドメイン

S3の設定とは別にAPI Gatewayでも独自ドメイン利用の設定をする必要があります。どうせなら合わせましょう。

 ココは後で書きます(たぶん

 

 

番外編:S3の独自ドメイン設定(CloudFront利用なしの場合)

S3でのファイル公開~独自ドメインアクセスは

qiita.com

にまとまっていて分かりやすいのでココにそってやると良いでしょう。

こちらはACM, CloudFrontが不要で、S3とRoute53のみの設定で出来ます。

 

番外編:間違ってACMをroot権限で作ってしまったら

下画像の様にCustom SSL Certificateが選択できなくなります。

f:id:notwo:20161130225758p:plain

こうなると面倒。やることはACMで証明書を発行し直しになります。作成直後すぐ気づけたなら作り直せばいいのですが、Route 53の設定を終わった後だとやっかいです。

  1. まずお名前.comのドメインNaviのネームサーバ変更で、最初にadmin@ドメイン名などのメールアドレスを登録したコントロールパネルのドメイン(dnsXX.gmoserver.jpの様な名前)に戻す必要があります。最大で24~72hかかります。
  2. 次に再度メールがadmin@ドメイン名などのメールアドレスにメールを送って、メールが届くことを確認してください。問題なければ、ACMの申請をやり直します。
  3. ACMで証明書を無事発行できたら、再度ドメインNaviでRoute 53で設定したNSレコードを使ってネームサーバ変更してください。
  4. CloudFrontのEditからCustom SSL Certificateが選択可になっていることが確認できればOKです。

 

番外編:Route 53/CloudFront/ACMの設定をしたはずなのにエラーが出る

qiita.com

の原因を辿ってみてください。感覚的にこの中だとCloudFrontの設定ミスが一番起こりやすいです。

 

総括

今回はインフラ寄りの知識が多かったです(寧ろそれしかなかった)。そもそもAWS全体的にそんな感じっていうか。。ただ言われたとおりのプログラムを書くだけのザ・プログラマにはちと辛いサービスであることは間違いありません。

もっともこれはインフラに造詣が深い人間が書いた記事ではないので、無駄がありそうです。もっとうまい方法を見つけたら修正します。

他の記事を沢山参照しまくらないと作れないよ本当。トホホ┐(´д`)┌

AWSでのサービス制作(テストアプリ)

 

概要

前回の記事

notwodaily.hatenablog.com

から、AWS Lambda + Amazon API Gatewayを用いたwebサービス制作について実際の制作の部分を抜き出しました。なるべく画像を使って説明します。今までに出た記事と比較すると、多少AWS側にUIの変更があるようです。そしてLambdaを見れば一目瞭然ですが、英語文章も出てきます。しかし文字の意味を捉えて行けば読み替えることは容易なので、焦らずにいきましょう(;´∀`)

登録の先から順を追って説明していきます。

※この記事は画像のせいで縦に糞長いです(泣)

 

テストアプリ

AWS Lambda

ステップ 2.1: Hello World Lambda 関数を作成する - AWS Lambda

に沿って作ります。しかしここでの説明はところどころ端折られているように思えて不満なので、細かい解説も入れてメモします。

 

まずここから、テスト用のfunctionを作成します。

f:id:notwo:20161113230257p:plain

Get Started Nowをクリック

次の画面が出たら、言語はPython2.7を選択します。

f:id:notwo:20161113230612p:plain

brueprintはhello-world-pythonを選択。filterにhelloと入れて絞り込みます。

f:id:notwo:20161113232146p:plain

そうしたら、configure triggersで空欄はAmazon API Gatewayを選択。

その他の入力欄はデフォルトのままです。

f:id:notwo:20161113232605p:plain
f:id:notwo:20161113232810p:plain

次はfunctionを作成します。

Name: myTestFunction

Runtime: python 2.3(pythonのバージョンはこれしか選べませんでした)

f:id:notwo:20161114070732p:plain

Role Name: myTestRole

※テストアプリなので名前は適当です。

ほかはデフォルトの入力のままです。

Nextボタンで作成すると、次の画面に遷移します。所謂設定確認画面です。

f:id:notwo:20161114072425p:plain

設定内容が正しいか確認して、問題なければCreate functionボタンで次画面へ。

この後API Gatewayの編集ページへ遷移しました。そこでリソースを定義します。

/myTestFunctionにカーソルが合った状態で、画面右上のアクションボタン→メソッドの作成→GET→✔マークをクリック

オプション設定フォームが現れるので、下記のとおりに入力

統合タイプ: Lambda関数

Lambdaのリージョンは

docs.aws.amazon.com

で確認できます。どうやら東京リージョンが出来ているようですので、これを使いましょう。

ap-northeast-1を選択して保存。 

f:id:notwo:20161114070958p:plain

これでfunctionを1つ作成できました。作成後でもさっき決めた設定を変更できるので、安心ですね!

Codeでデプロイするコードを編集できます。今回はpythonを選んでいるので、pythonコードがデフォルトで記載されています。ここではテストアプリなのでデフォルトのコードを使います。

ではせっかく作ったのでテストまでやりましょうか。

真ん中のTestボタンをクリック

f:id:notwo:20161114212512p:plain

といった具合にLambda functionを定義、テストまで完了しました。通常であれば必要な関数をこのように定義して必要に応じて呼ぶことが可能になります。そしてこれがLambdaに関数を定義する流れとなります。ここではデプロイまではしません。

 

Amazon API Gateway

f:id:notwo:20161114235910p:plain

上記で合わせてやってしまったので、割愛。とくにここではやることはありません。

 

S3, DynamoDBはテストアプリでは不要なため、特に触れません。本命のアプリ(別記事)で実際に利用します。そして今回は認証しないのでCognito未使用です。

 

 

テストアプリ(micro service: 最低レベルの小さなサービス)

ここからは、pythonのコードをデプロイし、リクエストを受け付けてレスポンスを返す普通のwebサーバとしての機能をLambdaに持たせます。やっとwebサーバっぽくなってきます。

まずLambdaコンソールを開きます。

f:id:notwo:20161115074614p:plain

このページ。

Create Lambda functionボタンを押し、microservice-http-endpointをfilter欄に入れます。出てきたカセットのうち、pythonのついてる方を選択します。

f:id:notwo:20161115075433p:plain

今度もデフォルトのままNextを押します。

f:id:notwo:20161115081611p:plain

今度のfunction名は「myPythonFunction」にします。

DescriptionにA simple backend (read/write to DynamoDB) with a RESTful API endpoint using Amazon API Gateway.とあるとおり、DynamoDBを利用したテストアプリが出来上がります。

Role nameはそれとわかる適当な名前で大丈夫です。権限については、下のフォームにあるpolicy templateで選んだテンプレートについている権限に加えて、フォーム上の説明(英語)にある通り、必要な権限が自動で入力されます。だから今のところは権限について気張る必要はありません。

たとえば、ここではmyPythonAppliRoleとします。

それ以外の項目はデフォルト値でOK。そのままNextボタンをクリック。

下の画像のようになるはずです。

f:id:notwo:20161119151627p:plain

入力に問題なければCreate functionボタンをクリックして、関数を作成します。

f:id:notwo:20161119152642p:plain

こんな感じでしょう。

Actions→Configure test eventをクリック。コードを下記の様な感じに編集。

f:id:notwo:20161120133023p:plain

まだDynamoDBを設定していないので、下記画像の様に

ResourceNotFoundException

のエラーが出ます。

f:id:notwo:20161119172911p:plain

じゃあDynamoDBの登録しましょう。と言っても何を入れたらいいかわからないので、ここではチュートリアルに沿って進めます。画面右上の「チュートリアル」ボタンを押して、解説に沿って入力して行きましょう。

f:id:notwo:20161120131827p:plain

作成後は下記画像のようになります。

f:id:notwo:20161120133927p:plain

 

 今度はLambdaのページに戻りましょう。LambdaのチュートリアルではAPIを叩けと言ってますが、先にそもそもTestが通るかをチェック。DashboardTestボタンをクリック。

f:id:notwo:20161120134725p:plain

status codeが200, bodyにjsonが返ってきているのがわかりますね。これでひとまず成功です。

しかしまだ肝心のAPI Gatewayが準備されていないのでこのまま外部からAPIを叩いても"Missing Authentication Token"とか返されてしまいます。今、TriggerタブのMethodがANYになっているので、ここにPOSTとGETを定義して、リクエストを受け付けられるようにします。ANYリンクをクリックして、前回の記事と同様に操作してそれぞれ用意します。

新しい APIからAPI名をpythontest, 説明は何でも構いませんので入れてAPIの作成ボタンをクリック

今、リソースが/(ルート)のままなので先にリソースを追加します。アクション→リソースの作成をクリック→新しい子リソースのリソース名をmusic, リソースパスをgetMusicにしてリソースの作成ボタンをクリック。

次に/getmusicをクリックしてGETメソッドを作成します。 

  • 統合タイプ:Lambda関数
  • Lambdaリージョン:ap-northeast-1
  • Lambda関数:さっき作ったLambda関数名

 

このままだとエラーが出るので修正します。リクエストパラメータをいじってもいいんですが面倒なのでcodeをいじります。

operation = event['httpMethod']

以下をすべてコメントアウトして

respond(None, None)

に置き換えてSave and Testボタンをクリックしてエラーが出ない(responseはnull)になることをチェック。

更にAPI Gateway側でもテストを押してみて、エラーが出ない(responseはnull)になることをチェック。

ここまで問題なかったら更に少しコードを書き換えて、DynamoDBに実際にデータを入れてみます。

codeを開き、

respond(None, None)

dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-1')
    table = dynamodb.Table('Music')

    Artist = "Artist Sample"
    songTitle = "songTitle Sample"

    response = table.put_item(
        Item={
            'Artist': Artist,
            'SongTitle': songTitle
        }
    )

に変えてAPI Gatewayからテストします。エラーなく完了するはず(responseはnull)。今度は読み込みも一応テストしておきます。

再度codeを開き、上記コードのdynamodb = 以下を下記の通りに修正します。

dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-1')
    table = dynamodb.Table('Music')

    Artist = "Artist Sample"
    songTitle = "songTitle Sample"

    try:
        response = table.get_item(
            Key={
                'Artist': Artist,
                'SongTitle': songTitle
            }
        )

    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        print("getItem succeeded:")
        print(json.dumps(response, indent=4))
    

また、頭のfromの塊を

from __future__ import print_function
import boto3
import json
from boto3.dynamodb.conditions import Key, Attr
from botocore.exceptions import ClientError

と書き換えてSave and Testボタンをクリックしてください。

これでテストが成功して下画像の通りに出力されていればOK

f:id:notwo:20161122213422p:plain

関数自体の戻り値はnullですがlog出力結果に確かにさっき入れたばっかりのデータが見て取れます。これでDB出力も問題ないですね。

 

pythonからDynamoDBを叩く方法は

docs.aws.amazon.com

を参考にしました。

 

そしてデプロイ。つまりはAPIを公開します。

デプロイする時はステージを選ぶのですがここでは何でも良いのでstagingとでもしましょう。

デプロイしたいAPI名を選択してリソースをクリック→アクションからAPIのデプロイを選択。ダイアログが開くので、例えば下記のように入力して、デプロイ

f:id:notwo:20161126143235p:plain

するとステージが選択されて今デプロイしたAPIの履歴やURLが見れるはずです。

f:id:notwo:20161126144206p:plain

ただし今回はルートリソース(/)の下にgetmusicをつけていますので、URLの後ろに/getmusicとつければアクセスできます。戻り値nullだけど。。

デプロイ後にAPIに修正が入ったなら再度デプロイすればいいです。

 

こんな感じでテストアプリとしては完了です。開発の大雑把な流れとしてはつかめてきたんじゃないかと思います。実際にwebアプリ開発する際にはcodeを書き換えたりIAM Roleを使いこなしていきますし、他にもS3やSESなどを組み合わせて本格的なアプリに仕上げていきます。

 

なんか無駄な操作をしているかもしれないので、この辺が詳しい人からしたらこうしたらいいのにっていうのがあるかもしれません。

【Python】【予約フォーム】AWS上でなるべく安くwebサービスを作ってみる

 

概要

AWS(Amazon Web Service)を始めようと思ったけど料金体系とサービスが複雑で分かりづらい!と思ったので、安く始めるために調べました。実際に筆者もまた新たにサービスを作るので、筆者の場合のプランについて説明します。

 

AWSについては

qiita.com

qiita.com

このあたりに分かりやすくまとまっています。

正直、公式HPを見ても情報が多すぎる上にあまりまとまりがないように見えて、そこだけですべて理解するのは難しいです。。せっかく分かりやすく解説してくれているサイトがあるのだから、実際に利用する前によく読み込んだほうが良いでしょう。

 

無料期間について

何と言ってもAWSの利用意欲を注ぐのがこれ。他は当然初月からしっかり請求されるので、月額の計算で萎えちゃったりします。

プラン的にも有料後も無理なく使えるものが揃っているので、無料期間終了後も長く使っていくのにも適していそう。

AWSのHPに載っていた無料期間については下記(16/11/13時点)。

f:id:notwo:20161113192258p:plain

 

無料期間は1年間も続くのでこの時点で破格なのですが、それでもやはり調子に乗って使っていると、有料期間ともなると馬鹿にならない請求が毎月来ます。シミュレーションで見れば一目瞭然...

 

制作物(予定)

とある予約フォームを制作します。

簡単な入力、確認、完了画面とメール送信機能だけしか作りません。

 

実際に利用する機能

たくさんの機能が有る中で、今回実際に利用するのは下記。

AWS Lambda

今回の記事の中で非常に重要。EC2ではなくこちらを使うのには大きな理由があります。

  • 金銭的にリーズナブル
  • 小規模な申込みフォームを作る程度なので、データ転送やストレージに大した規模を求めない(数百万数千万単位のアクセスが来ることがわかっていればこの限りではない)
  • プライベートネットワークは不要

↑とは逆にすでに大規模サイトを運用している、という場合はそもそも収入が相当あるでしょうから、まともにEC2のインスタンスを立てて24時間稼働をしても問題なく運営出来るかもしれませんし、そもそもそれだけ金が使えるならAWSでなく自前で用意したっていいですよね。筆者はそうではありませんので...

Lambdaについては

www.slideshare.net

この説明も役立ちました。今回は非同期ではないしNode.jsは使いませんけどね。

 

Amazon S3

要するにストレージ。料金体系は公式サイトよりも

qiita.com

を見たほうが分かりやすいです。こういう時本当にQiitaは頼りになります。

 

Amazon API Gateway

これとLambdaの組み合わせによってサーバレスなアプリケーション制作が可能になっちゃいます!

今回、下記で詳しく書きますがpythonを使うので

qiita.com

dev.classmethod.jp

この辺を参考にすると良いでしょう。

 

DynamoDB

フォームの入力データを保存するために必要。

qiita.com

ここが分かりやすかったです。

NoSQLだかなんだかにビビる必要はありません。要するにデータの保持の仕方がMySQLとかとはちょっと違うだけ。

 

Amazon CloudFront

所謂Amazon版CDN。とは言え今回は主に独自ドメイン+SSL設定のときにお世話になります。

 

Amazon SES

ここが分かりやすくまとまってました。

qiita.com

これと別でSNSを利用してもいいのですがそちらはモバイル端末へのPush通知用だということに対して作ろうとしているシステムはPCでも受け付けていること、内容的にどちらかと言うとメールに記録として残したほうが良いと思ったのでSESにしました。

 

言語は?

Pythonを利用します。これは言語のシェア率が低くなく、Lambdaで使える言語の中では学習する価値が一番高いと感じたので。

Pythonを使ったことがない筆者が1からやるのはちょっと骨が折れるかと思いきやそうでもありません。確かに色んなライブラリに手を出すとしたらきついのですが、今回はやりたいことが明確なので使用するライブラリも限定します。

サーバレスなのでBottleやDjangoは使わず、Lambda functionとしての部分に記述するだけです。

 

そして忘れずに、契約後にはこれを絶対しましょう!

qiita.com

1年間ずっと残り期間を見るわけにもいかないでしょうから、期限切れのときに気づかずに使い続けて利用費が跳ね上がるという悲劇を防ぐために重要です。

 

 

開発の流れ

ここは少し規模が肥大化しそうなので別記事としてアップします。本記事には概要だけ載せます。

前提の知識をつけたところで、やっと製作開始。前置きが非常に長くなりましたが、早速やってみましょう。

ちなみにまだ何もない真っさらな状態から始めるので、バックアップは取りません。

 

登録

まだAWSのアカウントがない前提ですのでアカウントを作成します。Amazonのアカウントとは別扱いです。

登録完了後はこんな感じのページが出ます。

f:id:notwo:20161115000252p:plain

登録が終わったばかりであればまだ請求額が$0のはず。念のため確認しましょう。

f:id:notwo:20161114234434p:plain

 

IAM Role/User, Groupの作成

qiita.com

IAMってなんのこっちゃ、という人はサーバでいつも使うユーザとかroot権限を思い浮かべれば分かりやすいです。

最初、AWSアカウントを解説したばかりで何もRole設定しないうちはroot権限と同等になっています。

16/11/16時点では日本語ではサービス→セキュリティ・アイデンティティをクリック→アカウント設定から入ってください。

グループを作成、次にユーザー作成です。

日本語では左メニュー「ユーザー」をクリック。

どういう条件か知りませんが、時々Create UserするときにThe request is invalidと出るときがありますが、その場合は何度かF5してやり直してみるとうまくいきます。

f:id:notwo:20161116080052p:plain

無事作成できると上記画面になります。 

パスワードの管理へは下記のように辿ります。

f:id:notwo:20161120175531p:plain

次はログイン。そこまで無事にできたら、ひとまずサインアウトして今度は「ルートアカウント認証情報を使用してサインイン」からデフォルトのアカウント情報でサインインし直しましょう。

adminはRoleとして強すぎるのでpythonサービス制作用に最低限のアクセス権限を持ったRoleを別途用意します。

 

 

サービスの選択

AWSのサービス群から必要な物を選びます。今選べるのはこんな感じ。

f:id:notwo:20161114234338p:plain

 

制作

CloudFrontでのSSL証明書登録、S3へのコンテンツ配備、APIの作成からメール設定などやることは盛りだくさん。ココに書ききるには狭すぎるので、別記事でアップします。

 

テスト

本当はここも書きたいのですがAWSでのデプロイやテストの自動化について1からやる流れについては後ほどまとめて記事を出したいと思います。

 

リリース

所謂デプロイ。とは言ってもS3やDynamoDBへのデータ登録やSSL設定は先にやってしまうので、API Gatewayのデプロイのことを指します。

どちらかと言うと制作に含まれてしまうので、ここで単体で書くことはありません。

 

(少し長めですが)総括

webサービスは便利なツールですがそもそも自分がやりたいことが明確でないのにwebサービス作ろう、とはならないはずなので、後はそんな人に必要なのは頭を使うことだけだと思います。今や様々なサービスとかツールが出回っているから、どれを使ったら自分に合うのかを設計前の段階に洗い出す。そしてそれらツールのうち料金プランとスペック的に無理のないものを選んで、必要なら乗り換えたりプランを変更したり、後から柔軟にやりくりするだけ。言ってみれば単純ですがそのためにはたくさん情報を得る必要があって1から自分だけで勉強するのは大変なので、今度はそのために情報を分かりやすくまとめてくれているQiitaやDevelopers IO、企業の開発者ブログ、はてなブログの一部の記事あたりを探っていく感じですね(ググった結果たいてい良記事はこのあたりに落ちていることが多いです)。

 

逆に一番ナンセンスなのは、トレンドというか新しいから大丈夫だろう使っちゃえというパターン。最新の技術だとサポートが行き届いていなかったり、ドキュメントが不十分だったりもします。そして本当にそれが自分たちに合うのか考えもせず取り入れるのは甚だ疑問です。せっかく参考書やネットで調べ放題なんだからそういった財産をフル活用して本当に役立つものを限定的に使っていく。

かつ知識がないとそもそも選定しようがないので、最新情報には触れていく。役立つなら取り入れる。この繰り返しです。筆者もそうしていくし、きっと世の中の”出来る”エンジニアと言われている人はこんなスタンスで仕事しているに違いない。限られた時間内で目的を達成するためには必然的にそうなるから。

 

本記事はAWS学び始めの初心者が理解したこと、実際に使ってわかったことを自分用メモ&なるべくこれから触る人向けに分かりやすくまとめたつもりですが、間違いもあるかもしれません。作っていっておかしいな?と思ったら後から随時修正を入れていきます。