7.2. インプットJSONファイルの作成 (CloudFrontディストリビューション: handson-cli-website-https-distribution)

作業の目的 [why]

CloudFrontディストリビューション"handson-cli-website-https-distribution"を作成します。

完了条件/事前条件 [設計者用情報]

完了条件 [after]

主処理は、以下を満たしたときに成功したものとします。

完了条件1
インプットJSONファイル"${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json"が存在する。

事前条件 [before]

主処理の実施は、以下の状態であることを前提とします。

事前条件1
インプットJSONファイル用ディレクトリ"${HOME}/conf/handson-cli-website-https-conf"が存在する。
事前条件2
インプットJSONファイル"${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json"が存在しない。
事前条件3
オリジンS3バケット"handson-cli-website-https-XXXXXXXXXXXX"が存在する。
事前条件4
ログ用S3バケット"handson-cli-website-https-XXXXXXXXXXXX-log"が存在する。
事前条件5
ドメイン"<ドメイン名>"のSSL証明書がus-east-1リージョンに存在する。

作業対象 [what]

  • CloudFrontサービス

標準時間(合計)

8分

パラメータ設定

パラメータ設定の標準時間:2分

作業に必要なモノ・情報 [resource]

作業開始には、以下が全て揃っていることが必要です。

リソース1: CloudFrontディストリビューションタグ名

  • 今回は"handson-cli-website-https-distribution"をCloudFrontディストリビューションタグ名とします。

リソース2: インプットJSONファイル用ディレクトリ

  • 今回は"${HOME}/conf/handson-cli-website-https-conf"をインプットJSON用ディレクトリとします。

ディレクトリが存在することを確認します。

コマンド:

ls -d ${HOME}/conf/handson-cli-website-https-conf

結果(例:存在する場合):

${HOME}/conf/handson-cli-website-https-conf

存在しない場合は作成します。

コマンド:

mkdir -p ${HOME}/conf/handson-cli-website-https-conf

リソース3: インプットJSONファイル名

  • 今回は"${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json"をインプットJSONファイルとします。

リソース4: SSL証明書ドメイン名

  • 作成するCloudFrontディストリビューションが利用するSSL証明書のドメイン名です。
  • 今回は"<ドメイン名>"とします。

リソース5: ホスト名

  • 作成するCloudFrontディストリビューションにアクセスするときに利用するホスト名です。
  • 今回は"handson-cli"とします。

リソース6: オリジンS3バケット名

  • 作成するCloudFrontディストリビューションが利用するオリジンS3バケットの名称です。
  • 今回は"handson-cli-website-https-XXXXXXXXXXXX"とします。

リソース7: ログ用S3バケット名

  • 作成するCloudFrontディストリビューションが利用するログ用S3バケットの名称です。
  • 今回は"handson-cli-website-https-XXXXXXXXXXXX-log"とします。

パラメータの指定

作業に必要なパラメータを変数に格納をします。

0.1. CloudFrontディストリビューションタグ名の指定

変数の設定:

CLOUDFRONT_DISTRIBUTION_TAG_NAME="handson-cli-website-https-distribution"

0.2. インプットJSONファイル用ディレクトリの指定

変数の設定:

DIR_INPUT="${HOME}/conf/handson-cli-website-https-conf"

0.3. インプットJSONファイル名の指定

変数の設定:

FILE_INPUT="${DIR_INPUT}/${CLOUDFRONT_DISTRIBUTION_TAG_NAME}.json" \
  && echo ${FILE_INPUT}

結果(例):

${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json

0.4. SSL証明書ドメイン名

ドメイン名を指定します。

変数の設定:

DOMAIN_NAME='<ドメイン名>'

ホスト名を指定します。

変数の設定:

HOST_NAME='handson-cli'

SSL証明書上のドメイン名を指定します。

コマンド:

ACM_DOMAIN_NAME="${HOST_NAME}.${DOMAIN_NAME}" \
  && echo ${ACM_DOMAIN_NAME}

結果(例):

handson-cli.<ドメイン名>

0.5. CloudFrontへのアクセスに利用するホスト名(Alias名)の指定

ホスト名を指定します。

変数の設定:

HOST_FQDN="${HOST_NAME}.${DOMAIN_NAME}" \
  && echo ${HOST_FQDN}

結果(例):

handson-cli.<ドメイン名>

0.6. オリジンS3バケット名

変数の設定:

S3_BUCKET_PREFIX='handson-cli-website-https'

コマンド:

AWS_ID=$( \
  aws sts get-caller-identity \
    --query 'Account' \
    --output text \
) \
  && echo ${AWS_ID}

結果(例):

XXXXXXXXXXXX

変数の設定:

S3_BUCKET_NAME="${S3_BUCKET_PREFIX}-${AWS_ID}" \
  && echo ${S3_BUCKET_NAME}

結果(例):

handson-cli-website-https-XXXXXXXXXXXX

0.7. ログ用S3バケット名

変数の設定:

S3_BUCKET_LOG="${S3_BUCKET_NAME}-log" \
  && echo ${S3_BUCKET_NAME}

結果(例):

handson-cli-website-https-XXXXXXXXXXXX-log

パラメータの保存

設定されている変数の保存先となるファイル名を指定します。

変数の設定:

DIR_PARAMETER="${HOME}/tmp/parameter-handson-cli-website-https"
FILE_PARAMETER="${DIR_PARAMETER}/$(date +%Y-%m-%d)-cloudfront-distribution_input_json-create.env" \
  && echo ${FILE_PARAMETER}

結果(例):

${HOME}/tmp/parameter-handson-cli-website-https/2019-07-14-cloudfront-distribution_input_json-create.env

各変数に正しいパラメータ値が格納されていることを確認しながら保存します。

変数の確認:

cat << EOF > ${FILE_PARAMETER}

  # 0.1. CLOUDFRONT_DISTRIBUTION_TAG_NAME:"handson-cli-website-https-distribution"
         CLOUDFRONT_DISTRIBUTION_TAG_NAME="${CLOUDFRONT_DISTRIBUTION_TAG_NAME}"
  # 0.2. DIR_INPUT:"${HOME}/conf/handson-cli-website-https-conf"
         DIR_INPUT="${DIR_INPUT}"
  # 0.3. FILE_INPUT:"${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json"
         FILE_INPUT="${FILE_INPUT}"
  # 0.4. DOMAIN_NAME:"<ドメイン名>"
         DOMAIN_NAME="${DOMAIN_NAME}"
  # 0.5. HOST_FQDN:"handson-cli.<ドメイン名>"
         HOST_FQDN="${HOST_FQDN}"
  # 0.6. S3_BUCKET_NAME:"handson-cli-website-https-XXXXXXXXXXXX"
         S3_BUCKET_NAME="${S3_BUCKET_NAME}"
  # 0.7. S3_BUCKET_LOG:"handson-cli-website-https-XXXXXXXXXXXX-log"
         S3_BUCKET_LOG="${S3_BUCKET_LOG}"

EOF

cat ${FILE_PARAMETER}

下段の変数が入っていない、もしくは上段と同等の値が入っていない場合は、それぞれの手順番号に戻って変数の設定を行います。

タスクの実施

タスク標準時間:6分

1. 前処理

1.1. 状態確認に必要な情報の取得

Websiteのホスト名の取得

変数の設定:

S3_BUCKET_LOCATION=$( \
  aws s3api get-bucket-location \
    --bucket ${S3_BUCKET_NAME} \
    --output text \
) \
  && echo ${S3_BUCKET_LOCATION}

結果(例):

ap-northeast-1

変数の設定:

CLOUDFRONT_ORIGIN_DOMAIN_NAME="${S3_BUCKET_NAME}.s3-website-${S3_BUCKET_LOCATION}.amazonaws.com" \
  && echo ${CLOUDFRONT_ORIGIN_DOMAIN_NAME}

結果(例)

handson-cli-website-https-XXXXXXXXXXXX.s3-ap-northeast-1.amazonaws.com

1.2. 処理対象の状態確認

主処理の実施は、以下の状態であることを前提とします。

前提と異なることが判明した場合、直ちに処理を中止します。

事前条件1: インプットJSONファイル用ディレクトリ"${HOME}/conf/handson-cli-website-https-conf"が存在する。

「インプットJSONファイル用ディレクトリ"${HOME}/conf/handson-cli-website-https-conf"が存在する。」ことを確認します。

コマンド:

ls -d ${DIR_INPUT}

結果(例):

${HOME}/conf/handson-cli-website-https-conf

事前条件2: インプットJSONファイル"${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json"が存在しない。

「インプットJSONファイル"${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json"が存在しない。」ことを確認します。

コマンド:

! ls ${FILE_INPUT}

結果(例):

ls: ${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json No such file or directory

事前条件3: オリジンS3バケット"handson-cli-website-https-XXXXXXXXXXXX"が存在する。

「オリジンS3バケット"handson-cli-website-https-XXXXXXXXXXXX"が存在する。」ことを確認します。

コマンド:

aws s3api list-buckets \
  --query "Buckets[?Name == \`${S3_BUCKET_NAME}\`].Name" \
  --output text

結果(例):

handson-cli-website-https-XXXXXXXXXXXX

事前条件4: ログ用S3バケット"handson-cli-website-https-XXXXXXXXXXXX-log"が存在する。

「ログ用S3バケット"handson-cli-website-https-XXXXXXXXXXXX-log"が存在する。」ことを確認します。

コマンド:

aws s3api list-buckets \
  --query "Buckets[?Name == \`${S3_BUCKET_LOG}\`].Name" \
  --output text

結果(例):

handson-cli-website-https-XXXXXXXXXXXX-log

事前条件5: ドメイン"<ドメイン名>"のSSL証明書がus-east-1リージョンに存在する。

「ドメイン"<ドメイン名>"のSSL証明書がus-east-1リージョンに存在する。」ことを確認します。

コマンド:

aws acm list-certificates \
  --region us-east-1 \
  --query "CertificateSummaryList[?DomainName == \`${ACM_DOMAIN_NAME}\`].DomainName" \
  --output text

結果(例):

handson-cli.<ドメイン名>

1.3. 主処理に必要な情報の取得

CloudFrontオリジンIDの指定

変数の設定:

CLOUDFRONT_ORIGIN_ID="S3-Website-${S3_BUCKET_NAME}.s3-website-${S3_BUCKET_LOCATION}.amazonaws.com" \
  && echo ${CLOUDFRONT_ORIGIN_ID}

結果(例):

S3-Website-handson-cli-website-https-XXXXXXXXXXXX.s3-website-ap-northeast-1.amazonaws.com

証明書のARN取得

コマンド:

ACM_CERT_ARN=$( \
  aws acm list-certificates \
    --region us-east-1 \
    --query "CertificateSummaryList[?DomainName == \`${ACM_DOMAIN_NAME}\`].CertificateArn" \
    --output text \
) \
  && echo ${ACM_CERT_ARN}

結果(例):

arn:aws:acm:us-east-1:XXXXXXXXXXXX:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

CallerReferenceの生成

変数の設定:

CLOUDFRONT_DISTRIBUTION_CALLER_REFERENCE=$(date +%Y-%m-%d-%H%M%S) \
  && echo ${CLOUDFRONT_DISTRIBUTION_CALLER_REFERENCE}

結果(例):

2019-07-14-012345

2. 主処理

インプットJSONファイルの作成

変数の確認:

cat << ETX

  # FILE_INPUT:"${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json"
    FILE_INPUT="${FILE_INPUT}"
  # CLOUDFRONT_DISTRIBUTION_CALLER_REFERENCE:"2019-07-14-012345"
    CLOUDFRONT_DISTRIBUTION_CALLER_REFERENCE="${CLOUDFRONT_DISTRIBUTION_CALLER_REFERENCE}"
  # HOST_FQDN:"handson-cli.<ドメイン名>"
    HOST_FQDN="${HOST_FQDN}"
  # S3_BUCKET_LOG:"handson-cli-website-https-XXXXXXXXXXXX-log"
    S3_BUCKET_LOG="${S3_BUCKET_LOG}"
  # CLOUDFRONT_ORIGIN_DOMAIN_NAME:"handson-cli-website-https-XXXXXXXXXXXX.s3-website-ap-northeast-1.amazonaws.com"
    CLOUDFRONT_ORIGIN_DOMAIN_NAME="${CLOUDFRONT_ORIGIN_DOMAIN_NAME}"
  # CLOUDFRONT_ORIGIN_ID:"S3-Website-handson-cli-website-https-XXXXXXXXXXXX.s3-website-ap-northeast-1.amazonaws.com"
    CLOUDFRONT_ORIGIN_ID="${CLOUDFRONT_ORIGIN_ID}"
  # ACM_CERT_ARN:"arn:aws:acm:us-east-1:XXXXXXXXXXXX:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    ACM_CERT_ARN="${ACM_CERT_ARN}"

ETX

コマンド:

cat << EOF > ${FILE_INPUT}
{
  "DistributionConfig": {
    "CallerReference": "${CLOUDFRONT_DISTRIBUTION_CALLER_REFERENCE}",
    "Aliases": {
      "Quantity": 1,
      "Items": [ "${HOST_FQDN}" ]
    },
    "DefaultRootObject": "",
    "Origins": {
      "Quantity": 1,
      "Items": [
        {
          "Id": "${CLOUDFRONT_ORIGIN_ID}",
          "DomainName": "${CLOUDFRONT_ORIGIN_DOMAIN_NAME}",
          "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
          }
        }
      ]
    },
    "DefaultCacheBehavior": {
      "TargetOriginId": "${CLOUDFRONT_ORIGIN_ID}",
      "ForwardedValues": {
        "QueryString": false,
        "Cookies": {
          "Forward": "none"
        },
        "Headers": {
          "Quantity": 0
        },
        "QueryStringCacheKeys": {
          "Quantity": 0
        }
      },
      "TrustedSigners": {
        "Enabled": false,
        "Quantity": 0
      },
      "ViewerProtocolPolicy": "redirect-to-https",
      "MinTTL": 0,
      "AllowedMethods": {
        "Quantity": 2,
        "Items": [
          "HEAD",
          "GET"
        ],
        "CachedMethods": {
          "Quantity": 2,
          "Items": [
            "HEAD",
            "GET"
          ]
        }
      },
      "SmoothStreaming": false,
      "DefaultTTL": 86400,
      "MaxTTL": 31536000,
      "Compress": false,
      "LambdaFunctionAssociations": {
        "Quantity": 0
      }
    },
    "CacheBehaviors": {
      "Quantity": 0
    },
    "CustomErrorResponses": {
      "Quantity": 0
    },
    "Comment": "${CLOUDFRONT_DISTRIBUTION_NAME}",
    "Logging": {
      "Enabled": true,
      "IncludeCookies": true,
      "Bucket": "${S3_BUCKET_LOG}.s3.amazonaws.com",
      "Prefix": ""
    },
    "PriceClass": "PriceClass_All",
    "Enabled": true,
    "ViewerCertificate": {
      "ACMCertificateArn": "${ACM_CERT_ARN}",
      "SSLSupportMethod": "sni-only",
      "MinimumProtocolVersion": "TLSv1",
      "Certificate": "${ACM_CERT_ARN}",
      "CertificateSource": "acm"
    },
    "Restrictions": {
      "GeoRestriction": {
        "RestrictionType": "none",
        "Quantity": 0
      }
    },
    "WebACLId": "",
    "HttpVersion": "http1.1",
    "IsIPV6Enabled": true
  }
}
EOF

cat ${FILE_INPUT}

結果(例):

()

JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。

エラーが出力されなければOKです。

コマンド:

jsonlint -q ${FILE_INPUT}

結果(例):

(出力なし)

3. 後処理

完了条件の確認

主処理は、以下を満たしたときに成功したものとします。

完了条件1: インプットJSONファイル"${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json"が存在する。

「インプットJSONファイル"${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json"が存在する。」ことを確認します。

コマンド:

ls ${FILE_INPUT}

結果(例):

${HOME}/conf/handson-cli-website-https-conf/handson-cli-website-https-distribution.json

完了