【AWS初心者】AWSソリューションアーキテクトアソシエイト資格勉強で得た知識でサーバー構築をする

#はじめに
今年4月からAWSソリューションアーキテクトアソシエイトの勉強を始めました。
知識の定着には手を動かすのが良いと思い、AWSのサービスを幾つか使ってサーバー構築を行いました。

アソシエイトのために手を動かして学びたいけど時間がないという方が、AWSに触れやすくなると幸いです。

#各stepの見方
stepで作ろうとしているものを「作るもの」、完成図から見た構成図を「全体構成図」としています。
この記事はかなり長くなっていますので、構成図から参考になりそうなstepを見つけて抜粋してもらえればと思います。

#完成形
<h3>構成図</h3>
この記事で最終的にできる構成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/3b9ea641-bc9b-868b-3631-72216c105efd.png)

|サービス名|数|名前|
|---|---|---|
|EC2|3|ec2-web1,ec2-web2,ec2-public|
|ALB|1|elb-web|
|RDS|1|rds-db|
|CloudFront|1|-|
|SNS|1|sns-email（トピック名）|

<h3>特徴</h3>
・2台のEC2とロードバランサーによる負荷分散と冗長化
・Webサーバーをプライベートサブネットに配置することによるアクセス制限
・SNSによるDBの状態の変化の通知
・パブリックサブネットに配置したEC2を踏み台とする、プライベートサブネット上のWebサーバーの操作

#製作手順

##step1.VPCとサブネットの作成とルーティング

###作るもの＆全体構成図

東京リージョンにVPCとサブネット６個を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/ce9ff84d-07ca-14d7-9fcc-ab5404737a77.png)

###作成手順＆構築確認

1.東京リージョンにVPCを作成する。
　IPv4 CIDRブロック：10.0.0.0/16
2.サブネットを6個作成する。

|サブネット名|アベイラビリティーゾーン|IPv4 CIDRブロック|
|---|---|---|
|private-c|ap-northeast-1c|10.0.1.0/24|
|public-c|ap-northeast-1c|10.0.4.0/24|
|public-a|ap-northeast-1a|10.0.3.0/24|
|public-d|ap-northeast-1d|10.0.5.0/24|
|private-a|ap-northeast-1a|10.0.0.0/24|
|private-d|ap-northeast-1d|10.0.2.0/24|

3.インターネットゲートウェイを作成する
　作成したVPCにアタッチする

|項目|値|
|---|---|
|名前タグ|igw|

4.ルートテーブルを２個作成する

１個目：インターネットに接続するためのルートテーブル

|項目|値|
|---|---|
|Name|rt-public|
|サブネットの関連付け|public-a,public-c,public-d|

　ルートを編集

|送信先|ターゲット|
|---|---|
|10.0.0.0/16|local|
|0.0.0.0/0|作成したインターネットゲートウェイ|

２個目：インターネットに接続しないルートテーブル

|項目|値|
|---|---|
|Name|rt-private|
|VPC|作成したVPC|
|サブネットの関連付け|private-a,private-c,private-d|

　ルートを編集

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

※構築確認
もし作成方法に問題があればエラーが出て作成は完了できません

###備考
　ルートテーブルの送信先は送信元が指定した送り先を表し、ターゲットは通信の送り先を表します。
　作成できるサブネット数=2^(24-16)=256個
　割り振れるアドレス数=2^(32-24)-2=254個

##step2.簡易サーバーの構築とブラウザによるアクセス
###作るもの＆全体構成図
簡単なサーバーを作ってブラウザからアクセスしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/2071e8bc-edf4-ef14-9c8e-3fbd514d7634.png)

###作成手順＆構築確認
1.セキュリティグループを作成する

|項目|値|
|---|---|
|セキュリティグループ名|sg-public|
|説明|sg-public|
|VPC|作成したVPC|
|タグ|Name : sg-public|

　インバウンドルール

|タイプ|プロトコル|ポート範囲|ソース|説明-オプション|
|---|---|---|---|---|
|SSH|TCP|22|ClientのグローバルIPアドレス/32|allow ssh|
|HTTP|TCP|80|ClientのグローバルIPアドレス/32|allow http|

2.EC2を作成する

|項目|値|
|---|---|
|AMI|Amazon Linux 2|
|インスタンスタイプ|t2.micro|
|ネットワーク|作成したVPC|
|サブネット|public-d|
|自動割り当てパブリックIP|有効|
|ユーザーデータ|※下記に記載|
|ストレージの追加|デフォルトのまま|
|タグの追加|Name：ec2-public|
|セキュリティグループ|sg-public|
|キーペア|必要があれば作成|

　※ユーザーデータ

```bash
#!/bin/bash
yum update -y
amazon-linux-extras install -y php7.3
yum install -y httpd mariadb mariadb-server
systemctl start mariadb
systemctl enable mariadb
systemctl start httpd
systemctl enable httpd
mkdir /tmp/wp
cd /tmp/wp
wget https://ja.wordpress.org/latest-ja.tar.gz
tar xzvf latest-ja.tar.gz
mv wordpress/* /var/www/html
chown apache.apache -R /var/www/html
chmod +w -R /var/www/html
```

※構築確認
　ClientのPCのブラウザからアクセスできるか確認をします。(http://EC2のグローバルIPアドレス)
　↓のようなページが出ると思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/e640a83f-80d2-ddb1-a7c6-4592b2a24772.png)

###備考
　ユーザーデータにはサーバーを構築するためのパッケージをインストールするコードを記述しています。
　今回はAWSに焦点を当てるためコードの説明は割愛します。
　以降、作成したEC2は踏み台サーバーとして使用します。

##step3.AMIでEC2を1台複製
###作るもの＆全体構成図
サーバーをプライベートサブネットに複製します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/3d864e91-f440-97e1-2f1b-c6dc5402f745.png)

###作成手順＆構築確認

1.step2で作成したEC2のAMIを作成する（アクション＞イメージとテンプレート＞イメージを作成）

|項目|値|
|---|---|
|イメージ名|ami-ec2-public|
|イメージの説明|ami-ec2-public|

2.セキュリティグループを作成する

|項目|値|
|---|---|
|セキュリティグループ名|sg-web|
|説明|sg-web|
|VPC|作成したVPC|
|タグ|Name : sg-web|

　インバウンドルール

|タイプ|プロトコル|ポート範囲|ソース|説明-オプション|
|---|---|---|---|---|
|SSH|TCP|22|sg-public|allow ssh|
|HTTP|TCP|80|sg-public,ClientのグローバルIPアドレス/32,10.0.3.0/24,10.0.4.0/24|allow http|

3.作成したAMIを基にEC2を作成する。

|項目|値|
|---|---|
|AMI|ami-ec2-public|
|ネットワーク|作成したVPC|
|サブネット|private-c|
|自動割り当てパブリックIP|有効|
|タグの追加|Name：ec2-web1|
|セキュリティグループ|sg-web|
|キーペア|必要があれば作成|

※構築確認
　踏み台サーバーからec2-web1にSSH接続します。
　(i)ec2-publicにec2-web1にSSH接続するためのキーを送信する

```shell
scp -i ec2-publicのキー ec2-web1のキー ec2-user@ec2-publicのグローバルIPアドレス:キーを保存するパス 
```

　(ii)ec2-publicを踏み台に、ec2-web1にSSH接続する。

```shell
sudo -i
ssh -i ec2-web1のキー ec2-user@ec2-web1のローカルIPアドレス
```

##step4.ELBの作成とエンドポイントからのWebサイトの閲覧
###作るもの＆全体構成図
ALBを作成してそのエンドポイントからWebサイトにアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/4ac2d294-9b83-9295-4675-5bf69eed9d4a.png)

###作成手順＆構築確認
1.ターゲットグループの作成(EC2＞ロードバランシング＞ターゲットグループ)

|項目|値|
|---|---|
|ターゲットタイプ|Instances|
|ターゲットグループ名|tg-web|
|VPC|作成したVPC|
|ターゲット|ec2-web1|

2.ALB(Application Load Balancer)を作成する

|項目|値|
|---|---|
|名前|elb-web|
|VPC|作成したVPC|
|アベイラビリティーゾーン|public-a,public-c|
|セキュリティグループ|sg-public|
|ターゲットグループ|作成したターゲットグループ|

※構築確認
　ELBのエンドポイント(DNS名)へブラウザでアクセスします。
　問題なければstep2と同様にWordpressの画面が出てきます。

###備考
　ELBの種類は３つありますが、HTTPを通すELBが必要なのでALBを選択しました。
###参考
　https://dev.classmethod.jp/articles/tsnote-alb-health-check-001/
　https://www.infoscoop.org/blogjp/2014/08/14/use-search-and-replace-for-wordpress-when-moving/

##step5.データベースとなるRDSの作成とアクセス
###作るもの＆全体構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/e8f08170-06c0-0af1-aa68-9da6f8961485.png)

###作成手順＆構築確認
1.RDSのサブネットグループの作成

|項目|値|
|---|---|
|名前|subnetgroup-db|
|説明|subnetgroup-db|
|VPC|作成したVPC|
|アベイラビリティーゾーン|ap-northeast-1c,ap-northeast-1d|
|サブネット|10.0.1.0/24,10.0.2.0/24|

2.RDS用のセキュリティグループの作成

|項目|値|
|---|---|
|セキュリティグループ名|sg-db|
|説明|sg-db|
|VPC|作成したVPC|
|タグ|Name : sg-db|

　インバウンドルール

|タイプ|プロトコル|ポート範囲|ソース|説明-オプション|
|---|---|---|---|---|
|MYSQL/Aurora|TCP|80|sg-web|allow sql|

3.RDSの作成

|項目|値|
|---|---|
|テンプレート|開発/テスト|
|DBクラスター識別子|db|
|マスターユーザー名|任意の名前|
|マスターパスワード|任意のパスワード|
|DBインスタンスサイズ|db.t2.small|
|VPC|作成したVPC|
|サブネットグループ|subnetgroup-db|
|VPCセキュリティグループ|sg-db|
|アベイラビリティーゾーン|ap-northeast-1d|

※構築確認
　WebサーバーからRDS内のデータベースにアクセスしてみます。
　(i)WebサーバーにSSH接続します。
　(ii)下記のコマンドでアクセスします。

```shell
mysql -h RDSのエンドポイント(ex.db....com) -P 3306 -u マスターユーザー名(ex.admin) -p
```
　　パスワードを求められるので設定したマスターパスワードを入力します。
　　MySQL [(none)]>と出たらアクセス成功です。

##step6.Wordpressの設定変更
###やること
　構成には触れず、コマンドによる操作がメインになります。
　Wordpressでウェブページの記事の投稿の一歩手前まで行きます。
　具体的には、データベースの作成をして、アップロード上限を2GBに増やします。

###作成手順＆構築確認
1.DBへのアクセス
　step5と同様にDBにアクセスします。

2.SQLによるデータベースの作成
　下記のコマンドでデータベースを作成します。

```sql
create database 任意のデータベース名;
```

3.ローカルPCからブラウザでウェブサーバーにアクセスをして、初期設定を行います。
　初回アクセス時には下記の項目を入力します。

|項目|値|
|---|---|
|データベース名|作成したDB名|
|ユーザー名|マスターユーザー名|
|パスワード|マスターパスワード|
|データベースのホスト名|RDSのエンドポイント|

　次に必要情報を入力します。(サイトのタイトル、ユーザー名、パスワード、メールアドレスなど)
　正しく設定されるとWordpressのダッシュボード画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/f1122b14-5b0c-30ba-be9c-b89598e0b756.png)

4.メディアの投稿の最大サイズを2MBから2GBに増やします。
　viコマンドで/etc/php.iniを開きます。
　php.iniの各設定を下記の表の値に変更します。

|項目|値|
|---|---|
|post_max_size|2000M|
|upload_max_filesize|2000M|

　変更後、下記のコマンドを実行します。

```shell
systemctl restart php-fpm
```

※構築確認
　Wordpressのメディアライブラリの画面にて、最大アップロードサイズが2GBになっていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/f43eac1c-31a5-74e6-0be1-70e50721285c.png)

###備考
　管理者画面へ行くには、urlに/wp-adminをつけてアクセスする

###参考
　https://mamepin.com/archives/180

##step7.WebサーバーのEC2をもう１台複製する
###作るもの＆全体構成図
Webサーバーをもう１台複製します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/d89b635f-550a-7649-82a4-83ce96975819.png)

###作成手順＆構築確認
1.ec2-web1のAMIを作成する。

|項目|値|
|---|---|
|イメージ名|ami-ec2-web|
|イメージの説明|ami-ec2-web|

2.ec2-web1のAMIからインスタンスを作成する

|項目|値|
|---|---|
|AMI|ami-ec2-web|
|ネットワーク|作成したVPC|
|サブネット|private-a|
|自動割り当てパブリックIP|有効|
|タグの追加|Name：ec2-web2|
|セキュリティグループ|sg-web|
|キーペア|必要があれば作成|

3.ALBのターゲットグループへec2-web2の追加

※構築確認
　ec2-web1を停止してもウェブページが正しく表示されるか確認します。
　(i)ec2-web1を停止します。
　(ii)ALBのDNSにアクセスして、ウェブページを確認します。

##step8.SNSによるRDSのイベントのEメール通知
###作るもの＆全体構成図
SNSを使用してRDSの状態の変化をEメールで通知する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/df296f58-3647-abac-ed81-3ca51bb1538d.png)

###作成手順＆構築確認

1.SNSのトピックを作成する

|項目|値|
|---|---|
|タイプ|スタンダード|
|名前|sns-topic-send-email|
|表示名-オプション|sns-topic-send-email|

2.SNSのサブスクリプションの作成

|項目|値|
|---|---|
|トピックARN|作成したトピックのARN|
|プロトコル|Eメール|
|エンドポイント|通知を受信したいEメールアドレス|

　サブスクリプションの作成後、登録したエンドポイントにメールが届くのでアドレスの確認を行う。

3.RDSのイベントサブスクリプションを作成する

|項目|値|
|---|---|
|名前|rds-event|
|ターゲットのARN|作成したSNSのトピック|
|ソースタイプ|クラスター|
|特定のクラスター|作成したRDS|

※構築確認
　RDSを停止させると、↓のような停止を通知するメールが届くことが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/fc1440dc-b36b-cce3-a122-04cbf5435e7d.png)

##step9.CloudFrontの設定
###作るもの＆全体構成図
ELBの前段にCDNサービスであるAmazon CloudFrontを使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/91298b43-fb62-e4bc-9fa9-3e0d65f39e94.png)

###作成手順＆構築確認
　CloudFrontのディストリビューションを作成します。

|項目|値|
|---|---|
|Origin Domain Name|ALBのDNS|

#断念した案

●Global Acceleratorの利用
・断念理由
今回はALBの前段に置くものとしてCloudFrontを採用したため。

・使い方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/74f0fe83-20c3-dca0-3751-34435ba026cb.png)

●SQSを使ったEメール通知
・断念理由
時間が足りなかったから

・使い方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/802ab740-46fe-7984-749d-9927533857e2.png)

●SESを使ったEメール通知
・断念理由
時間が足りなかったから。

・使い方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474054/e488407c-fe23-d65f-9316-8adbf3b50c55.png)

・参考
　https://qiita.com/OMOIKANESAN/items/1b8941258fb7ebbdb057
　https://aws.amazon.com/jp/premiumsupport/knowledge-center/lambda-send-email-ses/

#終わりに

100以上あるAWSサービスと比べれば、今回やったことはAWSのほんのさわり程度なのだと思います。AWSを学ぶには時間が足りないなと思う毎日です...
まだ、資格は受かっていないので、今後も勉強を頑張っていきたいと思います！