【前編】「じゃあこのRailsアプリ、AWSにデプロイしといて」「へ！？やったことないんだけど」って人のためのAWS環境構築

# AWS環境をイチから構築し、Railsアプリをデプロイすることがゴール

プロジェクト名はテキトーに`neon-cyber`とします。（GPTが提案してくれた）
要件
- フレームワークはお馴染みのRuby on Rails(7系)
  - WEBサーバー
  - Sidekiqのサーバー
- データベースはMySQLの8系

これをAWSで実現するとなる時には以下の構成となる

- EC2インスタンス（AMI用+踏み台サーバー）
  - ロードバランサー（CodeDeployでBlue/Greenデプロイをしたいから）
- EC2インスタンス（WEBサーバー）
- EC2インスタンス（Sidekiqのサーバー）
- RDSインスタンス
- Redisインスタンス

と、簡単に言ってもAWSで設定しなければいけないことは多岐に渡るので順番に解説していく。

- VPC
  - サブネット
  - ルートテーブル
  - セキュリティグループ
  - インターネットゲートウェイ
  - NATゲートウェイ
  - エンドポイント（EC2がS3にアクセスしたい場合）
- RDS
  - サブネットグループ
  - インスタンス
- Redis
  - サブネットグループ
  - インスタンス
- SystemManager
  - パラメーターストア
- IAM
- EC2
  - インスタンス作成
  - 起動テンプレート
  - AMI
  - ロードバランサー
  - ターゲットグループ
  - オートスケーリンググループ

## VPC（ヴァーチャル・プライベート・クラウド）
完成図は以下通りです。
![Thisbe VPCの設定まで.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/887dd556-f99f-d105-4788-0aed6350b28e.png)

順を追って説明していきます。

### VPCの作成
まずは仮想環境を作ります。

![スクリーンショット 2024-04-03 12.59.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/1c2ff2f1-cd13-1971-ee31-537c5949fbcf.png)
![スクリーンショット_2024-04-03_12_59_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/3adc1ed9-a9be-f786-7875-04cd528fab80.png)

名前は「neon-cyber-vpc」とし、IPv4 CIDRは`172.33.0.0/16`とします。
![スクリーンショット_2024-04-03_13_01_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/7c3e2ca3-30e1-bee7-97b0-c6ba7b6ef765.png)

### サブネット
インターネット環境からだれでもDBインスタンスにアクセスできたりしたら嫌なので基本的に必要なもののみインターネット環境からアクセスできるような構成をとります。

- EC2インスタンス
- RDSインスタンス
- Redisインスタンス
を今回利用するためそれぞれに対してサブネットを作成します

| サブネット名 |AZ（アベイラビリティゾーン）| 役割 |IPv4 CIDR|
|-----------|------------|------------|------------|
|neon-cyber-ec2-private-subnet-1a|ap-northeast-1a|EC2のプライベートサブネット。ロードバランサーを使用するためもう一つ1cのサブネットも用意してマルチAZ化している|`172.33.1.128/25`|
|neon-cyber-ec2-private-subnet-1c|ap-northeast-1c|EC2のプライベートサブネット。ロードバランサーを使用するためもう一つ1aのサブネットも用意してマルチAZ化している|`172.33.4.128/25`|
|neon-cyber-ec2-public-subnet-1a|ap-northeast-1a|EC2のパブリックサブネット。ロードバランサーを使用するためもう一つ1cのサブネットも用意してマルチAZ化している|`172.33.1.0/25`|
|neon-cyber-ec2-public-subnet-1c|ap-northeast-1c|EC2のパブリックサブネット。ロードバランサーを使用するためもう一つ1aのサブネットも用意してマルチAZ化している|`172.33.4.0/25`|
|neon-cyber-rds-private-subnet-1a|ap-northeast-1a|RDSのプライベートサブネット。RDSの要件として最低3つのAZが必要なため|`172.33.2.0/25`|
|neon-cyber-rds-private-subnet-1c|ap-northeast-1c|RDSのプライベートサブネット。RDSの要件として最低3つのAZが必要なため|`172.33.3.128/25`|
|neon-cyber-rds-private-subnet-1d|ap-northeast-1d|RDSのプライベートサブネット。RDSの要件として最低3つのAZが必要なため|`172.33.2.128/25`|
|neon-cyber-redis-private-subnet-1a|ap-northeast-1a|Redisのプライベートサブネット。ロードバランサーを使用するためもう一つ1cのサブネットも用意してマルチAZ化している|`172.33.3.0/25`|
|neon-cyber-redis-private-subnet-1c|ap-northeast-1c|Redisのプライベートサブネット。ロードバランサーを使用するためもう一つ1aのサブネットも用意してマルチAZ化している|`172.33.5.0/25`|

![スクリーンショット_2024-04-03_13_05_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/dd7d84cb-52d5-0d5e-ca1b-72cb581ca166.png)
![スクリーンショット_2024-04-03_13_08_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/6a1975bb-6f1b-4e3a-462d-6fe6bb92398e.png)
![スクリーンショット_2024-04-03_13_17_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/1610dc20-1693-7252-302a-1184e0b17269.png)

### IGW(インターネットゲートウェイ)
ブラウザやターミナルなどインターネット環境からVPC内にアクセスするにはVPCにIGWをアタッチする必要があります。
インターネット環境からサブネットに入るためにも必要ですし、サブネットからインターネット環境に出ていくためにもサブネットは必要になります。
![スクリーンショット_2024-04-03_16_53_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/a6aad57d-06c7-c8d0-3305-8baa41674090.png)
![スクリーンショット_2024-04-03_16_54_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/1bec600a-5d28-ebdb-909f-e684b3c7a6cf.png)

作成しただけではダメでVPCにアタッチする必要があります。
![スクリーンショット_2024-04-03_16_54_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/d117d2dd-67b5-f009-3d48-946f710839ed.png)

### NAT(ネットワークアドレストランスレーション)ゲートウェイ
NATゲートウェイはプライベートサブネット内のリソースがインターネットとやり取りするための中継役を果たし、セキュリティや通信の制御を強化します。

NATゲートウェイをパブリックサブネット内に作成します。プライベートサブネットがインターネット環境に出ていくにはパブリックサブネット内のNATゲートウェイを経由しインターネットとの通信が可能になります。
![https___qiita-image-store_s3_ap-northeast-1_amazonaws_com_0_427079_12b707de-4e63-7537-4c00-cca99a49f876.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/88d05979-622f-3ff4-42d8-959248c7f134.png)


ここで一度サブネットの種類について整理しておきます。

:::note info
プライベートサブネット
インターネット環境にでていくことはできる
:::

:::note info
パブリックサブネット
インターネット環境にでていくこともインターネット環境からもアクセスが可能
:::

### エンドポイント（EC2がS3にアクセスしたい場合）

![スクリーンショット_2024-04-08_11_18_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/be58420d-9186-a5db-e5ac-de371bc2c17e.png)
![スクリーンショット 2024-05-15 8.52.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/68237237-b05d-70a6-640c-2185b39bb92d.png)
サービス名はcom.amazonaws.ap-northeast-1.s3のタイプが「Gateway」
![スクリーンショット_2024-04-08_11_20_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/677ee825-73e5-8161-2c5c-d275fd594e52.png)

### ルートテーブル
VPCのルートテーブルは、VPC内のトラフィックを案内する案内人のようなものです。パケットがどの方向に送られるかを示す目的地（CIDRブロック）と、その目的地に到達する方法（ターゲット）が書かれています。

|名前|関連しているサブネット|
|---|------|
|neon-cyber-ec2-public-rt|`neon-cyber-ec2-public-subnet-1a` `neon-cyber-ec2-public-subnet-1c`|
|neon-cyber-ec2-private-rt|`neon-cyber-ec2-private-subnet-1a` `neon-cyber-ec2-private-subnet-1c`|
|neon-cyber-rds-rt|`neon-cyber-rds-private-subnet-1a` `neon-cyber-rds-private-subnet-1c` `neon-cyber-rds-private-subnet-1d`|
|neon-cyber-redis-rt|`neon-cyber-redis-private-subnet-1a` `neon-cyber-redis-private-subnet-1c`|

今回作成する4つのルートテーブルのうち、ルートの追加を行います

---

#### neon-cyber-ec2-public-rt
|送信先|ターゲット|
|-----|-----|
|`0.0.0.0/0`|neon-cyber-igw|

igwを割り当てたことによりパブリックサブネット化できました。

---

#### neon-cyber-ec2-private-rt
|送信先|ターゲット|
|-----|-----|
|`0.0.0.0/0`|neon-cyber-ngw|

NATゲートウェイを割り当てたことによりプライベートサブネットがインターネット環境にアクセスできるようになりました。

---

### neon-cyber-rds-rt
デフォルトのまま

---

### neon-cyber-redis-rt
デフォルトのまま

---
### セキュリティグループ
各インスタンスがどのようにネットワーク接続を行えるようにするかを定義します
以下作成するセキュリティグループの一覧です。
|名前|役割|
|-----|-----|
|neon-cyber-ec2-admin-sg|のちに作成する踏み台サーバー(EC2インスタンス)用|
|neon-cyber-private-sg-1a|プライベートサブネット内のインスタンス用(AZ:ap-northeast-1a)|
|neon-cyber-private-sg-1c|プライベートサブネット内のインスタンス用(AZ:ap-northeast-1c)|
|neon-cyber-alb-sg|ロードバランサー用|
|rds-sg|RDS用|
|redis-sg|Redis用|
|ec2-to-rds-sg|EC2インスタンスがRDSに接続する用|
|ec2-to-redis-sg|EC2インスタンスがRedisに接続する用|

どういったトラフィックを受け付けて、どういったトラフィックの送信を許可するかをそれぞれ定義します。

### neon-cyber-ec2-admin-sg
![スクリーンショット 2024-05-16 8.02.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/5bb94505-695c-ad75-279c-29cc169fc291.png)
![スクリーンショット 2024-05-16 8.02.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/bb128144-3be5-2d4d-9183-312472659907.png)
---

### neon-cyber-private-sg-1a
![スクリーンショット_2024-05-16_8_08_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/5fbe65ab-5099-fc6c-5190-d7812b7cc359.png)
![スクリーンショット 2024-05-16 8.08.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/4269a8c8-325f-5877-0a25-5192314c0c53.png)
---

### neon-cyber-private-sg-1c
![スクリーンショット_2024-05-16_8_16_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/4fd3a179-11ad-2d65-c67a-e9fec0e2312a.png)
![スクリーンショット 2024-05-16 8.16.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/1569f7dd-f421-99ad-e0dd-abc939cb8593.png)
---

### neon-cyber-alb-sg
今はHTTPしか許可していませんがのちにSSL証明書を当てたいので後で設定します。

![スクリーンショット 2024-05-16 8.20.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/b8ae2124-1758-e432-65ed-6c0461cda2ab.png)
![スクリーンショット 2024-05-16 8.20.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/92a085ed-011e-dc77-6ebd-6fe42796d1e1.png)
---

### ec2-to-rds-sg
![スクリーンショット 2024-05-16 8.34.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/947ae6cc-df88-4fee-bd88-e13438703f93.png)
rds-sgへのトラフィックの送信を許可します(次の工程で作るSGです)

![スクリーンショット 2024-05-16 8.34.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/36b18d02-7f4f-d3a1-a3d7-a81763edb9ab.png)
---

### rds-sg
thisbe-vpcのIPからのトラフィックと先ほど作った`ec2-to-rds-sg`のセキュリティグループからのトラフィックを許可します

![https___qiita-image-store_s3_ap-northeast-1_amazonaws_com_0_427079_6b42dd23-bd98-3fd2-e2eb-756754da260f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/2707d233-c51e-5dda-a917-d15b66d16e38.png)
![スクリーンショット 2024-05-16 8.26.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/96fd246f-75a9-c304-d43f-9e4a690b7c54.png)
---

### ec2-to-redis-sg
![スクリーンショット 2024-05-16 8.39.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/512a0b0f-8203-8bc9-6d8d-fa3372d4b3b0.png)
redis-sgへのトラフィックの送信を許可します（次の工程で作成するSG）

![スクリーンショット 2024-05-16 8.39.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/333e0a32-92ee-96ae-4782-5bf1051dfbd2.png)
---

### redis-sg
先ほど作成したec2-to-redis-sgからのトラフィックを許可します（カスタムTCPとSSH）

![スクリーンショット 2024-05-16 8.42.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/517e961b-bbea-651e-7427-2d161e70f62f.png)
![スクリーンショット 2024-05-16 8.42.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/e011b64d-847d-028d-180a-a7304c193d68.png)
---

ふう、、これでVPC周りの設定が完了です。（やっと１章、、、）
VPCの作成についてはこちらの動画を参考にさせていただきました。

https://www.youtube.com/watch?v=7J_crzU5KP8&list=PLS0SWeRoWAzEo2RffpYiRSSdHmQnTQl95&index=7

## RDS
### サブネットグループの作成
![スクリーンショット 2024-04-08 14.39.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/abff2d65-8768-1008-84a7-8d12e64ea950.png)
完成形は以下。
![スクリーンショット_2024-05-16_23_49_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/43b31ddf-a8c6-98a6-5ae0-f13053442b37.png)

### DBクラスタ・インスタンスの作成
エンジンのタイプはAurora (MySQL Compatible)
エンジンバージョンはMySQL Aurora 8系のデフォルトバージョン
パスワードはセルフマネージドにし、インスタンスタイプは一番安上がりなものにしました。（にしても高い...）

完成形は以下。
![https___qiita-image-store_s3_ap-northeast-1_amazonaws_com_0_427079_ea0727c4-a943-f997-5811-5d01102138ac.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/a5be5456-75e6-d049-31d7-004013221df2.png)
![スクリーンショット_2024-05-17_0_40_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/7c512f62-b20b-180b-92ea-efb10e0ccd29.png)

## Elastic Cache(Redis)

### サブネットグループの作成
![スクリーンショット_2024-05-17_0_52_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/2c11de0f-9928-2a15-cfd2-ab5efa2440e1.png)

### DBクラスタ・インスタンスの作成

完成系はこの通り。
![FireShot_Capture_028_-_ElastiCache_-_ap-northeast-1_-_ap-northeast-1_console_aws_amazon_com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/ea0727c4-a943-f997-5811-5d01102138ac.png)

## IAM
### ユーザーの作成
「neon-cyber-ec2」というEC2インスタンス用のユーザーを作成します
#### アクセスキーの作成
アクセスキーとシークレットアクセスキーを生成しておく。(のちに環境変数にセットします)

### ポリシーの作成
「neon-cyber-ec2-policy」というポリシーを作成します。
設定するポリシーは以下です。
![FireShot_Capture_029_-_ポリシーの編集_-_IAM_-_Global_-_us-east-1_console_aws_amazon_com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/e817c853-96dc-508c-5dd1-ad1e6e195954.png)

### ロールの作成
![スクリーンショット 2024-04-10 11.01.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/eb4da425-205c-1ae1-5cb6-9a0083c45b6f.png)
![スクリーンショット_2024-04-10_11_01_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/a8d4cd48-c077-65e4-4e3a-25bb897cc4b5.png)

## System Manager
### パラメータストアの追加
アプリで利用する環境変数をここにセットしておきます。
- AWS_ACCESS_KEY_ID(neon-cyber-ec2のアクセスキー)
- AWS_SECRET_KEY(neon-cyber-ec2のシークレットアクセスキー)
- REDIS_URL(redis://（ElastiCacheのプライマリエンドポイント）:(ポート番号))
- DATABASE_HOST(RDS Auroraのクラスタ（ライター）エンドポイント)
- DATABASE_USER(RDS AuroraのDBユーザー名)
- DATABASE_PASSWORD(RDS AuroraのDBパスワード)

## EC2
つづいて一番大事なEC2の作成をしていきます。
先述したとおり、以下三つのインスタンスを作成します
- neon-cyber-base(踏み台サーバーとAMIイメージの役割)
- neon-cyber-web(webサーバーとしてのインスタンス)
- neon-cyber-worker(workerサーバーとしてのインスタンス)

完成図は以下です。
![Thisbe インスタンスの設定まで.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/7c5ff05e-d60d-6fcb-0359-3c11f69bb659.png)

### インスタンス作成
#### neon-cyber-baseの作成
![スクリーンショット_2024-04-03_17_07_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/cda5a6eb-91d9-9ed4-0f48-6d4671c222f1.png)
![https___qiita-image-store_s3_ap-northeast-1_amazonaws_com_0_427079_e5acafb6-1848-03a4-e861-e780dc4b31c0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/441f23da-63ef-0949-1e10-a6fb06735a55.png)

私はubuntuを選択しました。(前に使ったことがあったので)

![https___qiita-image-store_s3_ap-northeast-1_amazonaws_com_0_427079_a233ed06-2e89-b158-3e09-59957c3a0b05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/7d9adafb-3ec4-9c33-493c-a838f47f432d.png)

この踏み台サーバーは踏み台の役割と　AMIの役割しか持っていない(railsサーバーなどを起動しない)ためインスタンスタイプは最低限でいいと思います。
![スクリーンショット_2024-04-03_17_08_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/e091c476-9ed3-b6d4-7f05-0aad957a9fcc.png)
このサーバーはパブリックサブネット上に配置し、インターネット環境から入れるようにするため
パブリックIPアドレスの割り当ては有効化します。(web,workerサーバーを作成するときは無効化)
![https___qiita-image-store_s3_ap-northeast-1_amazonaws_com_0_427079_2ccfc3f6-ac80-276e-0e39-4e5c839d8a2b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/574c3f79-34c8-dcf7-00cd-565af84ecda8.png)

新しいキーペアも作成しましょう。
「neon-cyber-web-ec2-key」にしました。

踏み台サーバーにpemファイルを配置

`$ scp -i ~/.ssh/neon-cyber-prod-web-ec2-key.pem ~/.ssh/neon-cyber-prod-web-ec2-key.pem ubuntu@52.195.207.191:~/`
- @の後ろはパブリックサブネット上にあるEC2インスタンスのパブリックIPアドレス

ssh接続

`$ ssh -i "~/.ssh/neon-cyber-prod-web-ec2-key.pem" ubuntu@52.195.207.191`
- ユーザーは`root`ではなく`ubuntu`

基本rootで作業するため

`$ sudo su -`

設定ファイルの修正

`$ sudo vi /etc/ssh/sshd_config`

```/etc/ssh/sshd_config
ClientAliveInterval 60
ClientAliveCountMax 60
```

`$ sudo vi ~/.ssh/config`
```~/.ssh/config
TCPKeepAlive yes
ServerAliveInterval 60
ServerAliveCountMax 120
```

aptコマンドのアップデート

`$ sudo apt update`

rbenvインストール

`$ git clone https://github.com/rbenv/rbenv.git /opt/rbenv`

rbenvがあるか確認

`$ ls /opt/`

パスを通す
```
$ echo 'export RBENV_ROOT="/opt/rbenv"' >> /etc/profile
$ echo 'export PATH="${RBENV_ROOT}/bin:${PATH}"' >> /etc/profile
$ echo 'eval "$(rbenv init -)"' >> /etc/profile

$ source /etc/profile
```

通っているか確認
```
$ echo $RBENV_ROOT
$ echo $PATH
```

ruby-buildをインストール

`$ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build`

入っているか確認

`$ ls $(rbenv root)/plugins/`

必要なパッケージをインストール
- rbenvのインストール
- mysqlクライアント
- redisクライアント
- awsのCLI
- jsonを扱うパッケージ
- CodeDeployに必要なパッケージ
などが含まれている

`$ apt install make zlib1g-dev gcc g++ libmysqlclient-dev libreadline-dev libffi-dev libyaml-dev mysql-client-core-8.0 awscli jq ruby-full wget redis-tools -y`

必要なバージョンのrubyをインストール
```
$ rbenv install 3.2.3
# => Installed ruby-3.2.3 to /opt/rbenv/versions/3.2.3
```

```
$ rbenv global 3.2.3
```

インストールできているか確認
```
$ ruby -v

$ which ruby
# => /opt/rbenv/shims/ruby
```
bundler インストール

`$ gem install bundler`

```
$ bundler -v
# => Bundler version 2.5.7

$ which bundler
# => /opt/rbenv/shims/bundler
```

プロジェクトディレクトリの作成とシンボリックリンクの設定
```
$ mkdir -p /var/www/rails/neon-cyber
$ ln -s /var/www/rails/neon-cyber neon-cyber
```

gitからリポジトリをクローンしてみる（AWSでCodeDeployの設定ができていないため）
```
$ ssh-keygen

Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX root@ip-172-33-1-117
The key's randomart image is:
+---[RSA 3072]----+
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
+----[SHA256]-----+

$ cat ~/.ssh/id_rsa.pub
ssh-rsa XXXXXX...
```
出力された内容を元にgithubでSSHキーを登録

`$ git clone git@github.com:username/NeonCyber.git .`

```
$ cd backend
$ bundle install
```
インストールできているか確認
```
$ rails -v
# => Rails 7.1.3.2
```
```
$ which rails
# => /opt/rbenv/shims/rails
```
aws cliの設定
```
$ aws configure

AWS Access Key ID [None]: neon-cyber-ec2ユーザーのAccessKeyId
AWS Secret Access Key [None]: neon-cyber-ec2ユーザーのSecretAccessKey
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

OS起動時にrailsサーバーが起動するように設定

```shell:get_parameters.sh
#!/bin/bash

# ssmからパラメータを取得し.envに書き出す
sudo -i
echo 'get_parameters.sh////////////////////////////////////////////////////////////////////////'
# ssm parameter-store settings
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") \
&& INSTANCE_ID=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") \
&& ZONE=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/availability-zone)
REGION=$(echo $ZONE | sed 's/.$//')
FILENAME="/var/www/rails/neon-cyber/backend/.env"
NAME=$(aws --region ${REGION} ec2 describe-instances --instance-ids "${INSTANCE_ID}" --query 'Reservations[0].Instances[0].Tags[?Key==`Name`]|[0].Value')
NAME=$(echo ${NAME} | awk '{print substr($0, 2, length($0)-2)}')

echo "INSTANCE_ID: $INSTANCE_ID"
echo "ZONE: $ZONE"
echo "REGION: $REGION"
echo "FILENAME: $FILENAME"
echo "NAME: $NAME"

if [ "${NAME}" = "neon-cyber-web" ] || [ "${NAME}" = "neon-cyber-worker" ]; then
  SSM_PARAMS=$(aws --region ${REGION} ssm get-parameters-by-path --path "/neon-cyber-production"  --with-decryption)
  for params in $(echo $SSM_PARAMS | jq -r --raw-output '.Parameters[] | .Name + "='\''" + .Value + "'\''"'); do

      echo ${params#"/neon-cyber-production/"}
  done > ${FILENAME}
elif [ "${NAME}" = "neon-cyber-web-test" ] || [ "${NAME}" = "neon-cyber-worker-test" ]; then
  SSM_PARAMS=$(aws --region ${REGION} ssm get-parameters-by-path --path "/neon-cyber-test"  --with-decryption)
  for params in $(echo $SSM_PARAMS | jq -r --raw-output '.Parameters[] | .Name + "='\''" + .Value + "'\''"'); do

      echo ${params#"/neon-cyber-test/"}
  done > ${FILENAME}
fi
```

```shell:start_application.sh
#!/bin/bash

chmod 755 /var/www/rails/neon-cyber/deployment_scripts/get_parameters.sh

# .envファイルを再読み込み
su -l -c '/var/www/rails/neon-cyber/deployment_scripts/get_parameters.sh'

echo 'start_application.sh////////////////////////////////////////////////////////////////////////'
export INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
NAME=$(aws ec2 describe-instances --instance-ids "${INSTANCE_ID}" --query 'Reservations[0].Instances[0].Tags[?Key==`Name`]|[0].Value')
NAME=$(echo ${NAME} | awk '{print substr($0, 2, length($0)-2)}')

if [ "${NAME}" = "neon-cyber-web" ]; then
  echo "railsサーバーを起動します"
  su -l -c 'cd /var/www/rails/neon-cyber/backend && echo "PROCESS_TYPE=\"web\"" >> .env && bundle exec rails s -e production -b 0.0.0.0 -p 80 -d'
elif [ "${NAME}" = "neon-cyber-web-test" ]; then
  echo "railsサーバーを起動します"
  su -l -c 'cd /var/www/rails/neon-cyber/backend && echo "PROCESS_TYPE=\"web\"" >> .env && bundle exec rails s -e development -b 0.0.0.0 -p 80 -d'
elif [ "${NAME}" = "neon-cyber-worker" ]; then
  echo "sidekiqを起動します"
  su -l -c 'cd /var/www/rails/neon-cyber/backend && echo "PROCESS_TYPE=\"worker\"" >> .env && bundle exec sidekiq -C config/sidekiq.yml -e production'
elif [ "${NAME}" = "neon-cyber-worker-test" ]; then
  echo "sidekiqを起動します"
  su -l -c 'cd /var/www/rails/neon-cyber/backend && echo "PROCESS_TYPE=\"worker\"" >> .env && bundle exec sidekiq -C config/sidekiq.yml -e development'
elif [ "${NAME}" = "neon-cyber-base" ]; then
  echo "Baseインスタンスでデプロイが実行されました。アプリケーションの起動は手動で行ってください。"
else
  echo "ec2インスタンスに適切なNameタグが付与されていないため、アプリケーションの起動に失敗しました。" 1>&2
fi

```



```
$ vi /etc/systemd/system/rails.service

[Unit]
Description=RailsApp
After=network.target

[Service]
Type=simple
WorkingDirectory=/var/www/rails/neon-cyber/deployment_scripts
ExecStart=/var/www/rails/neon-cyber/deployment_scripts/start_application.sh
Restart=always
User=root
Group=root
TimeoutStartSec=300

[Install]
WantedBy=default.target
```
デーモンの再読込・登録・起動・ステータスの確認
```
$ systemctl daemon-reload
$ systemctl enable rails.service
$ systemctl start rails.service
$ systemctl status rails.service
```

MySQLの接続確認

`$ mysql --version`

`$ mysql -h neon-cyber-production.cluster-ro-chueaqy2c9v6.ap-northeast-1.rds.amazonaws.com -P 3306 -u admin -p`
`show databases;`

Redisの接続確認

`$ redis-cli -h neon-cyber-production-001.miwzhw.0001.apne1.cache.amazonaws.com` (redisインスタンスのエンドポイント名から末尾のポートの記述を除いたもの)

`> ping`

`PONG` と返ってくればOK

バックグラウンドで起動しているrailsサーバーを停止したい時
PIDを拾う
```
$ ps aux | grep puma
root        2230  0.0 28.2 757544 129096 ?       Ssl  01:23   0:00 puma 6.4.2 (tcp://0.0.0.0:80) [backend]
```
プロセスをkillする
```
$ kill -9 2230
```

### ターゲットグループ
エンドユーザーはロードバランサー経由でEC2のwebサーバーにアクセスするものとします。そのための準備を行います。
![スクリーンショット_2024-05-17_3_01_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/f3c08b25-9df8-bf2c-b99f-d562669cdf7d.png)

### ロードバランサー
![スクリーンショット_2024-05-17_3_13_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/23267ca4-413c-9ce2-39e3-880297800518.png)


### 起動テンプレート
EC2のオートスケーリングを利用してインスタンスが自動で生成されるようにする場合、起動テンプレートという機能を使います。
#### イメージの作成
起動テンプレートを使うには元となるマシンイメージが必要になります。以下の手順でイメージを作成します。
![スクリーンショット_2024-04-09_15_55_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/6c8e23d9-5987-504f-fa9b-9a2b21b48ff0.png)
![スクリーンショット_2024-04-09_15_56_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/2b96ad2d-a00e-0aa3-9efe-ccc737f96e19.png)
#### 起動テンプレートの作成
![スクリーンショット_2024-04-09_16_03_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/ea49e0d9-0ee4-d69f-a727-bc048d821ad1.png)
![スクリーンショット_2024-04-09_16_03_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/9fc9e6b9-d1f3-855f-d147-f8847bb0ddcf.png)
![スクリーンショット_2024-04-09_16_04_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/ad0679fc-5a4d-5854-258b-b7d67b12a0fb.png)
![スクリーンショット_2024-04-09_16_12_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/4c269759-a44f-7917-50bb-3134db4b1c2d.png)

### オートスケーリンググループの作成
![スクリーンショット_2024-05-17_15_19_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/94781cbe-85f9-25ff-48f1-90ff36aae2b8.png)
Auto Scaing グループ名に「neon-cyber-web-auto-scaling-group」を入力
起動テンプレートから「neon-cyber-template」を選択
![スクリーンショット_2024-05-17_15_20_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/3a7da0d7-5549-ea78-9904-a411199ace72.png)
サブネットはneon-cyber-private-subnet-1a, neon-cyber--private-subnet-1c
![スクリーンショット_2024-05-17_15_21_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/9f81cf8a-5707-3601-2471-2cc3dbbc5bf3.png)

「起動テンプレートを上書きする」ボタンをクリック
![スクリーンショット_2024-05-17_15_20_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/13572c25-c408-f0b6-6098-536a4d80fea0.png)
「手動でインスタンスタイプを追加する」にチェックを入れ任意のインスタンスタイプを設定
![スクリーンショット_2024-05-17_15_20_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/6ac95cc2-3d15-6bee-c788-3b4f61119bf0.png)

「既存のロードバランサーにアタッチする」にチェック
既存のロードバランサーターゲットグループで「neon-cyber-target-group」を選択
![スクリーンショット_2024-05-17_15_22_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/be9aaa0b-669a-72e6-ce19-3080b7e471b1.png)
ヘルスチェックのタイプの「ELB」にチェックを入れる
ヘルスチェックの猶予期間を「30」を入力
![スクリーンショット_2024-05-17_15_22_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/8c362251-47e7-da99-675d-fdb41a452c11.png)

Cloud Watch内でグループメトリクスの収集を有効化するにチェックし「次へ」ボタンをクリック
何も入力せず「次へ」ボタンをクリック
何も入力せず「次へ」ボタンをクリック
「タグを追加する」ボタンをクリックし以下の組み合わせを登録したあと「次へ」ボタンをクリック
キー：Name、値：neon-cyber-web、新しいインスタンスをタグ付けするにチェック
「Auto Scalingグループを作成する」ボタンをクリック

![https___qiita-image-store_s3_ap-northeast-1_amazonaws_com_0_427079_7fadfbf4-6620-647c-299b-3af0785edb65.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427079/869a7bf3-210a-cd3c-bc25-ad8231a40f5e.png)

できがったAuto Scaling グループを一覧から選択し、高度な設定の「編集」ボタンをクリック
デフォルトのクールダウンに「30」を設定し「更新」ボタンをクリック

AutoScalingグループ（Worker用）の作成
(同上)
「ロードバランサーがありません」にチェック
(同上)

新しいインスタンスをタグ付けするにしないと意図した名前でインスタンスが再生成されなくなるため注意。）起動スクリプトはそのインスタンス名でwebサーバーかwokerサーバーか判別しているため）

これで完成です。
ロードバランサーのDNSにアクセスすることでwebサーバーにアクセスできるようになっていると思います！

つづきはこちら

https://qiita.com/a16111k/items/27dabc104275936d44e7