CloudfrontとS３で静的ホスティングしてみる[AWS]

皆さん、フロントエンドのホスティングはどのように行なっていますか？

HerokuなどのPaasにデプロイする、AWSでAmplifyを使うなど様々な手段があると思います。

今回はその中でもAWSのCloudforntとS3を使ってフロントエンドを静的ホスティングしてみようと思います。

# ホスティングの手段について

ホスティングには、`静的ホスティング` と　`動的ホスティング` の二種類存在します。

:::note
### ホスティングとは

サーバー等に保存したアプリケーションを世界に発信すること(つまり色々なデバイスで利用可能な状態にすること)をホスティングと言います。

webフロントエンドの話で言うと、ブラウザで表示されるサイトが表示される状態のことを指します。
:::

## 静的ホスティングとは
どの時間で見ても表示されるサイトの表示が変わらないホスティング方法を静的ホスティングといいます。

アプリケーション開発をやったことがない人からすると`静的`と言う単語が聞き慣れないと思います。

静的は言葉からもわかる通り変わらないものを指します。

例えばwebサイトを表示するにはHTML、CSS、JavaScriptが挙げられますが、それらのコードに記載されている内容が変更されることがない状態を指します。

有名な静的ホスティングの例で言うと`GithubPages`が挙げられます。

## 動的ホスティングとは
動的ホスティングとは、時間によって表示される内容が変わることを指します。

動的はその名前の通り変化するものであり、webサイトで言うとHTML等のデータが動的に変化し、サイトで表示される内容が一定でないホスティング方法です。


# S3にファイルをアップロード
まず、S3にファイルをアップロードしてみようと思います。

:::note
# S3とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/4de12b3a-7798-43fb-81c1-91036d4768c4.png)

S3(Simple Storage Service)とは、あるデータをオブジェクトという単位で保存することが可能なAWSのオブジェクトストレージサービスです。

大量のデータや大きなデータの保存、静的コンテンツの配信、バックアップのデータ保存等に使うことができます。
:::

まず、S3のページに移動してバケットを作成を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/306c20d4-82fc-4374-91cc-f1fb992acc6f.png)

:::note
### バケットとは
オブジェクトを入れるコンテナのことを言います。

この中に複数のオブジェクト(画像や動画)などを入れることができます。
:::

バケットを作成する際のオプションは大体デフォルトの状態で設定しています。
>バケット名は他のバケットと被らないように入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/1f315ad4-1683-4f41-965d-229d862e9fae.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/90767e78-f990-4ad3-804a-4b2886e5f133.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/e39636d9-6a80-4862-ae3f-6b66276fe330.png)

ここにビルドしたアプリケーションをアップロードします。

今回はNext.jsのアプリケーションをpnpmで作成していたので、以下のコマンドでビルドしました。
```zsh
pnpm build
```

すると、outディレクトリにビルドしたファイルが置かれるのでその中身をuploadします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/197d50fb-b030-4124-bbb6-6b5ac83ec3ee.png)

これで完了です。

# Cloudfrontを使ってみる

cloudfrontのリソースを作成してみます。

:::note
### Cloudfrontとは?

AWSのCDNサービスです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/f84c0e63-10c9-49e2-9196-106ed41e3586.png)

静的コンテンツを高速かつ安全に配信することが出来るのが特徴です。

エッジロケーションと呼ばれるコンテンツをキャッシュしたエッジサーバーが集められている箇所が世界各地に配置されており、エッジロケーションまでの道を最適化することで配信の最適化を行っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/ecd69099-8a74-4293-b606-28d3acb63779.png)

>https://aws.amazon.com/jp/builders-flash/202311/learn-cloudfront-with-trainer/

またデフォルトでHTTPSを使えるようになっているので安全に配信もできます
:::

ディストリビューションの作成を選択します。

:::note
### ディストリビューションとは
ドメイン毎に当てられるcloudfrontの設定単位のことを指します。
:::

下のような画面が出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/9ec941c4-982c-4dd6-ac99-05abeb0fd67e.png)


ここで注意なのはオリジンアクセスを`Origin access controll settings` にしてください。
そして`Create OAC`を選択して新しいOACを作成してください

:::note
### OACとは
`Origin Access Contorl`とは、指定されたcloudfrontのディストリビューションのみからS3にアクセスできるようにするセキュリティの仕組みです。
:::

以下はほとんど設定はデフォルトの状態から変更していないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/52319d5c-9f9b-4b1c-8dc8-43e122d37d97.png)

WAFは無効にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/b233cc50-7123-468f-b93d-7108b8b267c0.png)

:::note
### WAFとは
`Web アプリケーションファイアウォール`とは、AWSのセキュリティサービスの一つでファイアーウォールの役割をします。

SQLインジェクションやクロスサイトスクリプティング、DDosなどアプリケーションからそれらの脅威を防いでくれます。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/14b286b9-134c-482c-a961-e3b849c589af.png)

 作成すると下の画面になります。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/8267d23b-65d9-4e77-8154-a1e3e3a838b4.png)

その後にディストリビューション名にindex.htmlを追加して検索すると画面が表示されるのですが、現在はcloudfrontからs3にアクセスできないようになっています。
`https://d2kwpy4k28mwol.cloudfront.net/index.html`


アクセスできるようにするためにs3のバケットポリシーを変更します。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [s3のARN],
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": [cloudfrontのARN]
                }
            }
        }
    ]
}
```

s3のARNはバケットを検索するとコピーできるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/c6d72b47-fd64-4f80-85d7-35ecc6a14c58.png)


それで`https://d2kwpy4k28mwol.cloudfront.net/index.html`を検索すると以下のようにサイトが表示されるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/dcd657f6-bcb0-431d-a5f8-b4f69076cb10.png)

# 最後に

今回AWSでの静的ホスティングをcloudfrontとs3で行う方法を紹介しました。

cloudfrontとs3の構成を使うことで高速かつ安全に静的webサイトを配信することができます。

個人使用であれば、ある程度安価で運用できると思うのでぜひ参考にしてみてください。

# AWS関連の記事

https://qiita.com/maooz4426/items/fda7507d227d4d8551f2

https://qiita.com/maooz4426/items/43c05f14cae0d4753719