AWS環境をゼロから設計、構築してみた。

## 背景

今までゼロからインフラを構築する経験がなかった
（別部署のインフラチームにオーダーして構築してもらうなどしていた）のですが、
自分で構築する機会があったので、他社事例などを参考にしながら構築してみた。

## 完成図

![スクリーンショット 2021-05-06 22.28.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247837/ef9b6f89-906d-b875-0580-7766517be59c.png)

図は、draw.ioで書きました。デフォルトでAWSのアイコンセットがあり、必要なコンポーネントが揃っているためです。

## 手順

だいたい下記の手順に従って、構築したので忘備録とし残します。

### 1. VPC作成

> Virtual Private Cloud (VPC) は、AWS アカウント専用の仮想ネットワークのこと。
> VPCは、AWSクラウドの他の仮想ネットワークから論理的に切り離されている。

FYI : [AWS Black Belt Online Seminar Amazon VPC Basic](https://www.slideshare.net/AmazonWebServicesJapan/20190313-aws-black-belt-online-seminar-amazon-vpc-basic)

### 2. subnet作成

> VPCの中で、CIDRブロックを分割したネットワーク群をsubnetと呼びます。
> 外のネットワークと直接繋がっている「public subnet」と、直接は外のネットワークに繋ぐことのできない「private subnet」の2種類があります。

### 3. InternetGateWay作成

> VPC内部とインターネットとの間の通信を可能にするためのものGatewayです。
> ので、構築したVPCにアタッチすることで利用可能になります。

### 4. RouteTable作成とsubnet関連付け

> サブネット内の通信がどの宛先のネットワークに対して、どこに転送されるべきかを設定するのが、RouteTableの役割になります。
> 「public subnet」、「private subnet」毎にRouteTableを紐づけます。
> これを紐づけることで、「public subnet」から出ていくときの通信経路、「private subnet」から出ていくときの通信経路を確保できます。

### 5. public-subnetと関連づけたRouteTableにInternetGateWayへのルート登録

> 例えば、「public subnet」であれば、外のインターネットと通信して欲しいので、
> 転送先に「InternetGateWay」を設定します。
> 「private subnet」からも外に通信してほしいケースがあるので、
> 「NatGateway」を「public subnet」に設置して「private subnet」からの転送先に「NatGateway」を指定します。
> 図でいう、「private subnet」 -> 「NatGateway」 -> 「InternetGateWay」への通信経路がこれで確保できます。

### 6. Route53設定

> 別AWSアカウントで取得しているドメインに対し、
> さらに別AWSアカウントで構築した環境にサブドメインとして利用できるようにしたかったので、下記の作業を実施しました。

> 譲渡先アカウントでホストゾーン作成、NSレコードとSOAレコードが自動作成される。
> 譲渡元アカウントで上記のNSレコードを登録する。というステップが必要になります。

### 7. Certificate ManagerによるSSL証明書発行

> 画面の手順に従って、証明書を発行したドメインを入力していきます。
> 最後にroute53へのレコード登録ボタンが出てくるので、押下してあげることで利用可能になります。

### 8. FargateSpot構築

> 割愛。ここの構築は別の人に構築いただきました。

### 9. AuroraForPostgres構築とRoute53でCNAME登録

> 画面に従って、設定していきます。
> 構築後にエンドポイントが表示されるので、Route53のCNAMEレコードで、分かりやすい名称を設定します。

### 10. NatGateway作成
> 「public subnet」にNATGatewayを作成します。
> ECS（Fargate）を設置する「private subnet」 のルーティング（0.0.0.0/0） を 「NATGateway」に設定します。

### 11. Application Load Balancer作成とRoute53でAレコード登録

> 後から設定するCloudFrontにて、
「インターネットアクセス」 -> 「CloudFront」 -> 「Application Load Balancer」となるのですが、
> 一旦 「ドメイン名」のAレコードに、「Application Load Balancer」を設定します。

### 12. ElatiCacheForRedis構築とRoute53でCNAME登録

> 画面に従って、設定していきます。
> 構築後にエンドポイントが表示されるので、Route53のCNAMEレコードで、分かりやすい名称を設定します。

### 13. セキュリティグループ設定

> 完成図でいう赤枠の箇所がセキュリティグループを設定した箇所になります。
> 必要な経路に必要なアクセスポートを設定します。

### 14. CloudWatch Alarm

> Alertは通知先にslackを設定したので、chatbotとSNSを組み合わせます。
> Cloudwatchで監視する項目は、下記のシンプルなリソース監視を設定します。diskはS3を使用する想定です。

> ALBのアラート作成（HTTPCode_Target_5XX_Count）
> redis   memory / cpu 
> Aurora  memory / cpu
> fargate memory / cpu

### 15. Session Manager

> 今回、Session Managerを用意することで、踏み台サーバの構築をなくしました。
> Session Manager経由でEC2にアクセスし、そこから必要に応じてコンポーネントを利用します。
> Session Managerでのコマンド実行履歴は、「CloudWatchLogs」に転送するように設定したので、
> 誰がいつどのような操作をしたかを確認することができます。
> 踏み台サーバも構築していないのでよりセキュアな環境になります。

FYI : [セッションマネージャーのハマりどころをパターンごとに整理してみる](https://dev.classmethod.jp/articles/session-manager-pattern/)

### 16. VPCエンドポイント

下記4つのVPCエンドポイントが必要になります。
参考にしたクラスメソッドの記事がよくまとまっていて助かりました。

> 1. com.amazonaws.region.ssm
> 2. com.amazonaws.region.ec2messages
> 3. com.amazonaws.region.ssmmessages
> 4. com.amazonaws.region.s3

FYI : [セッションマネージャーのハマりどころをパターンごとに整理してみる](https://dev.classmethod.jp/articles/session-manager-pattern/)

### 17. CloudFront

> CloudFront用証明書発行します。（仕様でバージニア北部リージョンで発行する必要があります）
> Behaviorで、ルーティング先を「Application Load Balancer」に設定します。

### 18-1. Route53

> 「ドメイン名」のAレコードに、「CloudFront」に設定します。
> これでドメインにアクセス時、「CloudFront」を経由する形になります。

### 18-2. 「Application Load Balancer」のルール変更

> 「CloudFront」からのアクセスのみ処理するように、HTTPヘッダーに 「CloudFront」から渡される値を設定します。

### 18-3. CloudFront キャッシュ用S3 バケット作成

> コンソールでS3バケットを作成します。外部からのアクセスは許可しない設定にしておきます。

### 18-4. CloudFront Origin Access Identity 設定

> 「CloudFront」からのアクセスのみ許可したいので、この設定を行います。
> 設定途中で指定したS3バケットにポリシーを反映するか確認する項目があるので、選択します。

### 19. WAF for CloudFront / WAF for Application Load Balancer

> 必要に応じて、ルールを設定します。
> 基本的にマネージドルールを採用し、できるだけセキュアな設定にします。

### 20. ClouFront for WAF ログ出力

> cloudFront用のfirehoseは仕様で「バージニア北部リージョン」で構築する必要があります。
> また、firehoseから出力するS3バケットもfirehoseと同じリージョンで構築する必要があるため、「バージニア北部リージョン」で構築します。

FYI : [CloudFrontのログをAWS WAF + FirehoseでS3に送信しようとしてハマった話](https://dev.classmethod.jp/articles/sendcflog-tos3/)

### 21. ALB for WAF ログ出力

> 「Cloufront for WAF」で設定した手順とほぼ同等になります。今度は「東京リージョン」で構築すれば良いです。

## 最後に

実際に手を動かしてみてハマってみないと「だからこの設定が必要なのか」「確かにこの設定は分かりづらいし、気づけない」
「どこがおかしいかわからない」といったことが実感できないなと改めて感じました。

と同時に、AWSのリファレンスやBlackBeltを読むだけでは直感的にイメージが湧きにくく、
やはりクラスメソッドの記事は頼りになるなと感謝の気持ちでいっぱいです。

今回ゼロから構築できたので、だいたいこれくらいの時間あればできそうだなという勘所と、
ベストプラクティスの知見も得られたので、自身の成長につながったかなと実感できました。

やはり、今までできなかったことができるようになるのは楽しいですね！