ハンズオン(簡易版): CloudFront入門

1.1. CloudFrontディストリビューションの作成 (handson-cli-cloudfront-distribution)

手順の目的 [why]

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

設定値の指定

設定値の指定

手順に必要な設定値を変数に格納をします。

1. ディストリビューションタグ名

ディストリビューションタグ名の指定します。

変数の設定:

CLOUDFRONT_DISTRIBUTION_TAG_NAME="handson-cli-cloudfront-distribution"

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

オリジンS3バケット名を指定します。

変数の設定:

S3_BUCKET_PREFIX='handson-cli-cloudfront-highlevel'

コマンド:

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-cloudfront-highlevel-XXXXXXXXXXXX

3. デフォルトルートオブジェクト名

デフォルトルートオブジェクト名を指定します。

変数の設定:

CLOUDFRONT_DISTRIBUTION_DEFAULT_ROOT_OBJECT="index.html"

4. 一時ファイル用ディレクトリ

一時ファイル用ディレクトリを指定します。

変数の設定:

DIR_TMP="${HOME}/environment/tmp-handson-cli-cloudfront"

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

コマンド:

ls -d ${DIR_TMP}

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

${HOME}/environment/tmp-handson-cli-cloudfront

ディレクトリが存在しない場合は作成します。

コマンド:

mkdir -p ${DIR_TMP}

設定値の確認

各変数に正しい設定値が格納されていることを確認しながら保存します。

変数の確認:

cat << END

  # 1. CLOUDFRONT_DISTRIBUTION_TAG_NAME:"handson-cli-cloudfront-distribution"
       CLOUDFRONT_DISTRIBUTION_TAG_NAME="${CLOUDFRONT_DISTRIBUTION_TAG_NAME}"
  # 2. S3_BUCKET_NAME:"handson-cli-cloudfront-highlevel-XXXXXXXXXXXX"
       S3_BUCKET_NAME="${S3_BUCKET_NAME}"
  # 3. CLOUDFRONT_DISTRIBUTION_DEFAULT_ROOT_OBJECT:"index.html"
       CLOUDFRONT_DISTRIBUTION_DEFAULT_ROOT_OBJECT="${CLOUDFRONT_DISTRIBUTION_DEFAULT_ROOT_OBJECT}"
  # 4. DIR_TMP:"${HOME}/environment/tmp-handson-cli-cloudfront"
       DIR_TMP="${DIR_TMP}"

END

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

処理の実行

S3バケットのロケーションを取得します。

変数の設定:

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

結果(例):

ap-northeast-1

CloudFrontオリジンドメイン名を指定します。

変数の設定:

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

結果(例):

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

一時出力ファイル名を指定します。

変数の設定:

FILE_CLOUDFRONT_DISTRIBUTION_OUTPUT="${DIR_TMP}/$(date +%Y-%m-%d)-cloudfront-distribution-${CLOUDFRONT_DISTRIBUTION_TAG_NAME}.json" \
  && echo ${FILE_CLOUDFRONT_DISTRIBUTION_OUTPUT}

結果(例):

${HOME}/environment/tmp-handson-cli-cloudfront/2021-11-25-cloudfront-distribution-handson-cli-cloudfront-distribution.json

CloudFrontディストリビューションを作成します。

変数の確認:

cat << END

  # CLOUDFRONT_ORIGIN_DOMAIN_NAME:"handson-cli-cloudfront-highlevel-XXXXXXXXXXXX.s3-website-ap-northeast-1.amazonaws.com"
    CLOUDFRONT_ORIGIN_DOMAIN_NAME="${CLOUDFRONT_ORIGIN_DOMAIN_NAME}"
  # CLOUDFRONT_DISTRIBUTION_DEFAULT_ROOT_OBJECT:"index.html"
    CLOUDFRONT_DISTRIBUTION_DEFAULT_ROOT_OBJECT="${CLOUDFRONT_DISTRIBUTION_DEFAULT_ROOT_OBJECT}"
  # FILE_CLOUDFRONT_DISTRIBUTION_OUTPUT:"${HOME}/environment/tmp-handson-cli-cloudfront/2021-11-25-cloudfront-distribution-handson-cli-cloudfront-distribution.json"
    FILE_CLOUDFRONT_DISTRIBUTION_OUTPUT="${FILE_CLOUDFRONT_DISTRIBUTION_OUTPUT}"

END

コマンド:

aws cloudfront create-distribution \
  --origin-domain-name "${CLOUDFRONT_ORIGIN_DOMAIN_NAME}" \
  --default-root-object ${CLOUDFRONT_DISTRIBUTION_DEFAULT_ROOT_OBJECT} \
  > ${FILE_CLOUDFRONT_DISTRIBUTION_OUTPUT}

結果(例):

{
    "Location": "https://cloudfront.amazonaws.com/2020-05-31/distribution/xxxxxxxxxxxxxx",
    "ETag": "Exxxxxxxxxxxxx",
    "Distribution": {
        "Id": "xxxxxxxxxxxxxx",
        "ARN": "arn:aws:cloudfront::XXXXXXXXXXXX:distribution/xxxxxxxxxxxxxx",
        "Status": "InProgress",
        "LastModifiedTime": "2021-11-25T02:24:22.907Z",
        "InProgressInvalidationBatches": 0,
        "DomainName": "dxxxxxxxxxxxxx.cloudfront.net",
        "ActiveTrustedSigners": {
            "Enabled": false,
            "Quantity": 0
        },
        "ActiveTrustedKeyGroups": {
            "Enabled": false,
            "Quantity": 0
        },
        "DistributionConfig": {
            "CallerReference": "cli-1637807062-559528",
            "Aliases": {
                "Quantity": 0
            },
            "DefaultRootObject": "index.html",
            "Origins": {
                "Quantity": 1,
                "Items": [
                    {
                        "Id": "handson-cli-cloudfront-highlevel-XXXXXXXXXXXX.s3-website-ap-northeast-1.amazonaws.com-1637807062-193255",
                        "DomainName": "handson-cli-cloudfront-highlevel-XXXXXXXXXXXX.s3-website-ap-northeast-1.amazonaws.com",
                        "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": "handson-cli-cloudfront-highlevel-XXXXXXXXXXXX.s3-website-ap-northeast-1.amazonaws.com-1637807062-193255",
                "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": false,
                "LambdaFunctionAssociations": {
                    "Quantity": 0
                },
                "FunctionAssociations": {
                    "Quantity": 0
                },
                "FieldLevelEncryptionId": "",
                "ForwardedValues": {
                    "QueryString": false,
                    "Cookies": {
                        "Forward": "none"
                    },
                    "Headers": {
                        "Quantity": 0
                    },
                    "QueryStringCacheKeys": {
                        "Quantity": 0
                    }
                },
                "MinTTL": 0,
                "DefaultTTL": 86400,
                "MaxTTL": 31536000
            },
            "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
        }
    }
}

ディストリビューションARNの取得

ディストリビューションARNを取得します。

コマンド:

CLOUDFRONT_DISTRIBUTION_ARN=$( \
  cat ${FILE_CLOUDFRONT_DISTRIBUTION_OUTPUT} \
    | jp.py "Distribution.ARN" \
    | sed 's/\"//g' \
) \
  && echo ${CLOUDFRONT_DISTRIBUTION_ARN}

結果(例):

arn:aws:cloudfront::XXXXXXXXXXXX:distribution/Exxxxxxxxxxxxx

タグ情報の指定

タグ情報を指定します。

変数の設定:

CLOUDFRONT_TAG_KEY='Name'

変数の設定:

CLOUDFRONT_TAG_VALUE=${CLOUDFRONT_DISTRIBUTION_TAG_NAME} \
  && echo ${CLOUDFRONT_TAG_VALUE}

結果(例):

handson-cli-cloudfront-distribution

タグ設定文字列の生成

タグ設定文字列を生成します。

変数の設定:

STRING_CLOUDFRONT_TAGS="Items=[{Key=${CLOUDFRONT_TAG_KEY},Value=${CLOUDFRONT_TAG_VALUE}}]" \
&& echo ${STRING_CLOUDFRONT_TAGS}

結果(例):

Items=[{Key=Name,Value=handson-cli-cloudfront-distribution}]

タグ設定対象リソースの指定

タグ設定対象リソースを指定します。

変数の設定:

CLOUDFRONT_TAG_RESOURCE="${CLOUDFRONT_DISTRIBUTION_ARN}" \
  && echo ${CLOUDFRONT_TAG_RESOURCE}

結果(例):

arn:aws:cloudfront::XXXXXXXXXXXX:distribution/Exxxxxxxxxxxxx

タグの作成

タグを作成します。

コマンド:

aws cloudfront tag-resource \
  --resource ${CLOUDFRONT_TAG_RESOURCE} \
  --tags "${STRING_CLOUDFRONT_TAGS}"

結果(例):

(出力なし)

完了確認

本手順の主処理は、以下の完了条件を満たしたときに成功したものとします。

完了条件1: ディストリビューションドキュメントに記述されたWebsiteをオリジンとするCloudFrontディストリビューションが存在する。

「ディストリビューションドキュメントに記述されたWebsiteをオリジンとするCloudFrontディストリビューションが存在する。」ことを確認します。

コマンド:

for i in $( 
  aws cloudfront list-distributions \
    --query "DistributionList.Items[].ARN" \
    --output text \
); do
  j=$( \
    aws cloudfront list-tags-for-resource \
      --resource ${i} \
      --query "Tags.Items[?Key == \`Name\` && Value == \`${CLOUDFRONT_DISTRIBUTION_TAG_NAME}\`].Value" \
      --output text \
  )
  if [ "${j}x" != 'x' ]; then echo "${j}"; fi
done

結果(例):

handson-cli-cloudfront-distribution

課題

list-distributionsコマンドがタグ表示できないため、全てのディストリビューションに対してlist-tags-for-resourceコマンドでタグの有無をチェックするしか方法がない。(サポートには未確認)

完了条件2: CloudFrontディストリビューションタグ名"handson-cli-cloudfront-distribution"のステータスが"Deployed"である。

「CloudFrontディストリビューションタグ名"handson-cli-cloudfront-distribution"のステータスが"Deployed"である。」ことを確認します。

ディストリビューションIDを取得します。

コマンド:

for i in $(
  aws cloudfront list-distributions \
    --query "DistributionList.Items[].ARN" \
    --output text \
); do
  j=$( \
    aws cloudfront list-tags-for-resource \
      --resource ${i} \
      --query "Tags.Items[?Key == \`Name\` && Value == \`${CLOUDFRONT_DISTRIBUTION_TAG_NAME}\`].Value" \
      --output text \
  )
  if [ "${j}" == "${CLOUDFRONT_DISTRIBUTION_TAG_NAME}" ]; then \
    CLOUDFRONT_DISTRIBUTION_ID=$( \
      aws cloudfront list-distributions \
        --query "DistributionList.Items[?ARN == \`${i}\`].Id" \
        --output text \
    )
  fi
done \
  && echo ${CLOUDFRONT_DISTRIBUTION_ID}

結果(例):

Exxxxxxxxxxxxx

課題

list-distributionsコマンドがタグ表示できないため、全てのディストリビューションに対してlist-tags-for-resourceコマンドでタグの有無をチェックするしか方法がない。(サポートには未確認)

ディストリビューションのステータスを確認します。

コマンド:

CLOUDFRONT_DISTRIBUTION_STATUS=$(
  aws cloudfront get-distribution \
    --id ${CLOUDFRONT_DISTRIBUTION_ID} \
    --query 'Distribution.Status' \
    --output text \
) \
  && echo ${CLOUDFRONT_DISTRIBUTION_STATUS}

結果(例):

Deployed

注釈

"InProgress"から"Deployed"まで、20〜30分程度かかります。

手順の完了

(参考) マネジメントコンソールの確認

ディストリビューション一覧(画面)

  • ディストリビューションが表示されていることを確認します。(タグ名では検索できません)