【AWS備忘録】VPC, EC2ハンズオン

# 本記事で構成するVPC
![AWS_VPC_DEMO.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549894/2a50f7f6-f752-3a33-e989-9e488f82aa26.jpeg)

# VPC（Virtual Private Cloud）
AWS内部の自分専用のネットワーク。セキュリティの設定などもここに含まれる。

**用語**

- **リージョン**：国・地域
- **AZ（アベイラビリティゾーン）**：データセンター

**備考**

- VPCはリージョンを跨いで作成することはできない。
- 1アカウントにつき、1リージョンに5つまでVPCを作成できる。

# サブネット
大きなネットワーク（VPC）を複数の小さなネットワーク（サブネット）に分割することでセキュリティレベルを高めることができる。

**備考**

- サブネットはAZを跨いで作成することはできない。
- **パブリックサブネット**と**プライベートサブネット**の2種類が存在する。（後述）

# 補足：IPアドレス概要
`192.168.0.1` ← よく見るこういうヤツ。
実は全部で32ビットのデータで、8ビット毎にピリオドで区切られている。

**CIDR表記**を用いてIPアドレスをいくつ確保するかを表現する。
/nと書いた場合、$2^{32-n}$通りのIPアドレスを確保したことになる。

| CIDR表記         | 表しているもの |
|:---------------:|:------------|
| 10.21.59.223/32 | 10.21.59.223（1通り） |
| 10.21.59.223/24 | 10.21.59.*（256通り） |
| 10.21.59.223/16 | 10.21.\*.\*（65536通り） |
| 0.0.0.0/0       | 全てのIPアドレス（4294967296通り） |

**備考**

- VPCのアドレスレンジ帯は/16~/28。
- サブネットのアドレスレンジは/24がおすすめ。
  - 十分な量（256個）のIPアドレスを確保できる。
  - 第4オクテッドのみを使用するため分かりやすい。
  - 最小単位の/28で作成してしまうとELB（Elastic Load Balancing）が配置できない。
- VPCのアドレスレンジは上記のサブネットのアドレスレンジとの兼ね合いを考え、余裕を持って決めると良い。
  - VPCのアドレスレンジを`/21`、サブネットのアドレスレンジを`/24`とすると、例えば、VPCが`10.0.0.0/21`の場合、8つのサブネット（`10.0.0.0/24`〜`10.0.7.0/24`）を作成することができる。（$2^{24-21}=2^3=8$通り）

# ルートテーブル
サブネットから外に出る通信をどこに向けて発信するかを定義する。
デフォルトでは以下のようになっている。

| 送信先（このIPアドレスが来たら） | ターゲット（ここに飛ばす） |
|:-----------------------:|:-----------------:|
| 10.0.0.0/21             | local |

※ local：VPCの内部全てのこと

# インターネットゲートウェイとNATゲートウェイ
VPCを外部のネットワーク（インターネット）と接続する際に使用する。
どちらも自動でスケールしてくれる優れモノ。

### インターネットゲートウェイ
VPCにアタッチして、VPC内のAWSリソースとインターネットを繋ぐ。
以下のようにルートテーブルに設定し、使用する。

| 送信先（このIPアドレスが来たら） | ターゲット（ここに飛ばす） |
|:-----------------------:|:-----------------:|
| 10.0.0.0/21             | local |
| 0.0.0.0/0               | Internet Gateway |

**備考**

- 先述の2種類のサブネットは以下のように定義できる。
  - パブリックサブネット：インターネットゲートウェイへのルーティングが**ある**サブネット
  - プライベートサブネット：インターネットゲートウェイへのルーティングが**ない**サブネット

### NATゲートウェイ
パブリックサブネットに配置して、プライベートサブネットからのインターネット接続を可能にする。
インターネットゲートウェイとは違い、アウトバウンドはできるが、インバウンドはできない。（**発信はできるが、外部からのアクセスはできない。**）
以下のようにルートテーブルに設定し、使用する。

| 送信先（このIPアドレスが来たら） | ターゲット（ここに飛ばす） |
|:-----------------------:|:-----------------:|
| 10.0.0.0/21             | local |
| 0.0.0.0/0               | NAT Gateway |

**備考**

- NAT（Network Address Translation）
- NATゲートウェイはインターネットゲートウェイへのルーティングが必要なため、必ずパブリックサブネットに配置して使用する。

# ENI（Elastic Network Interface）
EC2インスタンスやNATゲートウェイ等にIPアドレスをアタッチする際、実はENIにIPアドレスを割り当て、それをアタッチ/デタッチしている。

# パブリック IPアドレスとElastic IPアドレス
一般に、外部ネットワーク（インターネット）に接続する際は、外部接続用のIPアドレスが必要となる。
AWSの場合、インターネットに接続する際は、外部接続用のIPアドレスとして**パブリック IPアドレス**か**Elastic IPアドレス**のどちらかが必要となる。

### パブリック IPアドレス
AWSのIPアドレスプールから割り当てられるIPアドレス。
インスタンスが再起動/停止/終了した場合、このアドレスは**解放される**。

### Elastic IPアドレス
AWSアカウントに関連づけられた静的なIPアドレス。
インスタンスが再起動/停止/終了しても**同じアドレスのまま**。

**備考**

- Elastic IPアドレスはどこにもアタッチしていない場合、1時間あたり約1円かかる。
- パブリック IPアドレスを持つインスタンスにElastic IPアドレスをアタッチした場合、Elastic IPアドレスが有効となる。
- Elastic IPアドレスは同一アカウントであれば、他のVPCのインスタンスにも付け替えができる。

# 補足：インスタンスのアドレス事情

インスタンスはVPC内部用と外部接続用等、複数のIPアドレスを持つことがある。

- VPC内部用：サブネットのアドレスレンジ内のIPアドレスが自動で割り当てられる。
- 外部接続用：Elastic IPアドレスをアタッチして使用することが多い。

**備考**

- NATゲートウェイを通る場合、NATゲートウェイ自身にアタッチされたElastic IPアドレスが使用される。

# セキュリティグループとネットワークACL
どちらもAWSの仮想ファイアウォールサービスではあるが、用途が違う。
基本的にはセキュリティグループで対策をしていき、ネットワークACLは補助的に使用する。

参考：[AWS セキュリティグループとネットワークACLの違い](https://qiita.com/TaigoKuriyama/items/d5b63bf7b169f4b8ffbd)

新規作成したセキュリティグループ/ネットワークACLでは、インバウンドトラフィックが全て拒否されている。「なんか繋がらないなー」とならないよう、設定はきちんと行おう。

### セキュリティグループ
ENI単位で設定するファイアウォール。
許可リストを設定する。拒否リストは設定できない。
ポート番号/アドレスレンジ/セキュリティグループ単位で許可リストを設定できる。

**ステートフル・インスペクション型**（戻り通信の設定が**不要**）

**備考**

- 参考：[Amazon VPCにおけるセキュリティグループの役割](https://dev.classmethod.jp/articles/amazon-vpc-security-group/)

### ネットワークACL
サブネット単位で設定するファイアウォール。
許可リストを設定する。拒否リストは設定できない。
ポート番号/アドレスレンジで許可リストを設定できる。

**ステートレス・インスペクション型**（戻り通信の設定が**必要**）

**備考**

- ACL（Access Control List）
- サブネットはネットワークACLを1つしか持てない。
- ネットワークACLはサブネット内の全のAWSリソースに適用される。

# デモンストレーション
### 完成系の図
![AWS_VPC_DEMO.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549894/2a50f7f6-f752-3a33-e989-9e488f82aa26.jpeg)
https://www.draw.io/ で作成。

### 作成手順
- リージョンが東京であることを確認する。
- VPC（`test-vpc`）を作成する。

##### VPC（`test-vpc`）
- サブネット（`test-subnet-0` `test-subnet-2`）を`test-vpc`に作成する。
- IGW（`test-igw`）を作成し、`test-vpc`にアタッチする。
- セキュリティグループ（`test-sg`）を`test-vpc`に作成する。
  - インバウンドルールに`SSH`を追加するのを忘れずに

##### サブネット（`test-subnet-0`）
- ルートテーブルに`0.0.0.0/0 : test-igw`を追加する。
- EC2（`Name: test-ec2-0`）を作成する。
  - 自動割り当てパブリックIP: `有効`
  - 新しいキーペア: `test-keypair`
- `test-ec2-0`のセキュリティグループを`test-sg`に変更する。
- `test-subnet-0`のネットワークACLを一応確認する。

##### `test-ec2-0`にSSH接続してみる
```bash:ターミナル
$ cd <秘密鍵があるディレクトリへのパス> # 秘密鍵があるディレクトリへ移動
$ chmod 400 <秘密鍵> # 権限変更
$ ssh -i <秘密鍵> ec2-user@<IPアドレス> # EC2にSSH接続
$ exit # EC2から抜け出す
```
- Elastic IPアドレスを割り当て、`test-ec2-0`に関連づける。
- 今度はElastic IPアドレスで`test-ec2-0`にSSH接続してみる。

```bash:ターミナル
$ ssh -i <秘密鍵> ec2-user@<Elastic IPアドレス> # EC2にSSH接続
$ exit # EC2から抜け出す
```

##### サブネット（`test-subnet-2`）
- EC2（`Name: test-ec2-2`）を作成する。
  - 自動割り当てパブリックIP: `有効`
  - セキュリティグループ: `launch-wizard-4`
  - **既存の**キーペア: `test-keypair`

##### `test-ec2-0`を踏み台サーバーにして`test-ec2-2`にSSH接続してみる

```bash:ターミナル
$ scp -i <秘密鍵> <秘密鍵> ec2-user@<IPアドレス>:/tmp/ # EC2の/tmp/に秘密鍵をコピー
$ ssh -i <秘密鍵> ec2-user@<Elastic IPアドレス> # EC2にSSH接続

# test-ec2-0
$ cd /tmp/
$ ssh -i <秘密鍵> ec2-user@<プライベート IPアドレス> # EC2にSSH接続
```

##### NATゲートウェイを通じて`test-ec2-2`からインターネットに接続してみる
- NATゲートウェイ（`Name: test-nat`）を`test-subnet-0`に作成する。
  - Elastic IP割り当てID: `新しいEIPの作成`
- ルートテーブル（`test-rtb`）を`test-vpc`に作成し、`test-subnet-0`に関連づける。
  - `0.0.0.0/0 : test-nat`を追加する。

```bash:ターミナル
# test-ec2-2
$ curl httpbin.org/ip # インターネット上のhttpbin.org/ipにアクセス
# 自分がどのIPアドレスを使用しているか返してくれる
# test-nat のElastic IPアドレスが帰ってくるはず
```

### 削除手順
このまま放置すると料金がかかるため、削除を行っていく。

- EC2（`test-ec2-0` `test-ec2-2`）を削除（`終了`）する。
- NATゲートウェイ（`test-nat`）を削除する。
- Elastic IPアドレス2つを削除（`開放`）する。
- VPC（`test-vpc`）を削除する。これで、
  - サブネット（`test-subnet-0` `test-subnet-2`）
  - IGW（`test-igw`）
  - セキュリティグループ（`test-sg`）
  - など、依存関係のあるものは全て削除される。

より詳しい解説は「[くろかわこうへいのAWS講座VPC編#4【デモ】自宅PCからEC2にログインしよう](https://www.youtube.com/watch?v=_LEDOr1Y57o)」を見ると良い。

# 参考
- [くろかわこうへいのAWS講座VPC編](https://www.youtube.com/playlist?list=PL2nCE2iR-lpmb9AR1ka1hq6WWORZ_crp2)　#1~4（チャンネル登録は[こちら](https://www.youtube.com/channel/UCirsB9lWx1Vao8jmbMK_nQg)）
- [動画で学ぶAWS講座 VPC編](https://www.youtube.com/playlist?list=PLtpYHR4V8Mg-hNPfIpCToq3ZLhvXMHFel)　section1~4（チャンネル登録は[こちら](https://www.youtube.com/channel/UCX30pfp4p82rIiSJmBygADw)）

***

<details><summary>テンプレート</summary><div>

# タイトル

タイトルの説明

**備考**

- 豆知識的な情報を書く
- なるべく書かない
</div></details>