「Amazon Web Services 定番業務システム12パターン設計ガイド」を読みながら実際に構築する⑤ 〜RDS、S3、CloudFront〜

# 概要
自分は普段Webやアプリのバックエンドエンジニアとして従事しており、ここ1年はずっとアプリのバックエンドとして、開発、保守を担当しています。
インフラは当然のようにAWSが使われていますが、構築と保守自体はアウトソーシングされているため、設定変更などは依頼ベースとなっています。
そんな事で知見はある程度貯まっていくのですが、自分で触らない以上最低限のレベルには到達出来ないという想いから本を買って実際に手を動かす事にしました。

まず、以下の本が評判良かったのでAmazonで即購入しました。
<a target="_blank" href="https://www.amazon.co.jp/gp/product/B01IB6Q1CA/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B01IB6Q1CA&linkCode=as2&tag=amazooooooooo-22&linkId=2c5db08621964edf2076fdd39e0022b3">Amazon Web Services　定番業務システム12パターン設計ガイド</a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=amazooooooooo-22&l=am2&o=9&a=B01IB6Q1CA" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

本に書いてある事はなるべく書かないで、それ以外にやった事や、本当にど素人だとつまづきそうなところ、自分もハマったところを中心に書いていこうと思います。

過去記事
[① 〜VPC、サブネット、EC2、セキュリティーグループ〜](https://qiita.com/tera78/items/ff3b521ff87a65d98b18)
[② 〜Route53〜](https://qiita.com/tera78/items/9f95301e8b2ecb200e78)
[③ 〜ssh公開鍵認証〜](https://qiita.com/tera78/items/2c07f42320b489db7fdd)
[④ 〜AMI、ELB〜](https://qiita.com/tera78/items/5b728979eab911c775b5)

### RDSを使ったDBサーバーの冗長化(P32)
---
RDS(Relational Database System)をマスターとスレーブの2台構成にします。以下図2参照。
<img width="1294" alt="004_001.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/0ebbf751-369c-8c9f-1f32-f62167f50ac1.png">

冗長性の重要性等は本を読んで頂くとして、RDS作成時の注意点として、恐らく普通に作成するとDBに接続出来ません。
RDSを作成したあとで良いのですが、RDSの詳細項目のセキュリティーグループ(以下参照)をクリックして

<img width="250" alt="005_001.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/c4488daf-8ed2-5251-614d-8d1426a9ad26.png">

以下の図のように、 **ソース** にアクセス元のEC2に設定しているセキュリティーグループを設定してあげる必要があります。
<img width="969" alt="005_002.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/b6289aa2-2bd2-5d35-5837-0d883857b922.png">

設定後はEC2より以下のコマンド後にパスワードを入力すると接続出来るはずです。```
mysql -h <エンドポイント名> -P 3306 -u <RDS作成時に作成したユーザ> -p
```


GUIのMySQLクライアントで繋ぐ場合は、sshオーバーする必要があります。Macの *Sequel Pro* を例にすると以下で接続出来るようになります。ちなみにWindowsは分からないですが、MacのMySQL Workbenchは不安定で接続出来なかったりするので、 *Sequel Pro* が機能も直感的でオススメです。Mac専用なのでWindows版はありませんが。。
<img width="718" alt="005_004.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/b0bbfc7e-8051-bc16-4101-61f5d0773bc1.png">

冗長化自体は、RDS作成時に設定するだけで勝手に作成してくれます。DB詳細メニューの一番下に表示されていました。

<img width="1057" alt="005_005.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/9ec809b2-62a4-964c-9806-12e826f2aa9f.png">

### 静的コンテンツを低コストに配信する(P35)
---
・ ここの設定方法の詳細は本にはほぼ載ってなくて自分も少しはまりました。やり方は色々ありそうなのですが、自分が今保守している環境を参考にしたいと思います（一応プロが作った環境なので。。）
・ まずはS3バケットを作成します。バケット名を **XXX.[ドメイン名]** とします（例：contents.tera78.work)
・ 作成したバケットのルートに適当な画像をあげます(例：animal.jpg)。以下参照。
<img width="307" alt="005_006.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/804356c3-3d19-4018-a170-b5240505d380.png">
===
・ 次にCloudFrontを作成します。AWSコンソールTOPより、 `CloudFront → CreateDistribution → (Web)GetStarted`
<img width="802" alt="005_007.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/b14d3604-122a-2070-7bb2-ad6e44f5ff69.png">
・ **Origin Domain Name** は 作成したS3バケットを選択します。これは、CloudFrontのオリジン名です。
・ **Restrict Bucket Access** は **Yes** を選択します。S3バケットへのアクセスを制限します。
・ **Origin Access Identity** は **Create a New Identity** を選択します。S3アクセス制限用に、CloudFrontユーザのIDを払い出し、後でS3側に設定する事でCloudFront経由のみのアクセスを許可するために必要です。

<img width="752" alt="005_008.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/8baca0b0-2f13-7325-9ec2-bc5e4bfd239d.png">
・ **Alternate Domain names(CNAMEs)** は、S3のバケット名を入れます。今回しようとしている設定には不要ですが、CNAMEでアクセスする事も可能です。
・ 後は ```Create Distribution``` ボタン押下して、15分ほどお待ちください。

---
<img width="979" alt="005_009.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/c53d8c1d-e660-7ddb-512f-275f0f8dc8c5.png">

・ 15分お待ちくださいと言いつつ、S3のアクセス制限設定が必要なので、S3の上記バケットポリシーの画面に遷移し、以下のJSONテキストを入力してください。

```
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity 【 Origin Access Identity 】"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::【 S3バケット名 】/*"
        }
    ]
}
```
・ 【 Origin Access Identity 】と【 S3バケット名 】は環境に合わせて変える必要があります。【 S3バケット名 】はいいとして【 Origin Access Identity 】ですが、CloudFrontコンソール画面の **Origin Access Identity** の **ID** にある値を入れてください。
<img width="544" alt="005_010.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/9fc3c0c8-269a-2afb-d85a-3fec06a994d9.png">
・ Jsonの ```Principal``` は ```リソースへのアクセスを許可または拒否するユーザー、アカウント、サービス、または他のエンティティを指定``` をする部分なので、 ```"*"``` として全公開でもアクセス可能なのですがこれだとCloudFrontを経由せず、直接S3にアクセスが可能になってしまいます。

---
・ 次に、Route53にAレコードを作成します。CloudFrontは、ドメインネームとして、 **XXX.cloudfront.net** というドメインが設定されるのですが、 **XXX** は意味の無い適当な文字列なので、意味のあるURLでアクセスするために必要です
<img width="430" alt="005_013.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/56b86dc2-81e9-96ba-7c0a-3a8cb2a47e48.png">
・ **Route53** の **Create Record Set** より、 **Name** は CloudFront経由でアクセスしたい名前(S3バケット名等が分かりやすくていいかと思います)、 **Type** は **A - IPv4 address** 、 **Alias Target** は、 CloudFrontのドメイン名 **XXX.cloudfront.net** を設定し、**Save Record Set** でAレコードの設定完了です。

---

・ CloudFrontの **Status** が **Deployed** になれば全ての準備完了です。

---
・ まずはS3のURL(**[バケット名].s3.amazonaws.com**)に直接アクセスしてみますが、 **AccessDenied** エラーが出て、パスは合っていますが、アクセス権が無い事が分かります。

<img width="485" alt="005_011.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/d6dcd0a0-5540-66dd-f0f5-c62742e057fa.png">

・ 次にCloudFront経由( **[Route53で作成したAレコード名]/[画像ファイル名]** )でアクセスします。見事に可愛い動物の画像が出ました。実際はhtmlの中などから画像やcssやjsなどをリンクする形になるかと思います。
<img width="434" alt="005_012.png" src="https://qiita-image-store.s3.amazonaws.com/0/113039/fa19c4fa-f7e9-0c3f-7219-58318bb59426.png">
---
今回はここまで。**1-2[パターン2] コーポレートサイト** は終了し、次回は **1-3[パターン3] 性能重視のイントラ Web** に入ります。