初めてAWSを利用したサーバー構築をやってみた



# 概要

こんにちは！ [Diverse株式会社](https://www.wantedly.com/projects/542880)のgataponです！
今年もアドベントカレンダー書きます！お願いします！

 今年は、担当しているサービスがオンプレミスからAWSに置き換わりました。少しずつAWSの機能には慣れていきつつあるのですがAWSを使ったサーバー構築をしたことがないため、まだまだわからないことがたくさんです。
今回はAWSを使ってイチからサーバーを構築してインフラ周りの理解も深めることにしてみました。

AWSの機能や役割などメインにサーバー構築の流れざっとを書いていきます。

利用させてもらった書籍は[Amazon Web Services 基礎からのネットワーク＆サーバー構築](https://www.nikkeibp.co.jp/atclpubmkt/book/20/277900/)です。

![277900_thumb_pc.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222848/562098a8-4149-0260-f236-598112bc5289.jpeg)

構築したサーバーは以下のようになります。

![AWS基礎からのネットワーク＆サーバー構築.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222848/df940a07-8023-3c19-23fb-86efab97e78f.png)

VPC内にパブリックサブネットとプライベートサブネットを用意しました。前者にはインターネットに公開されたアプリケーション（本書ではWordpress）とNATゲートウェイを配置。後者にはデータベースを配置しています。プライベートサブネットの配置されたインスタンスはNATゲートウェイを利用してのみインターネットにアクセスすることができます。

## VPC

まずは、Amazon VPCを利用して隔離されたネットワークを構築します。構築したネットワークには任意のネットワーク設定ができ、ルーターなどの仮想的なネットワーク機器も配置できます。VPCで利用するプライベートIPアドレスの領域は`10.0.0.0/16`としました。

## サブネット

VPCで割り当てたネットワークを更に分割して利用します。ここで２つのサブネットを作成し、プライベートIPアドレスの領域も割り振ります。

 - パブリックサブネット(10.0.1.0/24)
 - プライベートサブネット(10.0.2.0/24)

### どうしてサブネットを分割するのか
サブネットを分割するのには２つの利点があります。

 - 分割しておくことで万が一どちらかが障害を起こしても、片方に影響が出にくくなる
 - それぞれのサブネットに対して別のネットワーク設定ができる
    - パブリックサブネットは外部からの接続を許し、プライベートサブネットは外部からの接続を遮断できる

 このように設定することで、アプリケーションは外部の人から見ることができ、かつデータベースへの直接のアクセスは遮断できます。

![AWS基礎からのネットワーク＆サーバー構築 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222848/68929b3b-dad5-1bdb-0794-8f73b9c5695f.png)


## インターネットゲートウェイ
インターネットゲートウェイとはVPCとインターネットの接続を可能にする役割を担っていあす。作成したVPCとサブネットをインターネットに接続するためにはこちらを作成し、まず該当するVPCにリタッチする必要があります。しかし、それだけではインターネットに接続はできません。ルートテーブルの設定が必要になります。

## ルートテーブル（ルーティングテーブル）
　「TCP/IP」プロトコルでは、データを細切れにした「パケット」という単位でデータが送受信されます。その中にあるヘッダー情報の一つに「宛先IPアドレス」があります。TCP/IPでは、ネットワーク機器である「ルーター」が確認しながら目的地まで転送します。
　その役割を担うルートテーブルにIPアドレスの扱いを登録しなければいけません。 しかし、AmazonVPC作成時のデフォルトのルートテーブルは以下になっています。

| 送信先 | ターゲット |
| :--: | :--: |
| 10.0.0.0/16 | local |

これはVPC構築時に設定したプライベートIPアドレス領域で、このままではVPC内の通信のみが扱われ、それ以外の宛先のものは破棄されてしまいます。新しくルートテーブルを作成し、パブリックサブネットに割当て、新しく転送先に`0.0.0.0/0`(転送先が設定されていないときの、デフォルト転送先)、ターゲットに作成したインターネットゲートウェイを追加します。これでパブリックサブネット内からインターネットにアクセスできるようになります。

## Webサーバー(EC2)

次に、パブリックサブネット内のEC２インスタンスを起動しssh接続します。
作成したVPC内のパブリックサブネットにインスタンスを作成します。プライベートアドレスは`10.0.1.10`としました。
EC2インスタンス生成時に生成されるペアキーを利用し、ssh接続ができるようになるのでapacheなどのインストールが行えるようになります。

サーバーの設定が完了したらセキュリティグループの設定を行います。

### セキュリティグループ

セキュリティグループはAWSにおけるファイヤーウォールの役割を担っており、インスタンスに対して設定することが出来ます。
EC2インスタンスの作成時にセキュリティグループの設定が可能です。
既存のEC2インスタンスのセキュリティグループではインバウンドルールがssh接続しか設定されていません。
設定されていないIPアドレスを送信元やポート接続を除外するようになっています。
ポート80を開放してブラウザでサイトが確認できるようにします。

| タイプ | プロトコル | ポート範囲 | ソース | 説明 |
| :--: | :--: | :--: | :--: | :--: |
| カスタムTCP | TCP | 80 | 0.0.0.0/0 | - |

設定が完了したら、EC2インスタンスのパブリックIPアドレスをブラウザに叩くとapacheのデフォルトページが表示されます。

# DBサーバー(EC2)

次に構築したVPC内のプライベートサブネットにMariaDB用のEC2インスタンスも立ち上げます。
自動で割り当てられるパブリックIPアドレスは無効にしておきます。プライベートIPアドレスは`10.0.2.10`です。
ペアキーはWebサーバーと同じものを利用します。

セキュリティグループはデフォルトで設定されているsshプロトコルの他に、MariaDBの通信も許したいので通信ポート「3306」を追加します。

| タイプ | プロトコル | ポート範囲 | ソース | 説明 |
| :--: | :--: | :--: | :--: | :--: |
| MYSQL/Auror | TCP | ３３０６ | 0.0.0.0/0, ::/0 | - |

ここではNAT構築し、そこからアクセスする例を示すため、WebサーバーのIPアドレスだけに制限しないようにしています。

# DBサーバーにsshで接続する

DBサーバーにMariaDBをインストールするためにsshログインする必要があります。
しかし、プライベートサブネットは割り振られたパブリックIPアドレスがないので、Webサーバーを踏み台にして
プライベートサブネットのDBサーバーにssh接続する必要があります。
そのためにlocalからWebサーバーにssh接続するために利用しているpemファイルをサーバーに持っていきます。

例

```terminal
scp -i my-key.pem my-key.pem [WebサーバーパブリックIPアドレス]:~/
```

これでWebサーバーからDBサーバーにssh接続ができるようになります。

# NATゲートウェイ

プライベートサブネットに構築したサーバーはインターネットから接続できないので安全ですが、このままでは
インターネット通信が一切できないためソフトウェアのインストールが出来ません。
DBサーバーにMariaDBをインストールするためにもインターネット通信が必要になります。

この問題はパブリックサブネット内にNATを構築することで解決します。
NATとはIPアドレスを変換する装置で、インターネット接続が可能なパブリックIPアドレスとプライベートサブネットに接続するようのプライベートIPアドレスを併せ持っています。プライベートサブネット内のサーバーがインターネットに送信しようとした時にNATはそのパケットにあるヘッダーの送信元アドレスを自身のパブリックIPアドレスに書き換えて、インターネット接続を行います。インターネットからの応答パケットはNATに戻ってき、宛先を送信元のIPアドレスに書き換えてプライベートサブネットのサーバーに返します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222848/04e333dc-ad04-5a5b-520a-2d6d8303d3f0.png)


AWSにはNATゲートウェイという機能が提供されているので、非常に簡単にNATを利用することが出来ます。

## Elastic IP

Elastic IPは「静的で固定なパブリックIPアドレス」が利用できるAWSの機能の一つです。NATゲートウェイ構築にはamazonサービスのElastic IPを利用して構築していきます。EC2インスタンスなどでデフォルト割り振られるようなパブリックIPアドレスでは、起動・停止する度にアドレスが変わってしまうので、こちらを利用してみます。
NATゲートウェイ作成時に同時に設定することが可能です。

## ルートテーブルの変更

最後にプライベートサブネットからインターネットに対して通信する時に、NATゲートウェイを介するようにします。

| 送信先 | ターゲット |
| :--: | :--: |
| 0.0.0.0/0 | 作成したNATゲートウェイ |

デフォルトのルートテーブルを上記のように設定を追加すると宛先IPが未定義だった場合にNATゲートウェイに転送されるようになります。
DBサーバーにssh接続してMariaDBインストールがし、各種設定を行えばDBサーバー作成は完了です。

任意のアプリケーションやフレームワークをWebサーバーに乗せ、DB接続の設定を行えば図の完成になります。
![AWS基礎からのネットワーク＆サーバー構築.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222848/df940a07-8023-3c19-23fb-86efab97e78f.png)

# まとめ

何度かインフラやAWS周りの勉強はしてきましたが、今回利用させてもらった[Amazon Web Services 基礎からのネットワーク＆サーバー構築](https://www.nikkeibp.co.jp/atclpubmkt/book/20/277900/)はコンパクトでありながらAWS、インフラ、ネットワークの勉強になりました。実際に構築しながら学ぶことが出来たので、身についた感があります。
一日あれば終わるぐらいの簡潔な内容なのでとても良かったです。