AWS上にステージング環境を構築する（備忘録）

# はじめに
## この記事について
社内で対応したステージング環境構築の備忘録です。（もちろん重要な部分は諸々ぼかしています）
自分用の備忘録かつ、同じような作業を一からやる初学者の方に作業イメージを持ってもらうために作成しています。
（細かい部分は環境によって変わるため、あくまで流れだけでも理解していただけると幸いです）
※実装に関わる部分やデプロイなどは含めていません。

## 対象者
自分と同じAWS初学者の方向け

# 今回のゴール
ざっくり下記画像のような構成で作りたい。
本来はS3を利用する画像のホスティングをServer内の静的なファイルホスティングに置き換える、
certbot（Let's Encrypt）を利用してSSL証明書を発行しhttpsで接続できるようにする。
などのステージング向けの個別処理も行う。
![構成ず.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303906/77849d12-0119-ef13-fd3b-4a92c4de5d13.png)

# 作成フロー
1. EC2基本設定
    1. EC2起動
    1. EC2セキュリティグループ設定
    1. sshでEC2にアクセスできるよう設定
    1. git, nvmの導入
1. Route53設定
1. nginxの設定
    1. nginxのインストール
    1. confファイル設定
1. certbotの設定
 
# EC2基本設定

## EC2起動
AWSのコンソールからEC2を起動します。
今回はあくまで確認用のため無料利用枠対象の環境で作成しました。
- OSイメージ
    - Amazon Linux 2023
- インスタンスタイプ
    - t2.micro
- キーペア
    - 既存設定（なければ作成してください）
- ネットワーク設定
    - セキュリティグループ
        - 既存のセキュリティグループ
    - パブリックIPの自動割り当て
        - 有効化

パブリックIPの自動割り当ては、ネットワーク設定を編集しないと現れないので注意してください。

## EC2セキュリティグループ設定
HTTPS,HTTP向けの設定はされている前提ですが、
SSH接続するにあたって現在利用中のipアドレスを調べましょう。
https://www.cman.jp/network/support/go_access.cgi

このipアドレスで接続できるよう設定がしてあればOKですが、ない場合は下記を参考に対応しましょう。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/working-with-security-groups.html

## sshでEC2にアクセスできるよう設定
ターミナルからアクセスできるようにしたいため、sshでの接続ができるよう設定します。

githubのssh接続ができていればあると思いますが、.sshフォルダをホームディレクトリ直下に作成します。
```
mkdir ~/.ssh
```

このフォルダ内にEC2の秘密鍵(キーペアで指定したもの)を`ファイル名.pem`としてコピーしましょう。
その後、`config`という名前のファイルを同じく`.ssh`フォルダ内に作成します。
ファイル内にアクセスするための情報を記述しましょう。
```config
Host {この設定の名前}
    HostName {ipアドレス}
    User {ユーザ名}
    Port {ポート番号(大体22番。特別に設定していればそれで)}
    IdentityFile ~/.ssh/ファイル名.pem
```

この設定をした上でターミナルで
```
ssh {この設定の名前}
```
と入力すると下記のような形でEC2(amazon linux）にアクセスできるはずです。

![スクリーンショット 2024-06-05 16.15.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303906/afffc7ae-dfd4-fa6e-b390-991e81f3e552.png)

ここからはこのターミナル上で作業していきます。

## git, nvmの導入

パッケージマネージャー（yum）を利用してgitを、その後gitを利用してnvmを導入します。

まずyumを最新にupdateしておきます。
```
sudo yum update
```

次にgitのインストールを行います。
-yをつけると全設定をyesで実行してくれるので楽です。
```
sudo yum -y install git
```

nvmをgit cloneして取ってきます。
```
git clone https://github.com/creationix/nvm.git ~/.nvm
```

nvmのパスを通します。
```
source ~/.nvm/nvm.sh
```

また、bash_profileに下記を追加することで常にnvmのパスを通して置けるようにします。
```.bash_profile
# nvm
if [[ -s ~/.nvm/nvm.sh ]] ; then
        source ~/.nvm/nvm.sh ;
fi
```

その後、`nvm ls-remote`して最新のltsを確認し、nvmにインストールして利用できるようにしましょう。
```
nvm install v{x.x.x}
nvm use v{x.x.x}
```

`nvm list`を叩いてdefaultにインストールしたバージョンのnodeが表示されていればOKです。

# Route53設定
今回はステージング環境の構築のため、すでにドメインは存在している前提で、
- サブドメイン作成
- サブドメインとEC2のipアドレスの結び付け

を行います。

対応自体は簡単で、Route53→該当のホストゾーン→レコードを作成で、
サブドメイン名を入力し、レコードタイプをAで設定しつつ、
値の部分にipv4のアドレスを入力してください。
![スクリーンショット 2024-06-05 16.38.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303906/8814fb6a-b510-1d60-4351-1e44b5d322fa.png)

作成を押して５分ほど待つとサブドメインが反映されます。
下記のようにdigコマンドを実行して`ANSWER SECTION`に指定のipアドレスが表示されればOKです。
```
dig {ステージング環境用のサブドメイン} IN A
```

# nginxの設定
リバースプロキシとしてnginxを利用したいため、導入を進めます。

## nginxのインストール
下記コマンドでnginxのインストールを行います。
こちらにも書いてあるようにamazon linux 2023かつyumでnginxを落とそうとするとうまくいかないのでdnfでインストールした方が楽です。
https://blog.interstellar.co.jp/2023/05/11/amazon-linux-2023-nginx-install/
```
sudo dnf install nginx
```

インストールが終わったらnginxを起動しましょう。
```
sudo systemctl start nginx
```

現状だとOS再起動時にnginxを再度手動で立ち上げる必要があるため自動起動の設定をしておきます。
```
sudo chkconfig nginx on
```

ここまで終わったらサブドメインにアクセスしてみます。
Welcome to nginxというnginxのindex.htmlが表示されればOKです。

## confファイル設定

次にconfファイルを設定します。
`/etc/nginx/conf.d/`まで移動し、
適当な名前で`xxx.conf`ファイルを作成します。
詳細は各々の環境次第ですが、下記のようなイメージでconfファイルを作成します。
```
server {
    listen       80;
    listen       [::]:80;
    server_name  xxx.com;
    root         /usr/share/nginx/html/利用したいファイルパス;

    location / {
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}
```

設定したら下記コマンドでnginxを再起動しましょう。
```
sudo service nginx restart
```

`usr/share/nginx`内でデプロイ時にこちらを編集等できるように権限追加しておきます。
```shell
cd /usr/share/nginx

# グループ作成
sudo chown nginx:nginx html

# 権限付与
sudo chmod -R g+rwx html

# グループの追加
sudo usermod -aG nginx {ユーザ名}
```

※実装のデプロイは割愛するため、各々この辺のタイミングで行なってください。

# certbotの設定
HTTPSで接続できるようにするためにcertbotを導入します。
## インストール
certbotをインストールするためにpythonの環境を構築します。
```shell
sudo dnf install -y python3 augeas-libs pip
# 仮想環境作成
sudo python3 -m venv /opt/certbot/

# インストール
sudo /opt/certbot/bin/pip install --upgrade pip
sudo /opt/certbot/bin/pip install certbot certbot-nginx

# コマンドで実行しやすいようにシンボリックリンク作成
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot
```

## 証明書作成
下記コマンドでドメインに対して証明書を発行します。
```
sudo certbot --nginx -d {サブドメインのアドレス}
```

# その他(デプロイ周りのしくじり)
本編では入れませんでしたが、デプロイ時に色々しくじっているのでこちらも同じミスをしないようにまとめておきます...

## サーバのURLが本番環境のままだった
URLが違うため、サーバにそもそもアクセスできずにいました。
後でステージング用のenvファイルに書かれているURLが本番と同じになっていることに気付き、事なきを得ましたが、
一歩間違えると本番環境のサーバを使っていることに気づかず、とんでもないミスにつながるかもしれないので...

## デプロイ=サーバが立ち上がると考えていた
デプロイまで行ったのにうまく動かず、１〜2時間ぐらい消費してしまったのですが、
原因はデプロイしたサーバの立ち上げを忘れていただけでした。
（あまりに初歩的すぎて先輩方にも気づかれず沼にはまっていました...）
Vercelに慣れすぎていたせいかデプロイ=自動でサーバ立ち上げという安直な考えでいたのが良くなかったですね...

## サーバディレクトリへのnode_moduleのインストールでパーミッションエラー
node_moduleフォルダを事前に作成しておき、所有者を自分自身にしておくと良いです。
```
sudo chown -R $USER:$GROUP {node_modulesのパス}
```