AWSクラウド環境の構築からSpring Bootアプリのデプロイまで（初心者向け）

アプリケーションエンジニアとして、普段の仕事でインフラ設計をなかなか経験したことがないですが、AWSを通じてインフラ知識がほぼZeroの私でもインフラ基盤を気軽に構築できて感動しました。今回は、私と同じの初心者に向け、AWSクラウド環境の構築からSpring Bootアプリのデプロイまでの手順を共有します。

#環境構成図
AWS構成について、東京リージョン内で２つのアベイラビリティゾーン（AZ）を使用した冗長構成を採用します。EC2インスタンスはその２つのAZに分散配置し、ALB（ロードバランサ）経由でアクセスを分散する構成とします。また、RDSインスタンスはEC2と同様に２つのAZに分散配置するようMulti-AZの構成とします。
*この構成は[AWSの無料利用枠](https://aws.amazon.com/jp/free/)を超えているため、料金がかかります！ご注意ください。*
![全体構成図.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/36e9f316-70db-b5c9-94be-5c43a0713be6.jpeg)


#まず、VPCを構築します！
外部ネットワークからAWS内のインスタンスに到達できるように、AWS内の各インスタンスにIPアドレスが割り振られ、適切にルーティングされる必要があります。このような仮想ネットワークを提供しているサービスをAmazon Virtual Private Cloud（VPC）と言います。

##VPCの構成について
練習とは言え、実戦に近いVPC環境を目指しています。今回のVPCは、インターネット通信用の**パブリックサブネット**とインターネットから遮断される**プライベートサブネット**の２種類で構成されます。その２種類のサブネットへのアクセスを制御するために、それぞれに異なるセキュリティグループを適用します。APサーバーはパブリックサブネット上に構築し、DBサーバーはプライベートサブネット上に構築します。
![VPC構成詳細.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/ee342d6b-3ef1-b9e8-d40b-4629b73a7a68.jpeg)

##VPC作成
AWSアカウントを新規登録した後に、デフォルトのVPC環境が既に作られていましたが、今回はそれを利用せずに、一から以下のVPCを新規構築します。
![vpc構成図.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/de7c4d27-c93a-1332-8c1a-a67012d5a528.jpeg)

１．`AWSマネジメントコンソール`⇒`VPC`をクリック⇒左のメニューから`VPC`を選択⇒`VPCの作成`ボタンを押下します。
２．VPCの作成画面に適当な名前を入力し、CIDRブロック欄にIPアドレス範囲に入力します。（今回は「10.0.0.0/16」を入力します。）
３．`はい、作成する`ボタンを押下します。
![VPC作成.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/ae8dc26d-d4c9-d99a-150b-6d636189847c.jpeg)



##サブネット作成
上記のVPCの中にサブネットを作成します。サブネットは複数のAZに跨って作成することはできないので、必ず１つのAZを指定して作成します。負荷分散と冗長化のために、APサーバー用サブネットとDBサーバー用サブネットをそれぞれ２つずつ構築します。
![subnet構成.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/23c6f2ac-2f15-bf59-dee9-608f5fe2e4f9.jpeg)

１．左のメニューから`サブネット`を選択⇒`サブネットの作成`ボタンを押下します。
２．サブネットの作成画面に、適当な名前入力し、上記作成されたVPCを選んでCIDRブロックを入力します。（Subnet1は「10.0.0.0/24」とします。）
![subnet1作成.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/bda089c7-0bea-539c-8596-005750b356b7.jpeg)
３．上記と同じの手順で、Subnet2、Subnet3、Subnet4を構築します。

|   Subnet         |       AZ          |  IPv4 CIDRブロック  |
|:----------------:|:-----------------:|:------------------:|
| public-subnet1   |   ap-northeast-1a |   10.0.0.0/24      |
| public-subnet2   |   ap-northeast-1c |   10.0.1.0/24      |
| private-subnet1  |   ap-northeast-1a |   10.0.2.0/24      |
| private-subnet2  |   ap-northeast-1c |   10.0.3.0/24      |

完成後サブネット一覧画面
![subnetList.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/f3067166-4c0c-2d24-2a20-38aeebd4f21f.jpeg)


##インターネットゲートウェイ（IGW）とルートテーブルの作成
**インターネットゲートウェイ（IGW）**は、名前の通りにインターネットとの出入口であり、VPCと外部ネットワークの間で通信を行うために設置します。
また、上記作成されたサブネットがパブリックサブネットなのか、あるいはプライベートサブネットなのかは、そのサブネットに適用されている**ルートテーブル**によって決まります。
送信先：0.0.0.0/0のターゲットとしてIGWが設定されているルートテーブルが適用されているサブネットはパブリックサブネットです。一方、送信先：0.0.0.0/0のターゲットとしてIGWが設定されていないルートテーブル（デフォルトのまま）が適用されているサブネットはプライベートサブネットです。
![igw&rtb.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/424d1bbd-09bb-a4d9-6a85-20fbac6c3efa.jpeg)

１．左のメニューから`インターネットゲートウェイ`を選択⇒`インターネットゲートウェイの作成`ボタンを押下します。
２．適当な名前を入力し、`はい、作成する`のボタンを押下します。
![igw.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/214e89e0-153e-dc19-4cfa-e44a829040a9.jpeg)
３．`VPCにアタッチ`のボタンを押下し、VPCとの紐付けを行います。
![igw attache.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/7a22cae6-2f43-1799-8f51-c66ee88bf333.jpeg)
４．左のメニューから`ルートテーブル`を選択⇒`ルートテーブルの作成`ボタンを押下します。
５．パブリックサブネットであるSubnet1のルートテーブルを作成するために、適当な名前を入力し、VPCとの紐付けを行い、`はい、作成する`のボタンを押下します。
![rtb1.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/207ef03c-2c78-c91c-c86a-65d96b58a905.jpeg)
６．上記と同様の手順で、public-rtb2を構築します。今回はプライベートサブネット用ルートテーブルを作成せずに、デフォルトのルートテーブルを使用します。
７．パブリックサブネット用のルートテーブルに、デフォルトゲートウェイ（送信先0.0.0.0/0）のターゲットにIGWを登録します。
![route.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/5344e257-01a0-40f0-a31b-e440abbb1368.jpeg)
ルートテーブル内の「10.0.0.0/16  local」というルート情報は、デフォルトの設定で変更・削除することができません。このデフォルト設定は、VPC内の通信はルートテーブルでは制御できないということで、同じVPC内のサブネットであればサブネット間の通信が可能なっていることを意味しています。


##セキュリティグループの作成
セキュリティグループは、AWS内各インスタンスごとのファイアウォールで、受信（インバウンド）と送信（アウトバウンド）のアクセス制御ができます。各インスタンスには少なくとも１つのセキュリティグループを適用する必要があります。
![VPC構成詳細.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/078df70c-66d6-03c0-7bcc-3bfd4710cdff.jpeg)
１．左のメニューから`セキュリティグループ`を選択⇒`セキュリティグループの作成`ボタンを押下する。
２．APサーバー用セキュリティグループを作成するために、適当な名前を入力し、VPCへの紐付けを行い、`はい、作成する`のボタンを押下します。
![sg作成.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/2006ffc8-5b6d-0313-06a7-d9ce8e9d5cd2.jpeg)
３．上記と同じの手順でDBサーバー用のセキュリティグループを作成します。
![private sg.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/aaaa5305-4046-ce0e-78c2-7423e037a49c.jpeg)
４．それぞれのセキュリティグループに受信（インバウンド）と送信（アウトバウンド）のルールを作成します。デフォルトでインバウンドは許可されているルールがないため、どこからのアクセスも受け付けません。一方、アウトバウンドは、デフォルトで全ての宛先／ポート番号に対するアクセスを許可するルールが設定されています。
外部からアクセスできように、APサーバー用セキュリティグループでSSHの22ポートとウェブアプリの8085ポートを開けておきます。
![public inbound.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/814d7015-ba09-e5e6-6779-85e79a93bb82.jpeg)
一方、DBサーバー用セキュリティグループは、APサーバーからDBアクセスのみを許可するために、Auroraの3306ポートを開けておきます。
![private sg rule.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/91009687-f650-fe59-bbfb-1153a4c37167.jpeg)

以上でVPCの構築が完了しました。

#RDSインスタンスの構築
RDSは、リレーショナルデータベースのマネージャーサービスのことです。RDSで選択できるデータベースエンジンは、以下の６種類です。
・Amazon Aurora
・MySQL
・MariaDB
・PostgreSQL
・Oracle
・MS SQL Server
今回はAurora DBを構築します。Auroraは、MySQLと互換性のあるAWS独自のリレーショナルDBエンジンで、最大で MySQL の5倍のスループットおよび3倍の PostgreSQL スループットのパフォーマンスを持つと言われます。
![RDS.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/754f9b50-a9be-1b4f-1fb7-289c642b3bb6.jpeg)


##サブネットグループの作成
DBインスタンス作成の前提条件として、VPC内でDBサブネットグループを指定する必要があります。
DB サブネットグループには、特定のリージョン内の少なくとも 2 つのアベイラビリティーゾーンにサブネットが必要です。 VPC に DB インスタンスを作成するときに、DB サブネットグループを選択する必要があります。Amazon RDS は、その DB サブネットグループと優先アベイラビリティーゾーンを使用し、サブネットとそのサブネット内の IP アドレスを選択して DB インスタンスに関連付けます。
１．`AWSマネジメントコンソール`⇒`RDS`をクリック⇒左のメニューから`サブネットグループ`を選択⇒`サブネットグループの作成`ボタンを押下します。
２．名前等を適当に入力し、２つのDB用サブネット（private subnet1、private subnet2）を追加し、`作成`ボタンを押下します。
![db subnet group1.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/19ef6817-169f-8a80-64ee-40b69a68059c.jpeg)


##DBインスタンスの作成
１．左のメニューから`インスタンス`を選択⇒`DBインスタンスの起動`ボタンを押下します。
２．エンジンの選択画面にAmazon Auroraを選択します。
![db1.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/adb7ec86-ce7e-a9f8-2741-0ae34bbf55fe.jpeg)
３．DB詳細画面にて、DBインスタンスクラスなどを指定し、`次のステップ`ボタンを押下します。
※マルチAZ配置を選んだ場合、料金2倍かかります！
![db2.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/b5866740-775d-0a23-148b-42234c05def4.jpeg)
４．VPC、DBサブネットグループ、優先AZ、およびセキュリティグループを指定します。
![db3.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/b0a08b9e-b21d-e411-7a22-0c19ba134bb7.jpeg)
５．設定完了後にDBインスタンスが作成中の状態であることを確認できます。
![db4.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/a8e876a8-f910-ac9d-dbfd-e7f319bc29f5.jpeg)



#EC2インスタンスの構築
やっと、EC2まで辿り着きました。Amazon Elastic Compute Cloud（EC2）は、AWSにおける仮想サーバのことです。今回負荷分散のために、２つのインスタンスを構築します。
![EC2.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/1d590c3c-e8c3-cc17-44b0-17a2737b40c8.jpeg)

##EC2インスタンスの作成
１．`AWSマネジメントコンソール`⇒`EC2`をクリック⇒左のメニューから`インスタンス`を選択⇒`インスタンスの作成`ボタンを押下します。
２．インスタンスの種類にAmazon Linuxを選択します。
![ec21.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/d1c1647d-2a54-c5f9-6c62-4a24e0989c33.jpeg)
３．インスタンスタイプ選択画面に、無料利用枠対象のタイプを選択します。
![ec22.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/7ab1ae06-989b-dcc2-7f7a-cc6b58c31602.jpeg)
４．詳細設定画面に、VPCとサブネットを指定します。
![ec23.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/6c9d454a-ce06-426b-12a1-34676f6a32bc.jpeg)
５．ストレージを追加します。
![ec24.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/94eb4992-320f-65cc-84f3-c12bf0920265.jpeg)
６．APサーバー用セキュリティグループを指定します。
![ec25.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/7cdabf8c-a04d-2435-d993-d9bac73db020.jpeg)
７．最後に、EC2にログインするためのキーペアをダウンロードし、`インスタンスの作成`ボタンを押下し、インスタンス作成が完了です。
![ec26.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/452ed0da-0cc0-6785-4446-f54310771998.jpeg)

##ELASTIC IPの関連付け
上記のEC2インスタンスに対して、静的なパブリックIPアドレスを付与するために、ELASTIC IPの割り当てが必要です。
１．左のメニューから`ELASTIC IP`を選択⇒`新しいアドレスの割り当て`ボタンを押下します。
![eip1.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/80b6ae1e-633a-65ab-10b9-61f1fc17f609.jpeg)
２．EC2インスタンスに関連付けを行います。
![eip2.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/da79a830-e8dd-f042-6b3f-1516b849dd35.jpeg)


##EC2環境の初期設定
Tera TermなどのSSHクライアントを使って上記のELASTIC IPを入力し、EC2インスタンスにアクセスします。
![ec27.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/3bf5aca0-b17c-9ec8-4c0e-d20e36ce8a1c.jpeg)
「ec2-user」ユーザーを使って、先ほどダウンロードしたキーでログインします。
![ec28.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/9532b1af-76d1-b12f-1226-66d21a622354.jpeg)

![tera term.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/4a6de568-8cf6-2f73-5fda-585254bf7fac.jpeg)


##無事にログインできたら、EC2の初期設定を行います。
```bash
# 最新のソフトウェアにアップデート
$ sudo yum update -y
```

```bash
# ホスト名変更
$ sudo hostname ec2-1-cinpo1
$ sudo vim /etc/sysconfig/network
HOSTNAME=ec2-cinpo1;
# ホストファイルを編集し、AWSから払い出された<Private IP>を書く。
$ echo "17X.XX.X.X30 ec2-cinpo1" |sudo tee -a /etc/hosts
# ホスト名確認
$ hostname -f
```

```bash
# タイムゾーン変更
# /etc/sysconfig/clockの編集
$ echo -e 'ZONE="Asia/Tokyo"\nUTC=false' | sudo tee /etc/sysconfig/clock
# タイムゾーンファイルの変更
$ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# 結果確認
$ date
```

```bash
# Java 8のインストール
$ sudo yum install java-1.8.0-openjdk.x86_64
# Java 8の選択
$ sudo alternatives --config java
# 結果確認
$ java -version
```

##2台目のEC2を構築します。
上記と同じの手順で、2台目のEC2インスタンスを構築します。

##Aurora環境へのデータ移植
```bash
# Auroraサーバーに接続するために、MySQLクライアントをインストールします。
$ sudo yum install mysql
```

```bash
# Auroraサーバーに接続し、データベースの新規作成やデータの移植を行います。
$ mysql -h <RDSインスタンスのエンドポイント> -u username -p
$ create database sampleDB

...下記省略...
```
![mysql.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/77f28c84-a84e-61ad-6e37-d5df27acfce0.jpeg)


##Spring Bootアプリのデプロイ
１．Tera TermのSSH SCP転送を利用し、Spring Bootアプリをローカルから上記2つのEC2インスタンスにアップロードします。
２．完了後に、従来通りにSpring Bootアプリを起動します。

```bash
$ java -jar XXXXXXXX.jar
```
![boot.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/e30bd2f8-11b2-92f7-7f18-88b7ce5a51d7.jpeg)


３．この時点で、ELASTIC IP:8085 にアクセスしてみれば、アプリ画面が表示されるはずです。

#ロードバランサーの作成
最後に、ロードバランサー（Application Load Balancer [ALB]）を適用し、APサーバーの負荷分散を実現します。
![ALB.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/4e3c3c71-0764-8ad0-9110-f3615920254a.jpeg)

##ターゲットグループの構築
ALB適用の前提条件として、EC2インスタンスをターゲットとしてターゲットグループに登録する必要があります。ALBは、クライアントにとって単一の通信先として機能し、登録済みターゲットに受信トラフィックを分散します。
１．`AWSマネジメントコンソール`⇒`EC2`をクリック⇒左のメニューから`ターゲットグループ`を選択⇒`ターゲットグループの作成`ボタンを押下します。
![ALB1.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/a8b8649b-1f9c-471c-3fca-c3f98fd185e7.jpeg)
２．ターゲットグループ一覧画面にて選択済みのターゲットグループにターゲットの登録を行います。
![ALB2.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/d8a1bd61-0870-0624-930d-2ac482ed8f35.jpeg)
３．EC2インスタンスをターゲットとしてターゲットグループに登録します。
![ALB3.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/93ba546b-f4d8-dbb3-3e1f-e5886db4f6bb.jpeg)


##ALBの構築
１．左のメニューから`ロードバランサー`を選択⇒`ロードバランサーの作成`ボタンを押下し、Application Load Balancerを選択します。
![ALB4.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/c7373e0b-cce4-cece-57ec-620eb0397192.jpeg)
２．名前を適当に指定し、リスナーとサブネット等を指定します。
![ALB5.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/e2443d3f-23c0-b181-b97f-a8f3b5d7be3d.jpeg)
３．セキュリティグループを指定します。
![ALB6.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/ad6f08b7-a30e-8182-a830-4a3cbb702a12.jpeg)
４．先ほど作成されたターゲットグループを指定します。
![ALB7.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/81d6b9bd-5818-859e-b93b-f976d15a5b54.jpeg)
５．作成中のステータスとなり、１～２分後に利用可能となります。
![ALB8.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/0936949a-a3c2-2c06-40c3-6995eb1d0ed9.jpeg)

#動作確認
以上、AWS環境の構築からアプリのデプロイまで完成しました。
http://<ALBのDNS名>:ポート/にアクセスすれば、アプリ画面が表示されたら完成です。
![final1.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/7522dbe3-d8c3-84f8-fc79-60ce1bc1157a.jpeg)