AWSでサブドメイン移譲とCloudFront配信を試したときのメモ

# 背景・目的
AWS環境では、異なるアカウント間でのリソース管理が必要になる場合があります。
例えば、マルチアカウント構成や、運用上の要件から、1つのアカウントから別のアカウントにサブドメインを移譲し、そのサブドメインを使ってコンテンツを配信するケースがあります。

今回は、Amazon Route 53を使用してアカウントAからアカウントBにサブドメインを移譲し、アカウントAのCloudFront（S3オリジン）を利用してコンテンツを配信する手順を試してみます。

# 実践
今回、サブドメインを別アカウントに移譲し、移譲先のアカウントから、そのサブドメインを使用して別アカウントにあるCloudFrontへアクセスする流れを検証します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/7bac1370-915b-59f7-18e5-5ef967547f8d.png)

## 1. サブドメイン移譲 (NSレコードの設定)
アカウントAのRoute 53で、移譲するサブドメイン（例：sub.xxx.com）のNSレコードを作成し、アカウントBのRoute 53のネームサーバーを指定します。
アカウントBのRoute 53で、サブドメイン用のホストゾーンを作成し、そのホストゾーンに割り当てられたネームサーバー情報をアカウントAのNSレコードに設定します。


### アカウントBの作業
1. アカウントBでAWSにサインインします
1. Route 53に移動します
1. 下記を入力し、ホストゾーンを作成します
    - ドメイン名：アカウントAのドメインのサブドメインを設定
    - タイプ：パブリックホストゾーン
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/61f6df6b-b167-e579-c567-bd63c739842b.png)

1. NSレコードをメモします

### アカウントAの作業
下記で作成したドメインとホストゾーンを使用します。

https://qiita.com/zumax/items/154243d4cb0eaa255032

1. 作成済みのホストゾーンをクリックします
1. 「レコードを作成」をクリックします
1. 「シンプルルーティング」を選択し、「次へ」をクリックします
1. 下記を入力し、「シンプルなレコードを定義」をクリックします
    - ①. サブドメイン名
    - ②. NSレコード
    - ③. 値/トラフィックのルーティング先に、アカウントBのNSレコードに指定されているName Server
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/36e5b8b4-2873-39db-50ab-38877780856f.png)

1. 「レコードを作成」をクリックします

### 動作確認
:::note warn
DNSの伝搬には時間がかかるので、必要に応じて、ネームサーバを指定してください。
:::

1. ターミナルで、サブドメインに対して、digを実行します。QUESTION SECTIONとANSWER SECTIONが返ってきます
    ```bash
    % dig xxx.yyy.com
    ```
1. 上記で返ってこない場合は、ネームサーバを指定します
    ```bash
    % dig xxx.yyy.com ns-nnnn.awsdns-nnnn.org
    ```

1. 必要に応じてhttps://dnschecker.org/ などで確認します
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/d34c7b71-233f-7cfc-0768-cc42e69f0fe6.png)



## 2. CloudFrontの設定 (アカウントA)
アカウントAでCloudFrontディストリビューションを作成し、オリジンにS3バケットを設定します。
CloudFrontのカスタムドメイン名として、sub.xxx.comを追加します（この時点ではまだHTTP通信が可能です）。

### S3バケットの作成
1. S3に移動します
1. 専用のバケットを作成します
1. 下記のコンテツをアップロードします
    ```html
    % cat index.html 
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Welcome to CloudFront</title>
        <style>
            body {
                font-family: Arial, sans-serif;
                background-color: #f0f0f0;
                color: #333;
                text-align: center;
                padding: 50px;
            }
            h1 {
                color: #0073e6;
            }
        </style>
    </head>
    <body>
        <h1>Welcome to CloudFront</h1>
        <p>This HTML file is served via AWS CloudFront!</p>
    </body>
    </html>
    
    % 
    ```

### CloudFrontの作成

1. CloudFrontに移動します
1. 「CloudFrontディストリビューションを作成」をクリックします



### S3バケットポリシーの更新
1. S3に移動します
1. アクセス許可タブをクリックします
1. バケットポリシーの編集をクリックします
1. 下記のバケットポリシーを貼り付けます
    ```json
    {
            "Version": "2008-10-17",
            "Id": "PolicyForCloudFrontPrivateContent",
            "Statement": [
                {
                    "Sid": "AllowCloudFrontServicePrincipal",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "cloudfront.amazonaws.com"
                    },
                    "Action": "s3:GetObject",
                    "Resource": "arn:aws:s3:::XXXXXXXXXX/*",
                    "Condition": {
                        "StringEquals": {
                          "AWS:SourceArn": "arn:aws:cloudfront::XXXXXXX:distribution/XXXXX"
                        }
                    }
                }
            ]
    }
    ```

### 動作確認
1. CloudFrontのディストリビューションドメイン名でアクセスしてみます。画面が表示されました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/5371f1d7-284d-2d18-f770-45961f10757b.png)

## 3. Route 53でAliasレコードを設定（アカウントB）
1. Route 53に移動します
1. ホストゾーンを選択します
1. 「レコードを作成」をクリックします
1. 下記を入力し、「レコードを作成」をクリックします
    - ①レコードタイプ：A
    - ②エイリアス：有効
    - ③ルーティング：CloudFrontディストリビューションへのエイリアス
    - ④ディストリビューション：アカウントAのCloudFrontディストリビューションドメイン名
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/85e6a72d-04d1-81ba-a93b-b2e86282d925.png)


## 4. SSL証明書の発行と適用

アカウントAでAWS Certificate Manager（ACM）を使用し、sub.xxx.com用のSSL証明書を発行します。
ACMで「証明書のリクエスト」を行い、sub.xxx.comを指定します。
ドメイン所有確認のためのDNS検証が必要になるので、アカウントBのRoute 53に必要なDNSレコードを追加します。

ACMで発行されたSSL証明書をCloudFrontディストリビューションに適用し、HTTPS通信を有効にします。

###  証明書の作成（アカウントA）

1. AWS Certificate Managerに移動します
1. 「証明書をリクエスト」をクリックします
1. 「パブリック証明書をリクエスト」を選択し、「次へ」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f4948ce7-d99d-eac4-37d0-6c797153bb71.png)

1. 下記を指定し、「リクエスト」をクリックします
    - 完全修飾ドメイン名：サブドメイン
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/ef058ad4-a7ac-803f-2cfb-1af4b9ccbdd0.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b6ba46f3-c6c4-50f4-91e3-cf72384855c1.png)

1. ステータスが「保留中の検証」になります
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/a95f3c1a-9164-b993-9d29-8d0e62614e1e.png)

1. ①CNAME名と、②CNAME値を保存します
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b897f1b2-f8bd-a21a-fa0f-d4e9411fcc94.png)


### CNAMEレコードを追加（アカウントB）
1. Route 53に移動しホストゾーンを選択します
1. 「レコードを作成」をクリックします
1. 下記を指定し、「レコードを作成」をクリックします
    - ①レコード名：上記のアカウントAのCNAME名
    - ②値：上記のアカウントAのCNAME値
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/582d5fb7-cf73-3227-4544-c8a349e4cd89.png)
1. 作成されました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/46bd135f-bbc2-f783-927b-cc88c394c798.png)


### ACMのステータスの確認（アカウントA）
:::note info
CNAMEレコードの追加から、発行済まで少し時間がかかります。
:::


1. ACMに移動します
1. 作成した証明書を選択します
1. 証明書のステータスが「発行済み」になっていることを確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/24769823-3de9-db76-fda4-8d7622c487cd.png)

### CloudFrontでCustom SSL Certificationを設定（アカウントA）
1. CloudFrontに移動します
1. 作成したディストリビューションを選択します
1. Custom SSL certificate - optionalに作成した、ACMの証明書を指定します
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/9e3d5753-7920-75dc-c042-161f2438c49f.png)


### CNAMEを設定（アカウントA）
1. CloudFrontに移動します
1. 作成したディストリビューションを選択します
1. ①「項目を追加」をクリックし、②「CNAMEs」に上記のサブドメインを指定し、「変更を保存」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/707cd660-b797-e91d-012f-a7648131a255.png)


## 5. 動作確認
ブラウザやcurlコマンドを使用して、https://sub.xxx.comにアクセスし、HTTPSでセキュアにコンテンツが配信されているか確認します。
HTTPSでアクセスでき、CloudFront経由でS3のコンテンツが配信されることを確認します。

1. サブドメインでアクセスします。表示されました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/d05bf687-8223-3704-8a20-28d7e8e1e027.png)

# 考察
今回は、サブドメインの移譲に加えて、動作確認のために別アカウントのCloudFrontにリクエストされるように設定しました。そのため、事前に証明書を発行したり、CNAMEの登録が必要だったりと、少し複雑な構成になっていしまいました。

# 参考
https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/MigratingSubdomain.html

https://dev.classmethod.jp/articles/route53-transfer-hostedzones/

https://qiita.com/zumax/items/154243d4cb0eaa255032

https://qiita.com/zumax/items/14582d1dff091fe2838c

https://qiita.com/zumax/items/a7bac3d3e382173fb9eb