Docusaurus を AWS Amplify Hosting と Amazon Cloudfront でホスティングしてみた

※この記事は[KDDI Engineer&Designer Advent Calendar 2022](https://qiita.com/advent-calendar/2022/engineer-designer)の9日目の記事です。
（間違えて事前公開をした記事は削除したので、見てくれた人すいません…）

社内の人だけが見れるドキュメント管理サイトを作る機運がありそうなので、ドキュメントサイトを簡単に作ることが出来る Docusaurus を AWS のAmplify Hosting と CloudFront でホスティングする事を試してみました。この記事では Docusaurus 自体の使い方については特に触れません。

### Docusaurus とは

Docusaurus は Meta(元Facebook)社がOSSで開発をしていて、ドキュメント管理サイトを簡単に作成出来るフレームワークになります。

https://docusaurus.io/

今回のアドベントカレンダーで何度か登場している[ChatGPT](https://chat.openai.com/chat) さんがいい感じの回答をしてくれたので、説明は任せます。

> Docusaurus は、GitHub 上で開発されたオープンソースのウェブサイト生成フレームワークです。Docusaurus は簡単かつ高速に静的なドキュメントウェブサイトを作成するためのツールで、特に文書化されたプロジェクトや API のドキュメントを作成する際に適しています。Docusaurus は React と Markdown を使用しており、高いカスタマイズ性を持っています。
> 
> Docusaurus は、npm パッケージとして提供されており、Node.js 環境で動作します。Docusaurus のセットアップは簡単で、プロジェクトごとにサイトを作成することができます。
>
> Docusaurus では、Markdown ファイルから静的な HTML ページを生成することができます。Docusaurus は、ドキュメントやブログ記事を管理するための便利なツールも提供しています。また、検索や言語の切り替え、Google Analytics の統合などの機能も備えています。
>
> Docusaurus を使用することで、プロジェクトの文書化をスムーズかつ効率的に行うことができます。また、React に基づいているため、高度なカスタマイズが可能です。是非、Docusaurus を試してみてください。

### Docusaurus の初期設定

npx を利用できる環境であれば簡単に利用することが出来ます。npx は npm のバージョン5.2.0以降に同梱されています。[Docusaurus の公式ドキュメント](https://docusaurus.io/docs/installation)に記載のコマンドを実行するだけで初期設定が出来ます。

`npx create-docusaurus@latest my-website classic` 

上記コマンドを実行すると `my-website` ディレクトリが作成されて、必要なファイルが格納されます。ディレクトリ構成は下記のような感じです。

```
% tree -L 1 my-website 
my-website
├── README.md
├── babel.config.js
├── blog
├── docs
├── docusaurus.config.js
├── node_modules
├── package-lock.json
├── package.json
├── sidebars.js
├── src
└── static
```

`my-website` ディレクトリで `npm start`コマンドを実行すると、Docusaurus の Web サイトが表示できます。ローカル環境での使い方はここまで。

![Screenshot 2022-12-03 at 23.23.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953304/6af16e8d-a3d6-f1ec-6968-e7835f9d258b.png)

### AWS Amplify Hosting でのホスティング

AWS Amplify Hosting を利用して、Docusaurus をホスティングします。静的サイトのホスティングから CI/CD などの機能も簡単に実現可能で便利ですね。

https://aws.amazon.com/jp/amplify/hosting/

細かい説明は再び ChatGPT に任せます。

> Amazon Web Services (AWS) Amplify Hostingは、Webアプリケーションやモバイルアプリケーションをホストするためのサービスです。Amplify Hostingは、Webサイトやモバイルアプリケーションのフロントエンドをホストするために設計されています。Amplify Hostingは、Webサイトやモバイルアプリケーションのフロントエンドをスケールして、高速で安定したパフォーマンスを提供することができます。また、Amplify Hostingは、AWS Amplifyフレームワークと統合されているため、AWS Amplifyを使用している場合は、簡単にWebサイトやモバイルアプリケーションのフロントエンドをホストすることができます。

AWS Amplify Hosting を利用するためには、GitHub などを利用する必要があります。`my-website` を GitHub のリポジトリに登録する手順は省力します。

Amplify Hosting のリソースを作成していきます。下記の2ステップを設定するだけとなります。

1. コードのリポジトリとの連携
1. ビルド設定

まずは、最初は GitHub との連携をします。

![Screenshot 2022-12-03 at 23.44.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953304/7b7ae525-3bed-2493-9957-3590be580574.png)

細々した権限設定すると AWS の Amplify hosting とGitHub のリポジトリが連携することができます。

![Screenshot 2022-12-03 at 23.53.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953304/667b5d9b-4ea9-06e8-e1b9-763142b78fd2.png)

次はビルド設定です。Docusaurus は `npm run build` コマンドを実行すると静的コンテンツが `build` ディレクトリになります。そのため、下記のような Amplify にて下記のビルド設定をすればよいです。

![Screenshot 2022-12-04 at 11.35.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953304/0996dd78-abea-019e-b95a-c09d3b27786f.png)


``` yaml: Build Setting
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm install
    build:
      commands: 
        - npm run build
  artifacts:
    baseDirectory: /build
    files:
      - '**/*'
```

ここまで設定すると、GitHub のコードを更新するだけで Amplify Hosting のコンテンツも自動で更新されるようになります。

![Screenshot 2022-12-04 at 11.40.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953304/84a1312f-fb7a-fb3f-7d52-0ce3c49f21cd.png)

Amplify hosting が独自のドメインを払い出してくれるので、そこにアクセスするとサイトが見れるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953304/daf12733-2503-8d10-0871-a6b375fa739d.png)

２ステップほどで誰もが接続する事が出来るサイトがインターネット上に出来上がりました。カスタムドメインの設定をすれば、独自ドメインを利用する事ができたり、ベーシック認証でパスワードを知る人のみ接続することが出来るような状態にすることもできます。

Amplify Hosting で十分じゃない？と思いたい所ですが、インターネット上の誰もがアクセスする事が出来るので、`社内の人だけが見れるドキュメント管理サイト` という要件は残念ながら満たせません。ベーシック認証もパスワードを伝える必要があるので…（2022年12月05日時点）

### Amazon CloudFrontを利用する

手間ではありますが、仕方なく Amazon Cloudfront を利用します。Cloudfront の設定の詳細を記載するのは大変なので、やる事を箇条書きにします。

- S3 バケットの作成する
- CloudFront Distribution を作成する
- S3 のバケットポリシーを設定する 
- Docusaurus のビルド後の資材(`/build` 以下のファイル)をS3 にアップロードする

CloudFront経由でDocusaurus のサイトの画面が表示されるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953304/8ca0bb7e-55f7-38bd-e48d-4b0f8d8e51b7.png)


ただし、コードの更新をするたびにビルドしてS3にアップロードをするといった手間が発生してしまいます。そのため、AWS のコード3兄弟を使ってコードが更新されるたびにアップロードしてくれるように設定しましょう。

- CodePipeline を作成する
    - Source：GitHub
    - Build:Codebuild
    - Deploy: Deploy Provider(S3)
- CodeBuild を作成する
    - BuildSpec を設定する

ようやく、コードを更新するたびにパイプラインが実行されて、S3 にアップロードまでしてくれるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953304/32940b7f-741e-bf91-45e0-2d8a871be930.png)

また、Amplify Hosting だと、Pull Request を作成する度に事前に確認用のプレビューサイトを払い出してくれる機能は便利ですよね。この機能をCloudFront で簡単に実現する方法は思いつきませんでした…。最近新機能として公開された CloudFornt の継続的デプロイをうまい事活用すれば、出来るようになるのかもしれないですが大変そうなので検討してないです。

- [Amazon CloudFront が継続的デプロイのサポートを開始](https://aws.amazon.com/jp/about-aws/whats-new/2022/11/amazon-cloudfront-continuous-deployment-support/)

CloudFront の場合はファイルを配置するためのS3や、CI/CDのためのCodepipeline など自前で設定する必要があります。また、パスやヘッダの書き換えなどを行う方法として、CloudFront Functions や Lambda@Edge を利用する事が出来ます。

今回の`社内の人だけが見れるドキュメント管理サイト` という点については、アクセス制御のために AWS WAF で社内アクセスのIPアドレスのみ許可をすることで要件を満たせるようにもなります。せっかくなので、AWS WAFまで設定したかったのですが、時間不足でしたのでコメント程度に。

### 各手法の設定までの大変さ

二つの方法を試して、Amplify Hosting は設定方法をまとめましたが、Amazon Cloudfront の方はやる事を列挙しただけでまとめてないので、残念ながら設定の大変さが分からないです。定量的に表せと言われそうなので、Terraform のコード化して比較してみることにしました。

[お試しで作ったTerraform のコード一覧](https://github.com/mayuki12/sandbox-docusaurus/tree/7f2ddaef8686f2d7f571145d43e583236cdc5246/terraform)

AWS Amplify Hosting : [48行](https://github.com/mayuki12/sandbox-docusaurus/commit/7e73ea8eb4728152f048bb6cad341ad696aa23bf)
CloudFront + S3 ：[102行](https://github.com/mayuki12/sandbox-docusaurus/commit/6ae8d12c9c328d611f12a9b9b38d237a32f05bd3)
Codepipeline  : [197行 (IAM Role を設定除くと) ](https://github.com/mayuki12/sandbox-docusaurus/commit/0743f77129a4fd2aa28a7ca18f1e3529d5b5ea2a)

雑な計算をすると、CloudFront で勝手にデプロイされるまで設定をすると、Amplify の5倍くらいのコード量があるという事で設定箇所も多く、様々なサービスを組み合わせる必要があります。AWSのサービスは疎結合なので、トラブルシュートにも時間もかかります。細かい作り込みを求めないのであれば、Amplify Hosting で十分な気はします。ただし、細かい要件を達成しようとすると、CloudFront が必要になってきますので、要件に合わせて適切なサービスが選択出来るのは AWS の便利なところですね。

個人的にはAmplify Hosting で AWS WAF が利用できるようになって欲しいので期待してます。
- [Web Application Firewall Integration](https://github.com/aws-amplify/amplify-hosting/issues/36)

（補足）
`terraform apply` 後にAWSコンソールから GitHub の認証が必要になります。
サンプルプログラムは GitHub の認証までは考慮してないので、Codepipeline の Source フェーズでエラーとなります。
![Screenshot 2022-12-07 at 21.23.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953304/d301be2b-76c8-d071-a817-c1ad60be0e8e.png)

Codepipeline については、Terraform の aws_codestarconnections_connection のリソースであり、Settings の Connections に設定があります。認証情報をアップデートしましょう。

![Screenshot 2022-12-07 at 21.19.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953304/2f9cf28f-92fb-94ba-0834-e95575e19234.png)