AWSにWEBアプリの最小構成環境を作る

## この記事について

AWS上にWebアプリを構築する際のメモです。
既にWebアプリケーションは作成済みの前提とします。

## 構成図

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217094/a0fc21ea-00a8-02d4-42df-77f5766f6be5.png)

※ 構成図の作成ツールについて

たまに作るくらいならPowerPointかVisioで十分。自動作成ツールは利用料や学習コストが高くシロウトの手の出すのものではない。

### 参考資料

#### 書籍

全くの初心者はまず以下の本を読む。
[Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版](https://www.amazon.co.jp/dp/4822237443)

#### ウェブサイト

基礎知識

- [AWS クラウドデザインパターン](http://aws.clouddesignpattern.org/)
- [0から始めるAWS入門：概要](https://qiita.com/hiroshik1985/items/6433d5de97ac55fedfde)

各サービスの概要

- [「AWS is 何」を3行でまとめてみるよ](https://qiita.com/kohashi/items/1bb952313fb695f12577)
- [AWS シンプルアイコン(全52種類)の覚え方まとめ](https://qiita.com/szk3/items/eb78d8b9c60ec922e76b)

ツール

- [Windowsターミナルソフト + Rlogin が最高すぎる！！](https://qiita.com/murachi1208/items/d6e4ce7ba75f1625fe51)
 - pem形式のキーファイルを無変換で使える。Windowsならこれ一択。

作業手順


- [0から始めるAWS入門①：VPC編](https://qiita.com/hiroshik1985/items/9de2dd02c9c2f6911f3b)
- [0から始めるAWS入門②：EC2編](https://qiita.com/hiroshik1985/items/f078a6a017d092a541cf)
- [0から始めるAWS入門③：ELB編](https://qiita.com/hiroshik1985/items/ffda3f2bdb71599783a3)
- [0から始めるAWS入門④：RDS編](https://qiita.com/hiroshik1985/items/6643b7323183f82297b2)
- [EC2 + RDS によるミニマム構成なサーバー環境を構築してみよう](https://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/)

- [Amazon Route 53でドメインを購入する](https://dev.classmethod.jp/cloud/register-domains-route53/)
- [AWS：無料でSSL証明書を取得する方法](https://qiita.com/iwaseasahi/items/1687426add4124899fe3)
- [ELBにSSL証明書をインストールする](https://dev.classmethod.jp/cloud/aws/aws-beginner-elb-ssl/)

ネットワーク構成の考え方

- [AWSのネットワーク設計をサボらないでちゃんとやる](https://qiita.com/nisshiee/items/df4261132ec686964605)

ELBのメリット

- [１台のEC2でもELBを使うメリットについてまとめてみました](https://dev.classmethod.jp/cloud/aws/benefit_elb_with_one_ec2/)

## 構築手順

### 概要

基本的に「仮想ネットワーク構築」⇒「インスタンス作成」⇒「DNS等の設定」という順で作業を進める。

1. 仮想ネットワーク構築
  1. VPC
  2. サブネット
  3. インターネットゲートウェイ
  4. ルートテーブル
  5. セキュリティグループ
  6. データベースサブネットグループ
2. インスタンス作成
  1. EC2
  2. RDS
  3. EC2のコピー（任意）
3. DNS等の設定
  1. ドメイン取得 (Route53)
  2. 証明書取得 (Certificate Manager)
  3. ロードバランサ設定(EC2 ELB)
  4. DNS設定(Route53)

具体的な作業はリンク先参照。重要な設定のみを残す。

### 1. 仮想ネットワーク構築

#### 1-1．VPC

**メニュー　：[VPC] - VPC - VPCの作成**
**参考サイト：[0から始めるAWS入門①：VPC編](https://qiita.com/hiroshik1985/items/9de2dd02c9c2f6911f3b)**
 
※ 「[VPC] - ダッシュボード - VPCの作成 はウィザードでの作成であり無用な設定が入るので使わない。

|項目|値|
|:--|:--|
|名前タグ|{ 適当な名前 }|
|CIDR	|10.0.0.0/16|
|tenancy|Default|

本番環境や開発環境など複数のネットワークを作る場合は、第二オクテットの数字を変えるとパッと見で判別できて便利。

#### 1-2．Subnet

**メニュー　：[VPC] - サブネット - サブネットの作成**
**参考サイト：[0から始めるAWS入門①：VPC編 実際にSubnetの作成](https://qiita.com/hiroshik1985/items/9de2dd02c9c2f6911f3b#%E5%AE%9F%E9%9A%9B%E3%81%ABsubnet%E3%81%AE%E4%BD%9C%E6%88%90)**

基本的な設計：

機能ごと＋冗長化ごとに第三オクテットを１づつ増やす設計。この程度の規模でネットワークアドレスの細かい設計（AZへの配慮とか）をする必要はない。
※ 無料枠環境でも冗長化の検証するときに使うので冗長化サブネットを作っておく


|名前タグ|IPv4 CIDR|AZ|
|:--|:--|:--|
|application-left|10.0.0.0/24|ap-northeast-1a
|application-right|10.0.1.0/24|ap-northeast-1c
|database-left|10.0.2.0/24|ap-northeast-1a
|database-right|10.0.3.0/24|ap-northeast-1c

**作成後、application-leftとapplication-rightの「自動割り当て IP 設定の変更」をONにする。**

#### 1-3．Internet GateWay

**メニュー：[VPC] - インターネットゲートウェイ - インターネットゲートウェイの作成** 

|名前タグ|
|:--|
|{ VPC名 } + igw 

#### 1-4．Route Table

**メニュー：[VPC] - ルートテーブル - ルートテーブルの作成**
**参考サイト：[Route Table の確認 & 作成](https://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/)**
Route Table の確認 & 作成 の項

・とりあえず新規作成する

|名前タグ|
|:--|
|{ VPC名 } + rt 

・[ルート]タブの[編集]より、上で作ったインターネットゲートウェイを追加。

|送信先|ターゲット|
|:--|:--|
|0.0.0.0/0|{ VPC ID }||

・[サブネットの関連付け]タブで、事前に作った４つのサブネット全てにこのルートテーブルを適用する。 （ＤＢをインターネットから直接接続可能にするため）。

#### 1-5．Security Group

**メニュー：[VPC] - セキュリティグループ - セキュリティグループの作成**

ファイアウォールの設定を行う。AWSには２種類のファイアウォール機能がある。ここではセキュリティグループを使う。

- **ネットワーク ACL**
 - サブネット単位で適用する
- **セキュリティグループ**
 - インスタンス単位で適用する

まずセキュリティグループを作成する

|名前タグ/グループ名/説明|
|:--|
|load-balancer（本番のみ）|
|application|
|database|

各セキュリティグループごとにファイアウォールのルールを作成する。

※ 使うのは[インバウンドのルール]のみ。
※ **SSHとデータベースのインターネットからの接続は自宅・事業所・学校の固定IPアドレスを指定し制限をかける。セキュリティグループを分割し、必要な時だけ例外用セキュリティグループを適用して接続を認める運用にしてもいい。**

・ load-balancer

|タイプ|プロトコル|ポート範囲|ソース
|:--|:--|:--|:--|
|HTTP (80)|TCP (6)|80|0.0.0.0/0
|HTTPS (443)|TCP (6)|80|0.0.0.0/0

・ application

|タイプ|プロトコル|ポート範囲|ソース
|:--|:--|:--|:--|
|SSH (22)|TCP (6)|22|管理用IP/0 (※)
|HTTP (80)|TCP (6)|80|0.0.0.0/0
|HTTPS (443) ※無料枠のみ|TCP (6)|80|0.0.0.0/0

・ database

※ **データベースに合わせてタイプを変更する**

|タイプ|プロトコル|ポート範囲|ソース
|:--|:--|:--|:--|
|PostgreSQL (5432)|TCP (6)|5432|管理用IP/32  (※)
|PostgreSQL (5432)|TCP (6)|5432|10.0.0.0/16

#### 1-6．DB Subnet Group

**メニュー：[RDS] - サブネットグループ  - DB サブネットグループの作成**
**参考サイト：[0から始めるAWS入門④：RDS編 DB用セキュリティグループの作成](https://qiita.com/hiroshik1985/items/6643b7323183f82297b2#db%E7%94%A8%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%81%AE%E4%BD%9C%E6%88%90)**

・新規作成

|名前タグ/説明|
|:--|
|{ VPC名 } -dbsg |

・サブネットの登録

先に作成したデータベースサブネットを追加する。

|AZ|サブネット名|
|:--|:--|
|ap-northeast-1a|database-left|
|ap-northeast-1c|database-right|

### 2. インスタンス作成

#### 2-1．EC2

**参考サイト：[0から始めるAWS入門②：EC2編](https://qiita.com/hiroshik1985/items/f078a6a017d092a541cf)**

最初に、接続用のキーペアを作っていなければ作成する

**メニュー：[EC2] - キーペア  - キーペアの作成**

|キーペア名|
|:--|:--|
|{ 適当な名前 }|

認証鍵ファイルをダウンロードしたら無くさないように保管する。

次にインスタンスを作成する

**メニュー：[EC2] - インスタンス  - インスタンスの作成**

任意のAMIを選んでインスタンスを作成する。無料枠のときは有料版を選ばないように注意。以下の設定以外はデフォルトにして作成する。

|項目名|値|
|:--|:--|
|VPC|{ VPC 名 }|
|サブネット|application-left|
|自動割り当てパブリック IP|有効|
|セキュリティグループ|application|
|キーペア|{ 既存のキーペア名 }|

デプロイされたら「パブリックDNS」、もしくは「パブリックIPアドレス」に対して認証鍵ファイルでアクセスする。[ログインIDはAMIによって異なるので注意](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html)。



#### 2-2．RDS

**メニュー：[RDS] - インスタンス  - DB インスタンスの起動**
**参考サイト：[0から始めるAWS入門④：RDS編](https://qiita.com/hiroshik1985/items/6643b7323183f82297b2)**

任意のを選んでインスタンスを作成する。
以下の設定以外はデフォルトでＯＫ

|項目名|値|
|:--|:--|
|VPC|{ VPC 名 }|
|サブネットグループ|{ VPC名 } -dbsg|
|パブリックアクセシビリティ|はい|
|既存のVPCセキュリティグループ|database|

作成には10分程度かかる。
起動後にエンドポイントに対してSQLエディタ等で接続してみる。

動作を確認したら、EC2とRDSにWebアプリケーションを構築する。

#### 2-3．EC2のコピー

**参考サイト：[Amazon Web Services(AWS) のEC2でインスタンスをコピーする方法](https://qiita.com/murachi1208/items/8be3cd006d31f1f81ee4)**

構築後、EC2のインスタンスをコピーして冗長化することができる。
EC2の既存のインスタンスよりAMIを作り、そこからEC2を作ってコピーする。

|項目名|値|
|:--|:--|
|VPC|{ VPC名 }
|サブネット|application-right
|セキュリティグループ|application|

### 3. ドメイン設定

ここからは**無料枠の対象外**の範囲である。

|項目|課金対象|料金|
|:--|:--|:--|
|ドメイン取得・管理|1ドメイン/年|12 USD(.comの場合)|
|ホストゾーン運用|1ドメイン/月|0.5 USD|
|DNSクエリ(※)|1万件ごと|0.004 USD|
|ロードバランサ運用|1インスタンス/時間|0.0243 USD|

ドメインの取得と運用は年間2,000円程度となる。

SSL証明書はRoute53でドメインを管理すると無料でもらえるが、このSSL証明書はAWSサービスだけで使える特殊なもので、適用にあたってELBやCloudFrontの利用が必須である。

ELBの運用は月額2,000円程度となる。

**よってHTTPSの運用は月額2,000円程度。HTTPSの検証環境を作った場合は放置しないように気を付けること。**


#### 3-1．ドメインの取得

**メニュー：[Route 53]- Registered domains - Register domain**
**参考サイト：[Amazon Route 53でドメインを購入する](https://dev.classmethod.jp/cloud/register-domains-route53/)**

ドメインを取得する（有料 .comドメインで年間12ドル）。
取得の流れについては参考サイトで詳しく説明されている。
登録が完了すると自動的にドメインのホストゾーンが作成される。

#### 3-2．証明書の取得

**【本番環境のみ】**

**参考サイト：[AWS：無料でSSL証明書を取得する方法]**
(https://qiita.com/iwaseasahi/items/1687426add4124899fe3)

ドメインに対応するSSL証明書を取得する（無料）。
証明書の取得サービスは「Certificate Manager」。

#### 3-3．ロードバランサ

**【本番環境のみ】**

**メニュー：[EC2]-ロードバランサー-ロードバランサーの作成**
**参考サイト： [１台のEC2でもELBを使うメリットについてまとめてみました](https://dev.classmethod.jp/cloud/aws/benefit_elb_with_one_ec2/)**

ロードバランサを作成する（有料）。冗長化以外にも様々なメリットがあり利用すると色々楽になる。

設定内容：

以下の項目以外はデフォルトでＯＫ

|項目名|値|
|:--|:--|
|ロードバランサーの種類|Application Load Balancer|
|名前タグ|{ VPC名 } + alb|
|プロトコル|https (※)|
|アベイラビリティゾーン(サブネット)|application-left、application-rightを選択|
|SSL証明書の名前|前段で取得したSSL証明書|
|セキュリティグループ|load-balancer|
|ターゲットの登録|作成したEC2インスタンスを追加|

#### 3-4．DNSの設定

【本番環境の場合】ロードバランサを作った場合はロードバランサのエンドポイントを指定する。

|項目名|値|
|:--|:--|
|Name|ドメイン名 or 任意のサブドメイン名|
|Type| A Alias|
|Value|ロードバランサのエンドポイント|

【無料枠環境の場合】ロードバランサを作らずEC2に直接アクセスさせる場合は、EC2インスタンスに「ElasticIP」を設定し、そのIPを指定する。

|項目名|値|
|:--|:--|
|Name|ドメイン名 or 任意のサブドメイン名|
|Type| A |
|Value|EC2に設定したElasticIPのアドレス|

データベースはRDSのエンドポイントを指定する。

|項目名|値|
|:--|:--|
|Name|例：[database.（サブ）ドメイン名]
|Type|CName|
|Value|RDSのエンドポイント|

あとは外部から接続して動作検証すればＯＫ

#### 注意：常時SSLの設定
常時SSLに必要なHTTP⇒HTTPSのリダイレクト処理はELB単体では不可能。
EC2上のWEBサービスで設定する必要がある。

参考：[AWS EC2で常時SSLを実現する際の注意点](https://qiita.com/michimani/items/88973c5e2ae76a8e84aa)