AWS:実業務で使えるレベルの静的Webページの環境構築をする (独自ドメイン・フォーム付き)

# 背景
最近の会社がそれぞれ１つは持っているであろうもの、何でしょうか？
はい、その通り。「コーポレートサイト」です。大正解です。（にっこり）
ひょんなことからコーポレートサイトのインフラ構築をAWSで行う機会があったので、その備忘録として書きます。

# やったこと
正直、筆者はつい最近までAWS=EC2くらいのリテラシーの低さでした。
冷静に考えて、何もわからない...
そこでまず、ググります。GCP(Google Cloud Platform)やAzureとくらべて、ドキュメントが多いのがAWSの良いところです。

# 何をしたいか？（要件定義）
 - 静的なWebページのホスティングをしたい。
 - Webサイトにはお問い合わせ機能をつけたい
 - 問い合わせがあった場合、問い合わせ者に確認メールを、会社の担当者へ通知メールを送りたい
 - ドメインは新たに買う
 - www.example.com から [example.com](example.com) へのリダイレクト
 - ssl化もしたい

いろいろあるもんです...ただのコーポレートサイトなのに...

# 最終的に選択した構成
数日調べた結果、こんな感じになりました。
<img width="698" alt="スクリーンショット 2017-12-14 0.34.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/172187/4ea65123-39de-3ea3-83ef-a051cef60a33.png">

# それぞれのコンポーネントの軽い解説
### Route53
ドメインの購入から管理まで、一括して行ってくれる。
サブドメインに関しても管理が可能です。
もちろん、お名前.comなどで買ったドメインをRoute53にDNS移管することもできます。

### Cloud Front
AWSが提供する、CDN(Content Delivery Network)サービス。
世界中に存在するキャッシュサーバーがある特定のWebサーバーの代わりにコンテンツ配信を担ってくれます。
ここに後述するCertificate Managerで発行したSSL証明書を取り付けることで、通信のssl化が可能です。
Webサーバーが直接コンテンツ配信するのではなく、Cloud Frontが間に挟まることで、急激なアクセス増加に対してもしっかり対応できます。

### S3
イレブンナインの堅牢性を誇る、AWSのストレージサービスです。
少し古いですが、このページがわかりやすいです。
>https://dev.classmethod.jp/cloud/aws/cm-advent-calendar-2015-aws-re-entering-s3/

### Lambda
サーバーレスでコードを実行できるコンピューティングサービス。
流行りのサーバーレスアーキテクチャの一翼です。
ただ、使える言語に縛り（2017/12/14現在、Node.js・JAVA・C#・Python）があり、またメモリ量にも制限があります。

### API Gateway
APIを簡単に作成・運用できるサービス。
Lambdaと連携することで、Lambda関数に対してエンドポイントを張る事が可能。

### SES
AWSが提供する、Simple Email Serviceのこと。
Eメールの送受信プラットフォームです。

### 構成図には書いていないけど使った機能
Certificate Manager
ドメイン（サブドメインや、ワイルドカードも可能）に対してSSL証明書を無料で発行できる。

# 処理の流れと実装方法
以下に大まかに流れを書いていきます。細かい部分の情報は各自調べるのが確実です。
### ① コンポーネントのセットアップ
S3、Cloud Front共にセットアップしていきましょう。
２つのS3はそれぞれ以下の役割を請け負ってもらいます。
・静的Webサイトホスティング
・リクエストのリダイレクト

**バケット名とドメイン名を一致させる必要があります。**

また、S3にサイトのファイルをアップロードしましょう。
www.example.com の方はどっちみちリダイレクトされてしまうので、 [example.com](example.com) の方のみにアップロードします。
フォーム部分に後でajaxを仕込みますが、この時点では大丈夫です。

以下のページが参考になります。
>[Amazon S3 + CloudFront で始める静的サイトホスティング](https://kuune.org/text/2016/05/12/static-website-hosting-using-aws-s3-and-cloudfront/)

※ **静的Webサイトホスティング時には、S3のエンドポイント（S３を指すURLのこと）が通常と変わるので注意です。**
>[Amazon ウェブサイトと REST API エンドポイントの主な違い](http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/WebsiteEndpoints.html#WebsiteRestEndpointDiff)

　　　　　　
### ② ドメインの購入とルーティングの設定
Route53にてドメインの購入とルーティングの設定を行っていきましょう。


### ③ Cloud Frontを用いた通信のssl化
Certificate Managerを用いてSSL証明書を発行します。
それをCloud Frontに設定することで、通信のssl化が可能となります。
httpで来たアクセスをhttpsにリダイレクトするための設定はこちら。
>[ビューワーと CloudFront との通信で HTTPS を必須にする](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/using-https-viewers-to-cloudfront.html)

---

*これ以降の④〜⑦に関しては、このページにわかりやすくまとまっていました。*
>[AWS Lambdaで静的サイトにメール送信フォームを作る簡単な方法](https://blog.craftz.dog/aws-lambda%E3%81%A7%E9%9D%99%E7%9A%84%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AB%E3%83%A1%E3%83%BC%E3%83%AB%E9%80%81%E4%BF%A1%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%82%92%E4%BD%9C%E3%82%8B%E7%B0%A1%E5%8D%98%E3%81%AA%E6%96%B9%E6%B3%95-de8cba5e50a5)

### ④ メール送信用のLambda関数の作成
筆者はPythonで書きましたが、巷にはNode.jsで書いたコードが多いように思えます。
Pythonだとboto3というライブラリを使います。send_email関数しか使いませんが（笑）
> [Boto 3 Docs 1.4.8 documentation](http://boto3.readthedocs.io/en/latest/reference/services/ses.html#SES.Client.send_email)
[[boto3]SESを使ってメールを送信する](https://qiita.com/motchi0214/items/01b10b02745ec041c7cb)

コード量はそこまで多くはなりません。
フォームから送られてきた情報を、SESのライブラリ関数に渡す、というイメージ。
フォームに記入されたメルアドには確認とお礼のメールを、コード上に予め登録した管理者メールには通知のメールを送るようにしました。

※ **SES利用時には、初期設定が「サンドボックスモード」である　ことに注意しましょう。**
「サンドボックスモード」では、セキュリティの観点から認証済みのメルアドにのみメールを送れます。
お問い合わせした人のメルアドを事前に認証することは不可能ですので、もしメールを送信したい場合には「サンドボックスモード」の解除申請を行いましょう。
>[Amazon SES サンドボックス外への移動](http://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/request-production-access.html)



### ⑤ Lambda関数をAPI Gatewayで登録する
これによって、エンドポイントを作成し、コーポレートサイトのフォームに埋め込んだajaxからapiを介してLambda関数を叩けるようにします。
※ **普通にajaxからAPIを叩こうとすると、Cross Originに関してエラーが出てしまいます。**
これを防ぐためにはこれを参考に、CROSSの有効化を行いましょう。
>[API Gateway リソースの CORS を有効にする](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors.html)


### ⑥ フォームにajaxを埋め込む
⑤で作成したエンドポイントに対してajaxでフォームデータを送りつけます。

これにて完了です！素敵な静的ページライフをお送りください。