CLIいいですよね。
GUIと違ってコピペですみます。
これはAWS CloudFrontのDistributionをコマンドラインから作成する物語です。

ちなみに、DistributionというのはCloudFrontの設定単位です。

あらかじめ必要なもの|こと

  • AWS CLI
  • AWSのアカウント
  • AWS CLIにログインしておく

雛形JSONを生成

awsコマンドに渡す雛形を生成できます。便利。

aws cloudfront create-distribution --generate-cli-skeleton > aws-cloudfront-distribution.json

aws-cloudfront-distribution.jsonというファイルができました。

このJSONファイルを使ってDistributionを作成します。

Distributionの中身

Distributionには、大まかにいって2つの設定があります。配信元とキャッシュの振る舞いです。

配信元

配信元のことをOriginといいます。
OriginはS3やAPI Gateway等のhttp/httpsでアクセスできるものです。
Originは複数個使うことができます。

Originを束ねてフェールオーバーさせることもできます。OriginGroupといいます。

図にするとこんな感じです。

image.png

(作図には draw.io を使用しました。これすご過ぎないですか?)

キャッシュの振る舞い

キャッシュの振る舞いはパスごとに設定できます。
例えば、「/staticは最低3日キャッシュ」みたいなことができます。
どのパスにもマッチしないコンテンツに対しては既定の振る舞いを設定できます。

図にするとこんな感じです。

image.png

今回作成するもの

なんとなくわかった感じになったところで、今回作成するものです。

  • 配信元
    • Angularでできたフロントエンド。S3に格納しています。
    • API。LambdaでできたAPIです。クエリストリングを受け取ってJSONを返します。
  • キャッシュの振る舞い
    • 既定値は3日キャッシュ
    • APIへのアクセスは1日キャッシュ(あまり変わらないものなので)

JSONを編集

Originを作成

まずOriginを作成します。
Originは、S3とS3以外で少し違います。

S3の場合

パラメータ 説明
DomainName S3のホスト名です。
Id Originを区別する一意な文字列です。
S3OriginConfig S3へアクセスするのに必要なIdentityです。

S3OriginConfigは、プライベートなS3の時に使う認証情報です。
今回はパブリックなS3なので使いません。

S3以外の場合

パラメータ 説明
DomainName S3の場合と一緒です。
Id Originを区別する一意な文字列です。
CustomOriginConfig このOriginの設定です。

CustomOriginConfigはこんな内容です。

パラメータ 説明
HttpPort HTTPポート番号です。必須です。
HttpsPort HTTPSポート番号です。必須です。
OriginProtocolPolicy http-only、match-viewer、https-onlyのいずれかです。
OriginSslProtocols TLSv1等SSL接続に使うプロトコルです。|

できあがったJSON

Angularでできたフロントエンド用


        {
          "Id": "origin-s3",
          "DomainName": "hokanchan.uart.dev.s3-website-ap-northeast-1.amazonaws.com",
          "S3OriginConfig": {
            "OriginAccessIdentity": ""
          }
        }

S3OriginConfigは中身なくても記述しないとダメです。

API用


        {
          "Id": "origin-api",
          "DomainName": "4719bbobr6.execute-api.us-west-1.amazonaws.com",
          "OriginPath": "/Prod/suggest",
          "CustomOriginConfig": {
            "HTTPPort": 80,
            "HTTPSPort": 443,
            "OriginProtocolPolicy": "https-only",
            "OriginSslProtocols": {
              "Quantity": 1,
              "Items": ["TLSv1.2"]
            },
            "OriginReadTimeout": 60,
            "OriginKeepaliveTimeout": 1
          }
        }

TLSv1.2のみがベストプラクティスだそうです。

キャッシュの振る舞いを作成

キャッシュを制御するパラメータはたくさんあります。

中身は大体一緒です。とりあえず必須パラメータだけあげます。

パラメータ 説明
ForwardedValues クエリ文字列やCookieの振る舞いを設定します。
MinTTL キャッシュに残す最小TTLです。
TargetOriginId 先に設定したOriginのIdです。ルーティング先です。
TrustedSigners Originがプライベートなもののときに使う認証情報です(で、いいのかな)。
ViewerProtocolPolicy Originへのアクセスに使えるものです allow-all、https-only、redirect-to-httpsのいずれかです。

特定パス用には、パスを特定するパラメータ PathPattern も必須です。

できあがったJSON

既定用

    "DefaultCacheBehavior": {
      "TargetOriginId": "origin-s3",
      "ForwardedValues": {
        "QueryString": true,
        "Cookies": {
          "Forward": "all"
        }
      },
      "TrustedSigners": {
        "Enabled": false,
        "Quantity": 0
      },
      "ViewerProtocolPolicy": "redirect-to-https",
      "MinTTL": 0,
      "DefaultTTL": 259200,
      "Compress": true,
    }

API用

APIに渡すクエリストリングに応じてキャッシュするようにしました。
HTTPヘッダにHost以外の何かを指定する必要があります。

    "CacheBehaviors": {
      "Quantity": 1,
      "Items": [
        {
          "PathPattern": "/Prod/suggest/*",
          "TargetOriginId": "origin-api",
          "ForwardedValues": {
            "QueryString": true,
            "Cookies": {
              "Forward": "all"
            },
            "Headers": {
              "Quantity": 6,
              "Items": [
                "Accept",
                "Accept-Encoding",
                "Accept-Language",
                "Cache-Control",
                "User-Agent",
                "DNT"
              ]
            },
            "QueryStringCacheKeys": {
              "Quantity": 1,
              "Items": ["q"]
            }
          },
          "TrustedSigners": {
            "Enabled": false,
            "Quantity": 0
          },
          "ViewerProtocolPolicy": "allow-all",
          "MinTTL": 0,
          "DefaultTTL": 86400,
          "Compress": true
        }
      ]
    }

その他記述するもの

これらのパラメータが必須です。

パラメータ 説明
CallerReference CloundFront作成呼び出しを一意に識別する文字列。シリアルみたいなものですね
Comment 作成しようとしているディストリビューションにつける任意のコメント
Enabled 有効か無効か。もちろん有効にするので Yes 一択です。

独自ドメイン用サーバ証明書

*.cloudfront.comではなく、独自ドメインで運用したいので設定します。
Amazon Certificate ManagerのUS-EAST-1リージョンに証明書がないといけないみたいです。

    "ViewerCertificate": {
      "CloudFrontDefaultCertificate": false,
      "ACMCertificateArn": "arn:aws:acm:us-east-1:069866334413:certificate/6bbabedf-c976-49b5-9633-f676aa7f1f2c",
      "SSLSupportMethod": "sni-only"
    }

ARNは次のコマンドで取得できます。

aws --region us-east-1  acm list-certificates

/ でアクセスされた時に返すもの

https://www.example.com/ でアクセスされた時にindex.htmlを返すようにします。


    "DefaultRootObject": "index.html",

独自ドメイン名

使用する独自ドメイン名を記述します。

    "Aliases": {
      "Quantity": 1,
      "Items": ["hokanchan.uart.dev"]
    },

awsコマンドを実行

JSONファイルができました。
awsコマンドを実行します。

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

エラーが出たら……

必須と書いてなくても、存在しないといけない項目があるようです。
最初に生成した雛形から消し過ぎないほうがよさそうです。

DNSを設定

独自ドメインにしたので、ネームサーバにCNAMEレコードを登録します。
登録する値は次のコマンドでわかります。

aws cloudfront list-distributions --query 'DistributionList.Items[*].DomainName'

レコードが存在するとエラーになりますので、存在する場合は消しておきます。