モダンな技術を全く知らないSIer5年目がWebサービスを作ることになったため0から勉強する ~AWS編その3~

# はじめに
現在SIer5年目でjavascript(Jqueryのみ)、PHP(フレームワーク無し)を2年ほど、C#(Windowsアプリ)3年ほどやってきました。
色々なご縁があり、個人で最近Webサービスの立ち上げをやることになったのですが何せ本当にWebサービスを立ち上げるための知識がほぼ0に等しいです:sob:

ただ今後のキャリアを考えた時に今のままではいけないと思いチャレンジすることにしました。

まずは最初に技術を習得しないといけないので、学ぶ＆アウトプットするために毎回投稿していこうと思います。
今後身についていこうと思ってるのは下記のような技術です。
**AWS**
**Docker**
**CI/CD環境の構築(何を使うかはまだ未定)**
**Laravel**
**Nuxt.js**

今回はAWSについて学んでいきます。

# 今回学ぶこと
AWSでのVPC構築について
WebサーバとDBサーバを構築していきます。

最終的に構築するアーキテクチャ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/de40ee4d-6cc1-2e0c-a5ff-fd9484aa7c1c.png)

- 外部のネットワークアクセス用のInternetGWmを作成する
- Webサーバは外部からアクセスを許可する
- DBサーバは内部からのアクセス(厳密にはWebサーバからのみ)許可する
- DBを構築する際に外部からmysqlなどインストールするのにネットワークに繋がないといけないため
NATGWから外部に接続する様に設定

### 

- VPC
ネットワークアーキテクチャの親玉

- サブネット
VPCの中にIPの割り当てをした領域の設定
パブリックは外からでも見れる領域
プライベートはVPCの内部からしか見れない領域

- ルートテーブル
IPアドレスの指定がされた時にどこにアクセスを行うのか設定を行う

- internetGW
外部のNWとアクセスするためのGW

- NAT GW
プライベートサブネットが外部のネットワークにアクセスするために経由させる機能

### 構築手順

1. VPCを作る
2. パブリックサブネットをを作る▶︎Webサーバの構築
3. プライベートサブネットを作る▶︎DBサーバの構築

## リージョン/アベイラビリティーゾーンとは
クラウドでのサーバを構築する実際の場所などの定義

![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/31d12e83-3c21-da0c-b3d2-ab48dd99c1fb.png)


### リージョン
複数の地域を束ねたデータセンターの場所

### アベイラビリティーゾーン
リージョンの中でも各データセンターの場所

### VPCとサブネットの関係
VPCは全てのアベイラビリティーゾーンにまたがっている
サブネットは各アベイラビリティーゾーンに設定される
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/e3f263b7-77cf-4d8f-77e7-77f2b1f74167.png)

# 1. VPCを作る
VPCだけでなく、パブリック/サブネット/InternetGWも一緒に作成していく

### 新たにVPCを作成する

VPCウィザードの開始ボタンを押下する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/f57331c1-b969-2f00-2277-3518b21e10df.png)

1個のVPCを作成を選択し、下記の設定にしVPCの作成を押下
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/e21fc4ee-b203-b566-b408-72e43601cdf1.png)

設定したVPC名のVPCが作成される
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/0a7526d8-d5e6-b435-dd98-0cc583454e53.png)


publicサブネットも作成され、ルーティング設定も自身のIPアドレス群ならlocalに、それ以外であればinternetGWにいく様に定義されている
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/ba95f748-7276-0169-dfbf-4852c40b34e3.png)

### サブネットを新しく作る
先ほどは**サブネット1a**を作成したので、今度は**サブネット1c**を作成していく
サブネット作成ボタンを押下し、新しくサブネットを作成する設定を行っていく
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/a81797d7-894f-6662-d4fc-ce2c73ac1028.png)

作成後、ルーティングで**internetGW**に対して設定されてないので設定を行っていく
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/f598c93f-b312-3701-3203-67386e9b2fc9.png)

**サブネット1a**と同じルーティングテーブルに設定していく
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/4a43767a-16b9-3f7e-bbc0-2d1e6fae24ec.png)



# 2. パブリックサブネットをを作る▶︎Webサーバの構築

### Webサーバ用EC2の作成
今回もインスタンスの作成から作業を行っていく
今までと違う箇所をピックアップする

**インスタンスの詳細の設定**

- ネットワークを先ほど作ったVPC
- サブネットは*1a*の方
- 自動割り当てパブリックIPを**有効化**にする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/f855f1aa-1a95-0bd5-a087-ac3e62449917.png)

**タグの追加**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/3223e3a8-5434-85a7-9c0a-f0c17a49695f.png)

**セキュリティグループの設定**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/3f2318b3-960a-46d9-fdf7-21ecfcac0dd9.png)

※本体はフルオープンにするべきではない

キーペアは前回作成したものを再利用する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/66caf800-506e-d0ff-b132-e2bb21cb0fca.png)

### Webサーバ用EC2の設定
サーバの構築ができたので、インスタンスを起動しSSHで接続する

```sh
ssh -i {sshキーファイルのpath} ec2-user@{インスタンスのpublicIPアドレス}
```

下記の手順でWebサーバの設定を行う

```sh
## ホスト名の変更

sudo vim /etc/sysconfig/network

====

HOSTNAME=XXXX

====

sudo vi /etc/hosts

====

127.0.0.1 に↑を追加する

====

## OS の言語設定

sudo vi /etc/sysconfig/i18n

====

前）LANG=en_US.UTF-8

後）LANG=ja_JP.UTF-8

====

## OS の時刻設定

sudo cp /usr/share/zoneinfo/Japan /etc/localtime

sudo vim /etc/sysconfig/clock

====

ZONE="Asia/Tokyo"

====

# 必要なパッケージの導入

sudo yum update -y

sudo yum install -y httpd24

sudo yum install -y php70 php70-mbstring php70-pdo php70-mysqlnd

sudo yum install -y mysql

sudo yum install -y git

# Apache の設定

## DirectoryIndex の変更

sudo vim /etc/httpd/conf/httpd.conf

====

変更前）

<IfModule dir_module>

    DirectoryIndex index.html

</IfModule>

変更後）

<IfModule dir_module>

    DirectoryIndex index.php index.html

</IfModule>

====

====

ServerName もコメントアウトを外して、hostname に変更する

====

## httpd.conf の確認テスト

sudo /etc/init.d/httpd configtest

## EC2 インスタンス再起動時に、自動で httpd プロセスが上がるように設定

sudo chkconfig httpd on

## httpd の立ち上げ

sudo service httpd start

# PHP の設定
# 日本語を扱える様に設定を変更していく

sudo vim /etc/php.ini

====

# Dynamic Extensions の下の方に

extension=mbstring

====

====

mbstring.language = Japanese

mbstring.internal_encoding = UTF-8

====

# サンプルリソース取ってくる

git clone https://github.com/ketancho/udemy-aws-14days.git

cd udemy-aws-14days/Day3/

sudo cp index.php /var/www/html/

sudo cp -r img /var/www/html/


```

# 3. プライベートサブネットを作る▶︎DBサーバの構築



### DBサーバを構築する

#### プライベートサブネットの作成
DB構築箇所のプライベートサブネットを作成する
1aと1cそれぞれ作成する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/c60daea9-b862-20a0-93b7-c7f03b47a2b4.png)

#### ルートテーブルの作成
ルートテーブルメニューからルートテーブル作成を押下し、画像の様に設定を行う
VPCは今回作成したものを選ぶ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/82a01160-332b-534f-3dc0-cc38d6b4c19e.png)

それぞれ先ほど作成したプライベートサブネットにルートテーブルを適用する
1cの方も同様に
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/40f9a582-1298-5ad9-f4f3-dcb9ba0f856a.png)

#### DBサーバ用インスタンスの作成

**インスタンスの詳細の設定**
- Webサーバのインスタンスで指定したVPC
- サブネットは*プライベートサブネット1a*
- 自動割り当てパブリックIPはpublicIP入らないため**無効化**にする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/ee9cc00a-0569-f591-aac7-ab8626ea3059.png)

- ユーザデータでサーバの設定を自動化する

```sh
#!/bin/bash

# ホスト名
sed -i 's/^HOSTNAME=[a-zA-Z0-9\.\-]*$/HOSTNAME=udemy-aws-14days-db-1a/g' /etc/sysconfig/network
hostname 'udemy-aws-14days-db-1a'

# タイムゾーン
cp /usr/share/zoneinfo/Japan /etc/localtime
sed -i 's|^ZONE=[a-zA-Z0-9\.\-\"]*$|ZONE="Asia/Tokyo”|g' /etc/sysconfig/clock

# 言語設定
echo "LANG=ja_JP.UTF-8" > /etc/sysconfig/i18n
```

**タグの追加**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/92e81e62-2400-f932-5da2-7bd130b724a5.png)

**セキュリティグループの設定**

- 新しくDBサーバ用のSGを作成
- SSHとMYSQLの許可をする
- アクセスを許可するのはWebサーバで設定されているSGのみ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/40100ca7-d342-b54d-e097-c3ec0e5b8761.png)


※セキュリティグループについての補足
セキュリティグループはアクセスを許可をIPだけでなく、SGに対しても指定できる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/232059ec-67d4-a103-49cc-bda649cc3305.png)

#### NATGWを導入する
1. NAT GWの作成

[NATゲートウェイ]>[NATゲートウェイの作成]
NATGWを配置するサブネットIDとPublicIPアドレスを設定する
新しいEIPを作成してそのまま設定することも可能です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/3d3e0dc3-0d8a-24db-cf6f-da045d9b4f74.png)


2. ルートテーブルの設定

DBサーバを配置しているプライベートサブネットのルートテーブルをローカルIP以外に設定された際にNATGWにアクセスする様に設定を行う
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/61f435f2-34b6-20e9-5a56-ffe9df171c67.png)


#### MySQLのインストール

1. WebサーバからDBサーバにSSHで接続できる様にSSHキーのファイルをローカルからコピーする
2. DBサーバまで接続する
3. mysqlをインストールし、インスタンス起動時にmysqlも起動する様に設定
4. アプリを動作させるためにデータの作成
5. アプリからDBにアクセスしデータを取得する様に修正


```sh
# 秘密鍵を Web サーバへコピー
scp -i udemy-aws-14days.pem udemy-aws-14days.pem ec2-user@x.x.x.x:/home/ec2-user/

# Web サーバへSSH（x.x.x.x は Web サーバのグローバルIPアドレス）
ssh -i udemy-aws-14days.pem ec2-user@x.x.x.x

# Web サーバへSSH（y.y.y.y は DB サーバのプライベートIPアドレス）
ssh -i udemy-aws-14days.pem ec2-user@y.y.y.y

# yum update
sudo yum update -y

## インストール＆初期設定
sudo yum install -y mysql57-server

sudo chkconfig mysqld on

sudo service mysqld start

mysqladmin -u root password 


## DB サーバ上で mysql 接続 & サンプルテーブルの作成
mysql -u root -p

create database simple_blog;

use simple_blog;

create table posts (id int not null primary key, title varchar(100), detail varchar(1000), image varchar(1000));

insert into posts values (1, "XXXX", "XXXXXXXXXX", "./img/img1.jpeg");

insert into posts values (2, "YYYY", "YYYYYYYYYY", "./img/img2.jpeg");

grant all privileges on *.* to root@"%" identified by 'rootroot' with grant option; 


## Web サーバから mysql 接続
mysql -h x.x.x.x -u root -p
```



### SGとネットワークACL(NACL)について
SGはインスタンスごとに対してNACLはサブネット単位で設定を行える
IN：OUTそれぞれに制限をかけることが可能

![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/6dbd2c2b-4670-b2a9-1ba4-99057eb104bc.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/305479/3f458bb4-a49d-a226-185c-3ec0237ab09e.png)

# ネットワーク設計での注意点
1. VPC&サブネットは将来も考えて適切な広さにする
2. 広すぎてもIPが被った際には動かなくなる恐れも(VPC Peering)
3. 1システム/1アカウント(1IAM)にするべき


# 補足資料
[クラウド活用資料集](https://aws.amazon.com/jp/aws-jp-introduction/)