新人エンジニアがAWSを触る前に知っておきたい基礎知識

新人フロントエンドエンジニアですが先日業務でAWSを触る機会がありました。
その際AWS以前にインフラやネットワークに関する基礎知識が欠けており非常に苦戦したので調べた内容をまとめました。

実際のサーバー構築手順については書きませんのでご注意ください。

# そもそもアマゾンウェブサービス（AWS）ってなに？

AWSとは顧客へサービスを提供するために必要なサーバー、ストレージなどのITインフラストラクチャを提供するクラウドサービスのことです。
そしてクラウドサービスとはユーザーが端末上で利用しているデータやソフトウェアをネットワーク経由で提供するサービスのことです。例えばGoogle photoはユーザが写真をアップロードすれば、ブラウザ・インターネット接続環境があれば他の端末からでもGoogleのネットワークを経由して写真を見ることができるクラウドサービスです。

今回はこのAWSを使ってサーバーやネットワーク構築をしていきます。

# 結局ネットワーク＆サーバー構築って何をするの？
ざっくり言えば、情報のやり取りをするためにコンピュータ同士をつなげて「ネットワーク」を作り、クライアントからのリクエストに対してレスポンスを返す役割を持った「サーバー」を用意することです。

このリクエスト→レスポンスというやり取りはWebサイトやメールでも使われる基本の仕組みです。サーバーとネットワークを構築して、どんな時にどんな応答を返すのかをプログラミングすることで自分の好きなアプリケーションを作ることができます。

![サーバーとは.png](https://qiita-image-store.s3.amazonaws.com/0/267607/428877f4-1579-bc59-c45b-d06584781c1f.png)

## 手順1: ネットワークを作る
### ネットワーク
コンピュータ同士をケーブルや電波でお互いに接続して情報をやりとりする仕組みのこと、もしくはこうして接続されたコンピュータのグループ。このコンピュータ同士の接続が世界規模でされるようになったものをインターネットと呼びます。

### サーバー
クライアントからのリクエストに答えてサービスを提供するコンピュータのこと。Webサイトのデータを提供するWebサーバーやデータを保存するデータベースサーバーなど様々な種類があります。

サーバーとは決して「サーバー室にある真っ黒で大きなコンピュータ」だけではありません。
「リクエストに応じてサービスを提供する」という役割を持ったコンピュータすべてがサーバーなので、例えばWebサーバーの機能を提供するソフトウェアをインストールし、ポート開放して動作させれば自宅のPCもサーバーと言えます。

![サーバー種類.png](https://qiita-image-store.s3.amazonaws.com/0/267607/6d850368-6438-06ac-241c-2ff59ab6c8d5.png)

### IPアドレス
自分でサーバーやネットワークを構築する際には最初にどの範囲で自分のネットワークを作るのかを決めないといけません。家を建てる前に敷地や住所を決めるのと同じです。

インターネット上でこの住所に当たるのが「IPアドレス」で、重複しないように管理団体が一括管理しています。


AWS上にはアマゾンが所有しているネットワーク環境の中に、さらにVPC（バーチャルプライベートクラウド）という自分用のプライベートなネットワーク環境を作ることになります。
アマゾンが所有している敷地の一部を借りて家を建てるとイメージすると分かりやすいです。

この時VPCをどの「リージョン」に作るかと聞かれますが、リージョンとはサーバーの物理的な位置のことです。世界中にあるリージョンの中から東京リージョンを選べば、アマゾンが所有する東京のサーバーの一区画を借りることになります。
では東京リージョン内に「10.0.0.0/16」というプライベートIPアドレスを持ったVPC（ネットワーク）を作ることにしましょう。

ネットワークの大きさはこのプライベートIPアドレスで決まります。自由に決めることもできますが、AWSでは推奨しているプライベートIPアドレスが複数あり「10.0.0.0/16」もその一つです。
ではこのIPアドレスはどの程度の大きさのネットワークなのでしょうか？それはCIDRブロックを見ることで分かります。


![VPCとは.png](https://qiita-image-store.s3.amazonaws.com/0/267607/c9db99a8-8772-b030-08a7-5fe69b63b589.png)


### CIDRブロック
CIDRブロックとは、IPアドレス（ネットワーク上の住所）の範囲をCIDRという形式で表したものです。
IPアドレスを表すのには2進数表記、10進数表記など様々な方法がありますが、その中の一つがこのCIDRというIPアドレスとサブネットマスクを一緒に表記する書き方のことです。
ややこしくなってきました！

### IPアドレスとサブネットマスク
よく見るIPアドレスというのは「172.16.254.1」といった4つの数字の組み合わせです。

しかしIPアドレスはもともと２進数表記の数字を32個並べたものです。２進数で表された1桁の数字は1ビットの情報量を持つので、32桁のIPアドレスは32ビットということになります。

しかしこれでは長いので8ビット(8桁)で区切った上で2進数→10進数表記に変え、ドットで繋げています。
こうして「172.16.254.1」といったよく見る形式のIPアドレスになりました。

この172.16.254.1はさらに「ネットワーク部」と「ホスト部」に分けられます。

じゃあどうやって分けよう？という時に必要なのが「サブネットマスク表記」や「CIDR表記」です。

![IPアドレス.png](https://qiita-image-store.s3.amazonaws.com/0/267607/1c8c2064-22ab-6f0d-2506-de6bc0a806e6.png)

### サブネットマスク
サブネットマスク表記はIPアドレスのうち、ネットワーク部を表す部分を2進数の１、ホスト部を表す部分を０で表記したものです。
つまりサブネットマスクが「11111111 11111111 00000000 00000000」ならば上位16ビットがネットワーク部となります。

サブネットマスクを実際に表記する場合は2進数から「255.255.0.0」というように10進数に直します。
つまり最終的には「172.16.254.1/255.255.0.0」となり、スラッシュ以下を見て上位１６ビットがネットワーク部だと分かります。

CIDR表記では、シンプルにネットワーク部のビット長を「/16」のように表します。つまり「172.16.254.1/16」ならば最初の１６ビットがネットワーク部ということです。
ちなみに「/16」の部分はプレフィックスと呼びます。


### ネットワーク部とホスト部
ネットワーク部とはそのネットワークがインターネット上のどこにあるのか？を表すもので、ホスト部はそのネットワーク内のどのコンピュータを指しているか？を表します。
つまりIPアドレスが「172.16.254.1/16」ならば172.16がそのネットワークの場所を表し、254.16がネットワーク内におけるそのコンピュータを指しています。そのため同じネットワーク内にあるコンピュータはネットワーク部が同じになります。


![ネットワーク部.png](https://qiita-image-store.s3.amazonaws.com/0/267607/26809386-b8cb-199b-62b7-77cfaaf03281.png)

長くなってしまいましたがここで再度プライベートIPアドレス「10.0.0.0/16」のVPCについて考えます。
このプライベートIPアドレスのプレフィックスは/16のため下位16ビットの0.0の部分がホスト部になります。
これからこのVPCをにさらに別のネットワークを作ることでVPCを分割していきますが、その際新しく作るネットワークにはこのVPCのホスト部の部分から新しくIPアドレスを割り当てるになります。

そのため、このVPCが内部のネットワークに割り当てられるIPアドレスの範囲は「10.0.1.0」〜「10.0.1.255」であり、この範囲がVPCの持つIPアドレスの範囲=ネットワークの大きさです。

## 手順2: ネットワークを必要に応じて分割する
### サブネットとアベイラビリティゾーン
手順1でVPCを作ってプライベートなネットワークを用意したので、次にVPCの中にサブネットを作っていきます。
先程このVPCは東京リージョンに作りましたが、実は個々のリージョンはさらにアベイラビリティゾーン（AZ）という個々のデータセンターに分けられています。
そのため、VPCを区切ってサブネットを作る際はどのAZに作るかも一緒に選びます。

ではVPC内の「ap-northeast-1a」というAZにIPアドレス「10.0.1.0/24」のサブネットを作りましょう。

手順1で作ったVPCはプライベートIPアドレスが「10.0.0.0/16」でした。プレフィックスが/16であることからIPアドレスの下位16ビットにあたる「10.0.0.0」〜「10.0.255.255」をVPC内で自由に分割できることがわかります。
そこで、このうち「10.0.1.0」〜「10.0.1.255」を新しいサブネットに割り当てることにします。(本当は設定上使えないIPアドレスもあるので実際はこの範囲からもう少し減ります。)

![サブネット.png](https://qiita-image-store.s3.amazonaws.com/0/267607/6e6eb207-b2b4-3314-99fe-115c98992764.png)


### サブネットの種類
サブネットとは一つのネットワーク内でさらに分割されたネットワークのことです。
このサブネットには「パブリックサブネット」「プライベートサブネット」の2種類があります。

パブリックサブネットは外部との接続が可能なサブネットです。
一方でプライベートサブネットは直接外部と通信することができません。
そのためプライベートサブネット内のサーバーが外部と通信する必要がある場合は、同じVPC内のパブリックサブネットを経由して外部に繋いだり、NAT（Network Address Translation）を使う必要があります。
![サブネットの種類.png](https://qiita-image-store.s3.amazonaws.com/0/267607/34b83d86-e2f9-1b5c-7c16-97fdf0da2c93.png)

### パブリックIPアドレスとプライベートIPアドレス
プライベートIPアドレスは「このネットワーク（VPC）内においてどのコンピュータを指すのか？」を表すIPアドレスです
一方パブリックIPアドレスはVPC内に限らず、インターネット（世界中のネットワーク）全体で見た時にどのコンピュータを指すのか？を表すIPアドレスです。

パブリックサブネットは外部との接続も可能なためプライベートIPアドレスとパブリックIPアドレスの両方を持ち、外部と通信を行う際はパブリックIPアドレスが使われます(AWSの初期設定ではサーバーを再起動する度にパブリックIPアドレスが変わるので"xxxx..."で表しています)。
プライベートサブネットは外部との接続を行わないのでパブリックIPアドレスはそもそも持ちません。

## 手順3: 外部のネットワークと繋げる準備
### インターネットゲートウェイ
パブリックサブネットを外部に繋ぐためにはVPCにインターネットゲートウェイを置き、そのインターネットゲートウェイにパブリックサブネットを繋ぐ必要があります。VPCが家でサブネットが部屋ならば、インターネットゲートウェイは外へ通じるドアのようなものです。


![ルートテーブル.png](https://qiita-image-store.s3.amazonaws.com/0/267607/2792871c-fadb-15ff-91b3-3f278006f01d.png)


### ルートテーブル
先程インターネットゲートウェイとパブリックサブネットを繋ぐ、と話しましたがここで必要なのが「ルートテーブル」です。

ネットワーク上で一方の箇所から他方の箇所へ情報を送る際には送り先のIPアドレスが必要です。
しかし実際に情報を送信する際には様々なネットワークを経由することになるため、宛先だけでなくどのネットワークを経由すれば最速で送信先にたどり着くのかの情報も必要です。

この「宛先IPアドレスまでに経由するネットワーク」を教えてくれるのが「ルーター」で、ルーターは「ルートテーブル(一般的にはルーティングテーブルと呼ばれる)」という地図を見てデータを適切なネットワークに送信します。

そのためパブリックサブネット/プライベートサブネット問わず、ルートテーブルを事前に設定してどの種類の情報はどのネットワークに送るのかを決めています。送り先がこのルートテーブルで設定されている範囲外だとデータを送ることができません。

図中ではこのVPCのIPアドレス範囲である「10.0.0.0/16」に宛先のIPアドレスが含まれている（つまり宛先が同じVPC内である）ならばこのVPC内のルーター=localにパケットを送信する設定になっています。また２行目の0.0.0.0/0は全てのIPアドレスを指すので、宛先のIPアドレスがルートテーブルで設定されていない、つまりVPCの範囲外であるときはIGW（インターネットゲートウェイ）にパケットを送信するという意味を指しています。

プライベートサブネットの場合はIGWにつなぐ必要もないので0.0.0.0/0のルートテーブルの設定は不要です。

## 手順4: ネットワーク内にサーバー構築
### インスタンス
サブネットを作ったらその内部に「インスタンス」という仮想サーバーを構築します。仮想サーバーとはその名の通り「仮想化」されたサーバーのことです。インスタンス上にApacheなどのWebサーバーソフトをインストールすることで、ブラウザからの要求に対して応答するというサーバーとしての役割を実行できるようになります。

### 仮想化
仮想化とは物理的な構成にとらわれずにリソースを配置しよう！という考え方のことです。
サーバーで考えると、アプリケーションサーバー、DBサーバー、メールサーバー...とサーバーを３台用意するのではなく、1台の物理的なサーバー上にリソース(OS、各種ソフトなど)を配置して3台のサーバーを動かそうという仕組みです。

![仮想化.png](https://qiita-image-store.s3.amazonaws.com/0/267607/100c489a-97e8-f587-5574-79d1cb469f5e.png)

今回はAWSの東京リージョンに物理的に存在するサーバー上にネットワークを構築して自分のインスタンス(サーバー)を動かすので、インスタンスは全て仮想サーバーと言えます。
インスタンスを作るにはAMIやIPアドレスの設定が必要です。

![AWS仮想サーバー.png](https://qiita-image-store.s3.amazonaws.com/0/267607/dca2a928-f55a-cf41-b544-b1781f5f97b9.png)

### AMI(Amazon Machine Image)
AMIとはインスタンスの起動に必要なイメージファイルです。
AWSにおいては各種OSのインストールや設定が済んだ状態のものがイメージファイルとして用意され、好きなOSをコピーしてインスタンスを作ることでサーバーとして動かすことができます。


### イメージファイル
イメージファイルとはDVDなどのハードディスクに保存されたデータをファイルやフォルダの構造を保ったまま保存、コピーしたデータのことです。
DVDの中身そっくりそのままなので仮想ドライブ(ハードコピーと異なり実体がないので読み込みも仮想のドライブ)で再生が可能です。

よく聞くmp4などはハードウェアの中身を変換したものなので、イメージファイルとは異なり形式やフォルダ構成が変わっています。
![イメージファイル.png](https://qiita-image-store.s3.amazonaws.com/0/267607/e73d520c-dc3e-2e74-cd4b-41da775302d4.png)

### OS(Operation System)
キーボードを打つと文字が入力されたり、フォルダやファイルを作成したりとコンピュータの操作の基本となる機能を提供するソフトウェア。Microsoft WindowsやmacOSが代表的です。

## 手順5: ファイアウォールの設定
### ファイアウォール
ファイアウォールとは、外部のネットワークからの不正な通信からネットワークを守るための仕組み全般を指します。AWSではファイアウォール機能の一つとしてセキュリティグループを使います。

### セキュリティグループ
インスタンスからデータを送信したり、逆に外部からデータを受け取る際にデータは「ポート」というドアを通ります。つまり、このポートが外部のネットワークとインスタンスを繋ぐドアとなるのです。
通信をする際には必要なポートを開けておく必要がありますが、一方で全てのポートを開けるのは玄関のドアを開け放すようなものでセキュリティ上とても危険です。

そこで、インスタンスごとに「セキュリティグループ」を設定することで、該当する通信方法、ポート番号、接続元のアドレスからのデータのみがポートを通れるように制限してセキュリティを向上させられます。
図中ではHTTPのTCPという通信方法で送られたデータのみは送信元がどこからでもポート80で受け入れるよ！という意味です。
実際はデータを受け取る際の設定(インバウンド)だけでなくデータを送信する際の設定(アウトバウンド)も必要です。


![セキュリティグループ.png](https://qiita-image-store.s3.amazonaws.com/0/267607/770c5f14-addf-92db-e69a-98118281bb9d.png)

2018/12/8追記: 
セキュリティグループはステートフルなので、インバウンドの設定で許可されてネットワーク内部へ届いたデータに対するレスポンスはアウトバウンドの設定に関わらず送信ができます。逆にアウトバウンドの設定で許可されて送信されたリクエストに対するレスポンスはインバウンドの設定に関わらず受信します。

### ステートフル
サーバーがクライアント側アプリケーションの状態(セッション状態)を覚えていること。セキュリティグループはインバウンド/アウトバウンド通信の際に、「このサーバー(/ポート番号/プロトコル)での通信は許可されているんだな」と覚えているので、それに対するアウトバウンド/インバウンド通信はセキュリティグループで設定がされていなくても許可されます。
このように往復のやり取りが必須となる通信において自動的に応答の通信を許可する仕組みを「ステートフル・インスペクション」といいます。

### ステートレス
ステートフルの反対でサーバーがセッション状態を覚えていないこと。AWSにはセキュリティグループ以外にもネットワークACL(アクセスコントロールリスト)というファイアウォールがありますが、こちらはステートレスです。そのためインバウンド/アウトバウンド両方の設定が必要です。


# おわりに
今回の記事ではネットワークとは何か？という基本から、実際にAWSでネットワーク・サーバー構築する際に使うVPC、サブネットといった用語の説明をしてきました。
最近はAWS、Herokuなどのサービスを使えばインフラの知識がほぼ無くてもアプリケーションが公開できますが、やはりサービスを安全に使ったりエラーに自分で対処するためにはフロントエンドエンジニア〜インフラエンジニア問わず最低限のインフラ知識は必須だと改めて感じます。

もし記事の内容に間違いがありましたらご指摘いただけると幸いです。


参考：
https://qiita.com/mogulla3/items/efb4c9328d82d24d98e6
「Amazon Web Services 基礎からのネットワーク＆サーバー構築 改訂版」(日経BP社)