AWS CLIで Web サイトを構築、管理、運用する(5日目)

4日目では、ライフサイクルポリシーを設定してアクセスログが無尽蔵に増え続けるのを防ぎました。
5日目は、コンテンツ配信ネットワークの設定を入れます。

# 5日目の要約
コンテンツ配信ネットワークの設定を入れる！


# AWS CLI の準備
このあたりをみて、好きなバージョンとお使いのOSにあった環境設定をしてくださいね。
なんなら、 AWS CloudShell で実行するのも楽でよいと思います。
この記事シリーズは、AWS CloudShell で実行し、実行例を載せています。

バージョン１
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv1.html

バージョン２
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2.html

# 概要
CloudFront の設定をしてコンテンツ配信ネットワークを使えるようにする。

# さあ、やってみよう！
CloudFront では「ディストリビューション」というもので、どこからコンテンツを得るのか(オリジン）といった設定を行います。
コマンドは cloudfront create-distribution を使用します。
そして、このコマンドに投入する json ファイルを事前に作成します。
少し長めですが、ご参考まで。。。適宜変更を加えてください。

```json:distribution.json
{
   "DistributionConfig": {
    "CallerReference": "<任意の値>",
    "Aliases": {
       "Quantity": 0
    },
    "DefaultRootObject": "",
    "Origins": {
       "Quantity": 1,
       "Items": [ {
          "Id":"<S3 Web サイトのFQDN>",
          "DomainName": "<S3 Web サイトのFQDN>",
          "OriginPath": "",
          "CustomHeaders": {
             "Quantity": 0 
          },
          "CustomOriginConfig": {
             "HTTPPort": 80,
             "HTTPSPort": 443,
             "OriginProtocolPolicy": "http-only",
             "OriginSslProtocols": {
                 "Quantity": 3,
                 "Items": [
                     "TLSv1",
                     "TLSv1.1",
                     "TLSv1.2"
                 ]
             },
             "OriginReadTimeout": 30,
             "OriginKeepaliveTimeout": 5
          },
          "ConnectionAttempts": 3,
          "ConnectionTimeout": 10,
          "OriginShield": {
              "Enabled": false
          }
        }
     ]
   },
   "OriginGroups": {
      "Quantity": 0
   },
   "DefaultCacheBehavior": {
      "TargetOriginId": "<S3 Web サイトのFQDN>",
      "TrustedSigners": {
          "Enabled": false,
          "Quantity": 0
      },
      "TrustedKeyGroups": {
          "Enabled": false,
          "Quantity": 0
      },
      "ViewerProtocolPolicy": "allow-all",
      "AllowedMethods": {
          "Quantity": 2,
          "Items": [
              "HEAD",
              "GET"
          ],
          "CachedMethods": {
              "Quantity": 2,
              "Items": [
                 "HEAD",
                 "GET"
              ]
          }
       },
       "SmoothStreaming": false,
       "Compress": true,
       "LambdaFunctionAssociations": {
          "Quantity": 0
       },
       "FunctionAssociations": {
          "Quantity": 0
       },
       "FieldLevelEncryptionId": "",
       "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6"
    },
    "CacheBehaviors": {
       "Quantity": 0
    },
    "CustomErrorResponses": {
       "Quantity": 0
    },
    "Comment": "",
    "Logging": {
       "Enabled": false,
       "IncludeCookies": false,
       "Bucket": "",
       "Prefix": ""
    },
    "PriceClass": "PriceClass_All",
    "Enabled": true,
    "ViewerCertificate": {
       "CloudFrontDefaultCertificate": true,
       "MinimumProtocolVersion": "TLSv1",
       "CertificateSource": "cloudfront"
    },
    "Restrictions": {
       "GeoRestriction": {
          "RestrictionType": "none",
          "Quantity": 0
       }
    },
    "WebACLId": "",
    "HttpVersion": "http2",
    "IsIPV6Enabled": true
    }
}

```

json ファイルが作成できたら、ディストリビューションを作成していきます。

```sh
aws cloudfront create-distribution --cli-input-json file://distribution.json
```

コマンド実行が正常に完了すると、作成されたディストリビューションの情報が入った json が出力されます。
今回は流石に長いので割愛します。
出力された json のうち、 DomainName の値を確認します。
これが、CloudFront 経由でアクセスする際のFQDNです。

## 動作確認しよう
さきほど確認した DomainName の値を用いて curl コマンドを実行します。

```sh
curl https://<CloudFront の DomainName の値>
```

問題がなければ、3日目で作成した HTML が表示されるはずです。
もし、以下のような内容が返された場合は、 CloudFront のディストリビューションの設定を AWS のエッジロケーションに配布中の可能性が高いです。少し待ってから再実行してみてください。

```HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>403 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Bad request.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: gXOtvEVz_s7_8655aVFU9LPaf1bH33nv1txEtFuIA4KNEuYSLwXBbg==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>
```

# まとめ
S3 で配信している Web サイトをコンテンツ配信ネットワークである CloudFront に載せることができました。
また、副次的な効能として https でアクセスできるようになりました。
実は、 S3 の Web サイトホスティング機能は http のみのアクセスだったのです。。。！

* 今回使ったコマンド
 * cloudfront create-distribution