[備忘録] お名前.com で購入したドメインで、CloudFront + S3 で作成した静的コンテンツを表示

お名前.com で購入したドメインで、CloudFront + S3 で作成した静的コンテンツを表示してみた。  
ただし、CloudFront と S3 は[[備忘録] AWS CDK プロジェクトの作成](https://qiita.com/m-chan/items/011a93e40f26230df135)で作成した cdk プロジェクトを利用した。

# はじめに
### Route53 とは

> Amazon Route 53 は、可用性と拡張性に優れたドメインネームシステム (DNS) ウェブサービスです。Route 53 を使用すると、ドメイン登録、DNS ルーティング、ヘルスチェックの 3 つの主要な機能を任意の組み合わせで実行できます。

ドメイン管理はRoute53 以外の別のサービスでも行うことはできるが、 Route53 は 提供元である AWS が管理しており、負荷が高くなったら自動的にサーバ台数増やしたりサーバ強化したりなどのスケーリングを行なってくれるため、高可用性と高拡張性を担保できる。

### CloudFront とは

 > Amazon CloudFront は、ユーザーへの静的および動的なウェブコンテンツ (.html、.css、.js、イメージファイルなど) の配信を高速化するウェブサービスです。

ユーザーに一番近いエッジロケーションから配信することで、さまざまなWebコンテンツをスムーズに配信できるコンテンツデリバリネットワーク（CDN）である。他にも、エッジサーバーでコンテンツをキャッシュすることによって、オリジンの負荷を減らすことがができる。

### S3 とは

> Amazon Simple Storage Service (Amazon S3) は、業界をリードするスケーラビリティ、データ可用性、セキュリティ、およびパフォーマンスを提供するオブジェクトストレージサービスです。

つまり、Amazonが提供するストレージサービスである。バケットの内容を静的ウェブサイトとしてホストできる静的ウェブサイトホスティングの機能があるため、cloudfrontと組み合わせて、静的なWebサイトを公開することもできる。


# 実施したこと
1. お名前.comで購入したドメインのホストゾーンをRoute53で管理する設定
1. CloudFront、S3 の作成
1. DNS 登録
1. ACM で証明書発行

### 1. お名前.comで購入したドメインのホストゾーンをRoute53で管理する設定
"ホストゾーンの作成"から今回購入したドメインをドメイン名に記入して、ホストゾーンを作成していくと、レコードを２つ持ったホストゾーンが作られる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280374/e9d05099-f3ac-773c-8560-c74f05eeb923.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280374/c67a3a0b-cf33-40d8-c5ab-5be61647d131.png)

デフォルトで設定されているレコードは、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280374/92d384af-2cae-1919-7d38-eb496f2fdd9a.png)

NSレコードのルーティング先をお名前.com の設定画面から登録する。

[お名前.comのTOPページ](https://navi.onamae.com/domain/setting/renew/list)でログインし、ドメイン > 利用ドメイン一覧 から設定するドメインのリンクを踏む。  
さらに、ネームサーバーの変更をクリックすると、下記のようにネームサーバー情報を登録できる画面に辿り着くので、NSレコードのルーティング先4つを入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280374/daadd09f-6f7b-c1d5-6f97-07e954540564.png)

ここで注意するのは、Route53のルーティング先は最後にピリオド(.)が含まれているが、これがあると"ネームサーバに設定されている値が正しくありません。"とエラーになる。
したがって、ピリオドを除いだルーティング先を記入欄に入れる必要がある。

完了ページに遷移したら、設定は終わり。

nslook コマンドで名前解決の正引きを行なった。  
Non-authoritative answer にRoute53 のルーティング先が表示されたので設定は成功していることがわかる。
```
% nslookup -type=NS {対象ドメイン}
~省略~
Non-authoritative answer:
{対象ドメイン}	nameserver = ns-*****.awsdns-43.net.
{対象ドメイン}	nameserver = ns-*****.awsdns-29.org.
{対象ドメイン}	nameserver = ns-*****.awsdns-26.co.uk.
{対象ドメイン}	nameserver = ns-*****.awsdns-22.com.
```

### 2. CloudFront、S3 の作成

```app-stack.cs
// s3
const appContentsBucket = new Bucket(this, "app-contents-bucket", {
  bucketName: 'app-contents-bucket',
  removalPolicy: RemovalPolicy.DESTROY,
  websiteIndexDocument: 'index.html'
});

const oai = new OriginAccessIdentity(this, "app-oai");

const appContentsBucketPolicy = new PolicyStatement({
  effect: Effect.ALLOW,
  actions: ["s3:GetObject"],
  principals: [
    new CanonicalUserPrincipal(
      oai.cloudFrontOriginAccessIdentityS3CanonicalUserId
    ),
  ],
  resources: [appContentsBucket.bucketArn + "/*"],
});
appContentsBucket.addToResourcePolicy(appContentsBucketPolicy);

// cloudfront
new CloudFrontWebDistribution(this, "AppDistribution", {
  viewerCertificate: {
    aliases: [],
    props: {
      cloudFrontDefaultCertificate: true,
    },
  },
  priceClass: PriceClass.PRICE_CLASS_ALL,
  originConfigs: [
    {
      s3OriginSource: {
        s3BucketSource: appContentsBucket,
        originAccessIdentity: oai,
      },
      behaviors: [
        {
          isDefaultBehavior: true,
          minTtl: Duration.seconds(0),
          maxTtl: Duration.days(365),
          defaultTtl: Duration.days(1),
        },
      ],
    },
  ],
  errorConfigurations: [
    {
      errorCode: 403,
      responsePagePath: "/index.html",
      responseCode: 200,
      errorCachingMinTtl: 0,
    },
    {
      errorCode: 404,
      responsePagePath: "/index.html",
      responseCode: 200,
      errorCachingMinTtl: 0,
    },
  ],
}); 
```

### 3. DNS 登録
Route53 の 1 で作成したホストゾーで、レコードの作成をクリックする。  
ディストリビューションは 2 で作成したcloudfrontのディストリビューションドメイン名を入力し作成。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280374/edc83a30-ece6-ec3b-d6e5-c5473795f33f.png)

一方、cloudfrontの代替ドメイン名 (CNAME)にも、Route53 で設定したレコード名を指定する。  

### 4. SSL証明書発行
コンソールから証明書を発行していく。  
該当のCloudFront の、一般 > 編集 から"証明書のリクエスト"のリンクをクリックする。
すると、AWS Certificate Manager (ACM)のページに遷移するので、そのままドメイン名を記入して証明書を作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280374/b16fd55b-337b-c035-468a-671de237635d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280374/9795943c-e76e-d46c-4aca-bf4f25063137.png)

作成するだけだとステータスが保留中なので、さらにRoute53でレコードを作成のボタンからレコードを作成する。
すると、何回か更新したら発行済みのステータスに変わった。  

次にCloudFrontの編集画面に戻り、発行した証明書を選択した上で必要事項を記入、登録を進めていく。  


# 最後に
s3 にindex.htmlをアップロードし、設定したドメインにアクセスしたら、index.html の内容が表示された。  

参考にした文献を記す。
- https://dev.classmethod.jp/articles/route53-domain-onamae/
- https://dev.classmethod.jp/articles/how-to-manage-own-domain-with-route-53-origin-cloudfront/
- https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/Welcome.html
- https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Introduction.html
- https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/Welcome.html
- https://dev.classmethod.jp/articles/s3-cloudfront-static-site-design-patterns-2022/