Amazon CloudFront Distribution の価格クラスごとに、AWS CDK でのデプロイ所要時間は大きく変わるのか確認してみた

結論:価格クラスに比例してデプロイ所要時間が大きくなる挙動は見られませんでした
2024.01.13

こんにちは、CX 事業本部製造ビジネステクノロジー部の若槻です。

Amazon CloudFront では、コンテンツを配信する Distribution リソースが世界中のエッジロケーションに配置され、ユーザーがコンテンツにアクセスした際に最も近いエッジロケーションからコンテンツを配信することによって低レイテンシーを実現しています。

特徴 - Amazon CloudFront | AWS より引用

このエッジロケーションは、地理的リージョンによってグループ化されており、コンテンツの配信に使用された地理的リージョンによって価格が異なります。この時、どの地理的リージョンを使用するかを価格クラスによって制御することができます。

価格クラスには All、200、100 の 3 つがあり、それぞれの価格クラスで使用される地理的リージョンは以下の通りです。クラスが高いほど、より多くの高額な地理的リージョンが使用されます。

地理的リージョン ALL 200 100 オリジンへのリージョンレベルの
データ転送 (OUT) (GB あたり)
北米 (米国、メキシコ、カナダ) 0.020 USD
ヨーロッパおよびイスラエル 0.020 USD
南アフリカ、ケニア、中東 - 0.060 USD
日本 - 0.060 USD
香港、インドネシア、フィリピン、
シンガポール、韓国、台湾、タイ
- 0.060 USD
オーストラリアおよびニュージーランド - - 0.080 USD
南米 - - 0.125 USD
インド - - 0.160 USD

そこでふと気になったのが、「価格クラスごとに、CloudFront Destribution の作成や削除などの操作に掛かる時間はどのくらい違うのか?」ということです。世界中のエッジロケーションへの伝搬が必要な Distribution の操作は何かと時間が掛かるため、低い価格クラスを選択することにより、デプロイ時間の短縮に繋がるのではないかと考えました。

そこで今回は、Amazon CloudFront Distribution の価格クラスごとに、AWS CDK でのデプロイ所要時間は大きく変わるのか確認してみました。

型定義

CDK においては CloudFront Distribution の価格クラスは、PriceClass という enum で定義されています。

node_modules に生成された PriceClass の型定義は以下となります。3 種類の価格クラスが定義されています。なお既定値は PRICE_CLASS_ALL となります。

node_modules/aws-cdk-lib/aws-cloudfront/lib/distribution.d.ts

/**
 * The price class determines how many edge locations CloudFront will use for your distribution.
 * See https://aws.amazon.com/cloudfront/pricing/ for full list of supported regions.
 */
export declare enum PriceClass {
    /** USA, Canada, Europe, & Israel */
    PRICE_CLASS_100 = "PriceClass_100",
    /** PRICE_CLASS_100 + South Africa, Kenya, Middle East, Japan, Singapore, South Korea, Taiwan, Hong Kong, & Philippines */
    PRICE_CLASS_200 = "PriceClass_200",
    /** All locations */
    PRICE_CLASS_ALL = "PriceClass_All"
}

CDK コード

価格クラスを指定した CloudFront Distribution を作成する CDK コードは下記のようになります。Distribution のプロパティとして priceClass を指定しています。

lib/cdk-sample-stack.ts

import {
  aws_cloudfront,
  aws_s3,
  aws_s3_deployment,
  aws_cloudfront_origins,
  Stack,
  RemovalPolicy,
  Duration,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    // S3 バケット を作成
    const websiteBucket = new aws_s3.Bucket(this, 'WebsiteBucket', {
      removalPolicy: RemovalPolicy.DESTROY,
      autoDeleteObjects: true,
    });

    // CloudFront の OriginAccessIdentity を作成し、S3 バケットにアクセスできるようにする
    const originAccessIdentity = new aws_cloudfront.OriginAccessIdentity(
      this,
      'OriginAccessIdentity'
    );
    websiteBucket.grantRead(originAccessIdentity);

    // CloudFront Destribution を作成
    const distribution = new aws_cloudfront.Distribution(this, 'Distribution', {
      defaultRootObject: 'index.html',
      errorResponses: [
        {
          ttl: Duration.minutes(5),
          httpStatus: 403,
          responseHttpStatus: 403,
          responsePagePath: '/error.html',
        },
        {
          ttl: Duration.minutes(5),
          httpStatus: 404,
          responseHttpStatus: 404,
          responsePagePath: '/error.html',
        },
      ],
      defaultBehavior: {
        allowedMethods: aws_cloudfront.AllowedMethods.ALLOW_GET_HEAD,
        cachedMethods: aws_cloudfront.CachedMethods.CACHE_GET_HEAD,
        cachePolicy: aws_cloudfront.CachePolicy.CACHING_OPTIMIZED,
        viewerProtocolPolicy:
          aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
        origin: new aws_cloudfront_origins.S3Origin(websiteBucket, {
          originAccessIdentity,
        }),
      },
      priceClass: aws_cloudfront.PriceClass.PRICE_CLASS_ALL,
    });

    // S3 バケットへのコンテンツのデプロイ、Destribution のキャッシュのクリア
    new aws_s3_deployment.BucketDeployment(this, 'WebsiteDeploy', {
      distribution,
      destinationBucket: websiteBucket,
      distributionPaths: ['/*'],
      sources: [
        aws_s3_deployment.Source.data(
          '/index.html',
          '<html><body><h1>Hello, World!</h1></body></html>'
        ),
        aws_s3_deployment.Source.data(
          '/error.html',
          '<html><body><h1>Error!!!</h1></body></html>'
        ),
        aws_s3_deployment.Source.data('/favicon.ico', ''),
      ],
    });
  }
}

価格クラスごとによる CDK デプロイ所要時間の比較

実際に価格クラスごとによる CDK デプロイ所要時間の比較を行ってみます。所要時間として CDK コマンド上での Deployment time を使用します。

注意点として、Distribution のデプロイには時間が掛かるため n 数はそれぞれ 1 ずつでの検証となります。

価格クラス 100 の場合

リソース作成

CDK コマンド上での Deployment time は、776.12s となりました。

$ cdk deploy --require-approval never --method=direct

✨  Synthesis time: 3.74s

CdkSampleStack:  start: Building 9d7e824b6dd7340008813f19d3c217e8083745aefeac0638aeb5573d6d2cf0fd:current_account-current_region
CdkSampleStack:  success: Built 9d7e824b6dd7340008813f19d3c217e8083745aefeac0638aeb5573d6d2cf0fd:current_account-current_region
CdkSampleStack:  start: Publishing 9d7e824b6dd7340008813f19d3c217e8083745aefeac0638aeb5573d6d2cf0fd:current_account-current_region
CdkSampleStack:  success: Published 9d7e824b6dd7340008813f19d3c217e8083745aefeac0638aeb5573d6d2cf0fd:current_account-current_region
CdkSampleStack: deploying... [1/1]
CdkSampleStack: updating stack...

 ✅  CdkSampleStack

✨  Deployment time: 776.12s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:300561038900:stack/CdkSampleStack/64865330-32dd-11ee-966b-0ad98d96b631

✨  Total time: 779.86s

リソース削除

CDK コマンド上での Deployment time は、314.74s となりました。

$ cdk deploy --require-approval never --method=direct


✨  Synthesis time: 3.33s

CdkSampleStack: deploying... [1/1]
CdkSampleStack: updating stack...

 ✅  CdkSampleStack

✨  Deployment time: 314.74s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:300561038900:stack/CdkSampleStack/64865330-32dd-11ee-966b-0ad98d96b631

✨  Total time: 318.06s

価格クラス 200 の場合

リソース作成

CDK コマンド上での Deployment time は、427.24s となりました。

$ npm run deploy

> cdk_sample_app@0.1.0 deploy
> cdk deploy --require-approval never --method=direct


✨  Synthesis time: 2.73s

CdkSampleStack:  start: Building 9e9f5f90bc3689be91d49bccae1ab0f1e139519a5013d151bd906c2b34b0c7e5:current_account-current_region
CdkSampleStack:  success: Built 9e9f5f90bc3689be91d49bccae1ab0f1e139519a5013d151bd906c2b34b0c7e5:current_account-current_region
CdkSampleStack:  start: Publishing 9e9f5f90bc3689be91d49bccae1ab0f1e139519a5013d151bd906c2b34b0c7e5:current_account-current_region
CdkSampleStack:  success: Published 9e9f5f90bc3689be91d49bccae1ab0f1e139519a5013d151bd906c2b34b0c7e5:current_account-current_region
CdkSampleStack: deploying... [1/1]
CdkSampleStack: updating stack...

 ✅  CdkSampleStack

✨  Deployment time: 427.24s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:300561038900:stack/CdkSampleStack/64865330-32dd-11ee-966b-0ad98d96b631

✨  Total time: 429.97s

リソース削除

CDK コマンド上での Deployment time は、309.34s となりました。

$ npm run deploy

> cdk_sample_app@0.1.0 deploy
> cdk deploy --require-approval never --method=direct


✨  Synthesis time: 2.69s

CdkSampleStack: deploying... [1/1]
CdkSampleStack: updating stack...

 ✅  CdkSampleStack

✨  Deployment time: 309.34s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:300561038900:stack/CdkSampleStack/64865330-32dd-11ee-966b-0ad98d96b631

✨  Total time: 312.02s

価格クラス ALL の場合

リソース作成

CDK コマンド上での Deployment time は、427.17s となりました。

$ npm run deploy

> cdk_sample_app@0.1.0 deploy
> cdk deploy --require-approval never --method=direct


✨  Synthesis time: 3.37s

CdkSampleStack:  start: Building dc470b08e9460c9ba6e18008277a46983efecd1b65dd95acc332915a86b59136:current_account-current_region
CdkSampleStack:  success: Built dc470b08e9460c9ba6e18008277a46983efecd1b65dd95acc332915a86b59136:current_account-current_region
CdkSampleStack:  start: Publishing dc470b08e9460c9ba6e18008277a46983efecd1b65dd95acc332915a86b59136:current_account-current_region
CdkSampleStack:  success: Published dc470b08e9460c9ba6e18008277a46983efecd1b65dd95acc332915a86b59136:current_account-current_region
CdkSampleStack: deploying... [1/1]
CdkSampleStack: updating stack...

 ✅  CdkSampleStack

✨  Deployment time: 427.17s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:300561038900:stack/CdkSampleStack/64865330-32dd-11ee-966b-0ad98d96b631

✨  Total time: 430.54s

リソース削除

CloudFormation のイベント履歴上では、スタックのステータスが 2024-01-13 03:02:40 UTC+0900DELETE_IN_PROGRESS となり、2024-01-13 03:07:17 UTC+0900DELETE_COMPLETE となりました。

CDK コマンド上での Deployment time は、283.58s となりました。

$ npm run deploy

> cdk_sample_app@0.1.0 deploy
> cdk deploy --require-approval never --method=direct


✨  Synthesis time: 2.61s

CdkSampleStack: deploying... [1/1]
CdkSampleStack: updating stack...

 ✅  CdkSampleStack

✨  Deployment time: 283.58s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:300561038900:stack/CdkSampleStack/64865330-32dd-11ee-966b-0ad98d96b631

✨  Total time: 286.19s

結果

それぞれの価格クラスでのデプロイ所要時間は以下の通りでした。価格クラスの高さに比例してデプロイ所要時間が長くなるという結果とはなりませんでした。

  • リソース作成
100 200 ALL
12分56秒 7分7秒 7分7秒
  • リソース削除
100 200 ALL
5 分 15 秒 5 分 9 秒 4 分 44 秒

各エッジロケーションで作成や削除のワークロードがパラレルに実行され、また実行所要時間はエッジロケーション上でのワークロードの実行状況に大きく左右されるという挙動となるようで、エッジロケーションの数の多さはデプロイ所要時間に大きく影響しないようです。

おわりに

Amazon CloudFront Distribution の価格クラスごとに、AWS CDK でのデプロイ所要時間は大きく変わるのか確認してみました。

「Distribution を頻繁に操作する検証時には低い価格クラスを使えばデプロイ時間を短縮できるのでは?」と考えたのですが、そんなことはないようでした。というわけで価格クラスは実際の利用に即したものを選択すれば良さそうです。

参考

以上