【AWS】EC2で複数のサブドメインをVirtualHost化

1つのEC2に立てたWebサーバーで、役割や種類の違うサイトをサブドメインとして公開したいときがある。そんな時、EC2のLinuxサーバーでどのように設定すればよいのか、紹介する。今回は、Apacheを使用する。

## 事前準備
- Route53でドメイン・サブドメインを取得する
- EC2にSSHでログインして、Apacheを立ち上げて、/var/www/htmlにテストサイトが表示される

## 特定のフォルダにサブドメインを割り当てる

```
$ cd /var/www/html/
$ sudo mkdir sub1.example.com
$ cd sub1.example.com
$ sudo vi index.html
$ cd ../
$ sudo mkdir sub2.example.com
$ cd sub2.example.com
$ sudo vi index.html
```
何か書き込む。一応vi使い方。
i : 書き込みモード
Esp : インラインモード
u : 戻る
Esp後に
:wq : 保存&終了
```
$ cd /etc/httpd/conf
$ sudo vi httpd.conf
```
下記のコードを最後に書き足す
```
<VirtualHost *:80>
    ServerName sub1.example.com
    DocumentRoot /var/www/html/sub1.example.com
    ErrorLog /var/log/httpd/sub1.example.com-error.log
    CustomLog /var/log/httpd/sub1.example.com-access.log combined
</VirtualHost>

<VirtualHost *:80>
    ServerName sub2.example.com
    DocumentRoot /var/www/html/sub2.example.com
    ErrorLog /var/log/httpd/sub2.example.com-error.log
    CustomLog /var/log/httpd/sub2.example.com-access.log combined
</VirtualHost>
```
でApache再起動
```
sudo systemctl restart httpd
```

## 各サブドメインにSSL認証を割り当てる

上記でhttpではブラウザで開くことができる。
でも、このままではhttpsでは開けないので、下記記事を参照して、SSL認証書を取得する

https://qiita.com/grapefruit1030/items/f864b669d54ec8097d04

```
$ sudo systemctl stop httpd
$ sudo certbot certonly --standalone -d sub1.example.com
```

```
あることを確認
$ sudo ls /etc/letsencrypt/live/example.com/
キーをフォルダ毎コピー
$ sudo cp -LR /etc/letsencrypt/live/example.com /etc/pki/tls/certs/
```

```
cd /etc/httpd/conf.d
sudo vi sub.example.com.conf
```
で以下のコードを書きこむ
```
<VirtualHost *:443>
    ServerName sub1.example.com
    DocumentRoot /var/www/html/sub1.example.com
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/sub1.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/sub1.example.com/privkey.pem
</VirtualHost>
```
でApache再起動
```
sudo systemctl restart httpd
```

これでサブドメインのサイトもSSL認証付きでブラウザでアクセスできる。

## 特定のアドレスをローカルAPIへルーティング
Apacheで立てたサーバー内にPython Fast APIのWeb APIを実装する。

Apache設定ファイルにhttp://******/apiをlocalhostで公開したWeb APIへルーティングする。
```/etc/httpd/conf/httpd.conf
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html

    # 通常のWebサイトの設定

    # FastAPIアプリケーションへのプロキシ設定
    ProxyPass /api http://localhost:8000/api
    ProxyPassReverse /api http://localhost:8000/api
</VirtualHost>
```

任意のフォルダでPythonコードを置いて、Fast APIを起動する。

```Python:main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}
```

```
pip3 install fastapi uvicorn
pip3 install pydantic
# Fast APIサーバー起動
uvicorn main:app --host localhost --port 8000
# バックグラウンドで、同時接続数を10で起動
nohup uvicorn main:app --host localhost --port 8000  --workers 10  --timeout-keep-alive 30 &

ps aux | grep uvicorn
kill PID
か
ps aux | grep uvicorn | grep main:app | awk '{print $2}' | xargs kill
ps aux | grep multiprocessing | grep python | awk '{print $2}' | xargs kill -9
```

これで、http://******/apiにWeb APIが立てれた。

## EC2の環境変数の設定
EC2の環境変数は.bashrcでもいいが、環境変数の設定用に```/etc/environment```が用意されている。
```
export AWSACCESSKEYID='AKI*************'
export AWSSECRETACCESSKEY='***************************************'
export AWSROLEARN='arn:aws:iam::***************************************'
```

## EC2へ他AWSサービスのアクセス権限を付与する

1. EC2メイン画面でアクション->セキュリティ->IAMロールの変更を押す
1. 他AWSサービスのアクセス権限を持ったIAMロールを選択する
1. IAM ロールの更新を押す