# CloudFrontとRoute 53を使ったAWSでのサブディレクトリ設定

{% hint style="info" %}
このガイドでは、AWS CloudFront と Lambda\@Edge を使用してサブディレクトリを設定する方法を説明します。これは AWS ユーザー向けの一つの方法です。AWS の構成が異なる場合（たとえば、NGINX を実行する EC2 インスタンスを備えたロードバランサーなど）、リバースプロキシの設定を別の方法で行う必要があるかもしれません。 [サポート](https://gitbook.com/docs/help-center/further-help/how-do-i-contact-support) 代替構成に関する案内が必要な場合は、お問い合わせください。
{% endhint %}

{% stepper %}
{% step %}

#### GitBook サイトの設定

GitBook 組織で、サイドバー内のドキュメントサイト名をクリックし、次に **サイトを管理** または、 **設定** タブを開きます。 **ドメインとリダイレクト** セクションを開き、「Subdirectory」の下で **サブディレクトリを設定**.

docs をホストしたい URL を入力します。次に、docs にアクセスするためのサブディレクトリを指定します。例: `example.com/docs`を入力し、 **設定**.

の下で **追加の設定**をクリックすると、プロキシ URL が表示されます。次の手順で Lambda 関数を設定する際にこれを使用します。クリップボードにコピーしてください。
{% endstep %}

{% step %}

#### Lambda\@Edge 関数を作成する

AWS コンソールにサインインして、 **Lambda**.

次のボタンをクリックします **関数を作成** ボタンをクリックしてください。

を選択します **一から作成**、次に：

* 関数に、次のようなわかりやすい名前を付けます `gitbook-subpath-proxy.`
* 選択してください **Node.js** をランタイムとして選択します（利用可能な最新バージョンを使用してください）。
* アーキテクチャやその他の設定はデフォルトのままにします。

クリック **関数を作成**.
{% endstep %}

{% step %}

#### Lambda 関数コードを更新する

Lambda 関数エディタで、デフォルトのコードを次の内容に置き換えます：

{% code lineNumbers="true" %}

```javascript
export const handler = async (event) => {
	const request = event.Records[0].cf.request;
	
	// サブディレクトリが /docs でない場合は更新してください
	const subdirectory = '/docs';
	
	// 以下をプロキシ URL で更新してください
	const target = new URL('<GitBook から取得したプロキシ URL>');

	// 書き換え: /docs* -> proxy.gitbook.site
	if (request.uri.startsWith(subdirectory)) {
		request.uri = target.pathname + request.uri.substring(subdirectory.length);

		// 末尾のスラッシュがあれば削除
		if (request.uri.endsWith('/')) {
			request.uri = request.uri.slice(0, -1);
		}

		request.origin = {
			custom: {
				domainName: target.host,
				port: 443,
				protocol: 'https',
				path: '',
				sslProtocols: ['TLSv1.2'],
				readTimeout: 30,
				keepaliveTimeout: 5,
				customHeaders: {},
			},
		};

		request.headers['host'] = [{ key: 'host', value: target.host }];
		request.headers['x-forwarded-host'] = [{ key: 'x-forwarded-host', value: target.host }];
	}
    
	return request;
};
```

{% endcode %}

{% hint style="warning" %}
必ず更新してください `target` 1 つ目の手順で GitBook から取得したプロキシ URL を、8 行目で設定してください。これは次のようになります `https://proxy.gitbook.site/sites/site_XXXX`
{% endhint %}

{% hint style="warning" %}
また、必ず更新してください `subdirectory` 使用しているサブディレクトリのパスが次と異なる場合は、5 行目を更新してください `/docs`.
{% endhint %}

クリック **デプロイ** をクリックして変更を保存します。
{% endstep %}

{% step %}

#### Lambda\@Edge 用に Lambda の権限を設定する

Lambda 関数を CloudFront で使用する前に、Lambda\@Edge がその実行ロールを引き受けられるように設定する必要があります。

1. Lambda 関数で、 **設定** タブ
2. クリック **権限** を左サイドバーでクリックします
3. の下で **実行ロール**、ロール名をクリックして IAM で開きます
4. 次のボタンをクリックします **信頼関係** タブ
5. クリック **信頼ポリシーを編集**
6. 信頼ポリシーを次の内容に置き換えます：

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "edgelambda.amazonaws.com",
                    "lambda.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

クリック **ポリシーを更新** して保存します。
{% endstep %}

{% step %}

#### Lambda 関数を公開する

Lambda\@Edge では、公開済みバージョンが必要です（単なる `$LATEST`).

1. Lambda 関数で、 **アクション** 右上のドロップダウン
2. 選択してください **新しいバージョンを公開**
3. 必要に応じて、「CloudFront 用の初期バージョン」のような説明を追加します
4. クリック **公開**
5. **重要：** ページ上部に表示される公開済みバージョンの ARN をコピーしてください（末尾にバージョン番号が含まれます。例： `arn:aws:lambda:us-east-1:123456789:function:gitbook-subpath-proxy:1`)

{% hint style="warning" %}
Lambda\@Edge 関数は、 **us-east-1** （バージニア北部）リージョンで作成する必要があります。別のリージョンで関数を作成した場合は、us-east-1 で作り直す必要があります。
{% endhint %}
{% endstep %}

{% step %}

#### CloudFront ディストリビューションを作成する

次へ移動し **CloudFront** を AWS コンソールで開き、 **ディストリビューションを作成**.

次の設定を行います。指定されていない設定はデフォルトのままにしてください。

**オリジンを指定**

| 設定           | 値                                |
| ------------ | -------------------------------- |
| **オリジンタイプ**  | その他                              |
| **カスタムオリジン** | メインのウェブサイトドメイン（例： `example.com`) |

**キャッシュ設定**

| 設定                | 値                         |
| ----------------- | ------------------------- |
| **キャッシュポリシー**     | CachingDisabled           |
| **オリジンリクエストポリシー** | AllViewerExceptHostHeader |

クリック **次に、** 希望するセキュリティ保護を選択し、次に **次へ** を再度クリックします。

クリック **ディストリビューションを作成**.

ディストリビューションがデプロイされるまで待ちます（ステータスが「In Progress」から「Enabled」に変わります）。これには数分かかる場合があります。
{% endstep %}

{% step %}

#### Lambda\@Edge を CloudFront に関連付ける

CloudFront ディストリビューションがデプロイされたら：

1. ディストリビューション ID をクリックして設定を開きます
2. 次の場所へ移動します **Behaviors** タブ
3. デフォルトのビヘイビアを選択し、 **編集**
4. までスクロールします **関数の関連付け**
5. の下で **オリジンリクエスト**、選択し **Lambda\@Edge**
6. の中で **Lambda 関数 ARN** フィールドに、公開済み Lambda 関数の ARN（手順 5 のもの）を貼り付けます
7. チェックを入れます **Include body** 必要に応じて関数がリクエストボディにアクセスできるようにするためです
8. クリック **変更を保存**
   {% endstep %}

{% step %}

#### ドメインと DNS レコードを設定する

1. CloudFront ディストリビューションのメインページで、 **一般** タブをクリックし、 **Alternate domain names**の下で、 **ドメインを追加**
2. サブディレクトリを設定するドメインを入力します。例： `example.com` をクリックします **次へ**
3. 既存の TLS 証明書を選択するか、必要であれば新しく作成して、次に **次へ** を再度クリックします
   {% endstep %}

{% step %}

#### CloudFront から Route 53 DNS レコードを設定する

DNS に Route 53 を使用している場合は、CloudFront ディストリビューションを指すように DNS レコードを作成または更新する必要があります。

1. CloudFront ディストリビューションのメインページにとどまったまま、 **一般** タブにいることを確認し、 **Alternate domain names,** の下に設定した URL の下で、 **Route domains to CloudFront.**
2. クリックします **ルーティングを自動的に設定** を選択して、ドメイン用の A および AAAA DNS レコードを作成します

{% hint style="info" %}
Route 53 を使用していない場合は、DNS プロバイダーの設定を更新して、ドメインが CloudFront ディストリビューションのドメイン名を指すようにする必要があります。これは CloudFront ディストリビューションの詳細にある「Distribution domain name」で確認できます。
{% endhint %}
{% endstep %}

{% step %}

#### 設定をテストする

すべての変更が反映されたら（10～15 分かかる場合があります）：

1. ブラウザを開き、サブディレクトリパス付きのドメインにアクセスします（例： `https://example.com/docs`)
2. GitBook のドキュメントサイトが表示されるはずです！

サイトがすぐに読み込まれない場合は、次を試してください：

* DNS の反映を待つために、さらに数分待つ
* ブラウザのキャッシュをクリアするか、シークレットウィンドウを試す
* 実行する `nslookup yourdomain.com` DNS が正しく名前解決されていることを確認するために、ターミナルで実行します
* CloudFront ディストリビューションのステータスが「In Progress」ではなく「Enabled」になっていることを確認する

{% hint style="success" %}
おめでとうございます！これで GitBook のドキュメントはカスタムサブディレクトリ経由でアクセス可能になりました。
{% endhint %}
{% endstep %}
{% endstepper %}

### トラブルシューティング

**Lambda 関数がトリガーされない：**

* Lambda 関数のバージョンを公開していることを確認してください（使用しているのが `$LATEST`)
* Lambda 関数が us-east-1 リージョンにあることを確認してください
* 信頼ポリシーに次が含まれていることを確認してください `edgelambda.amazonaws.com`

**DNS が名前解決されない：**

* DNS の変更が反映されるまで時間がかかることがあります（最大 48 時間、通常はもっと速いです）
* Route 53 レコードが正しい CloudFront ディストリビューションを指していることを確認してください
* 古い競合する DNS レコードを削除したことを確認してください

**SSL 証明書エラー：**

* AWS Certificate Manager の SSL 証明書にカスタムドメインが含まれていることを確認してください
* CloudFront 用の証明書は us-east-1 リージョンで作成する必要があります

**サブディレクトリが機能しない：**

* 次を確認してください `SUBDIRECTORY` Lambda 関数内の値が、GitBook で設定した内容と一致していること
* 次を確認してください `target` Lambda 関数内の が正しいこと
* リクエストがディストリビューションに到達しているかどうかを確認するために CloudFront ログを確認してください
