AWS CDK で CloudFront KeyValueStore の L2 Construct がサポートされました(ただし CloudFront Functions との関連付けは未対応)

2024.01.05

こんにちは、CX 事業本部 Delivery 部の若槻です。

先日に AWS CDK v2.118.0 がリリースされ、CloudFront KeyValueStore の L2 Construct がサポートされました。

Features

  • cloudfront: Key Value Store L2 (#28473) (030db42), closes #28377

これにより CloudFront Functions が利用する Key Value Store を AWS CDK でより簡単に構成できるようになりました。ただし注意点として、CloudFront Functions と KeyValueStore の関連付けは現時点でも未対応となります。

試してみた

CDK ライブラリのアップグレード

AWS CDK のモジュールを v2.118.0 以上にアップグレードします。

npm i aws-cdk@latest aws-cdk-lib@latest

型定義

node_modules に生成された KeyValueStoreProps の型定義は以下となります。source によりデータをあらかじめインポートできるようになっています。

node_modules/aws-cdk-lib/aws-cloudfront/lib/key-value-store.d.ts

/**
 * The properties to create a Key Value Store.
 */
export interface KeyValueStoreProps {
    /**
     * The unique name of the Key Value Store.
     *
     * @default A generated name
     */
    readonly keyValueStoreName?: string;
    /**
     * A comment for the Key Value Store
     *
     * @default No comment will be specified
     */
    readonly comment?: string;
    /**
     * The import source for the Key Value Store.
     *
     * This will populate the initial items in the Key Value Store. The
     * source data must be in a valid JSON format.
     *
     * @default No data will be imported to the store
     */
    readonly source?: ImportSource;
}

ここで、KeyValueStore を Function の関連付けはどう行えば良いのでしょうか。CloudFormation の「AWS::CloudFront::Function FunctionConfig」の定義を見ると KeyValueStoreAssociations というプロパティがあります。CloudFront Functions 側で関連付けを構成する必要があるんですね。

{
  "Comment" : String,
  "KeyValueStoreAssociations" : [ KeyValueStoreAssociation, ... ],
  "Runtime" : String
}

そこで node_modules に生成された FunctionConfigProperty の型定義を見ると KeyValueStoreAssociations は存在しません。これは L1 の定義でもあるのでエスケープハッチによる対応も行えません。

    /**
     * Contains configuration information about a CloudFront function.
     *
     * @struct
     * @stability external
     * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionconfig.html
     */
    interface FunctionConfigProperty {
        /**
         * A comment to describe the function.
         *
         * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionconfig.html#cfn-cloudfront-function-functionconfig-comment
         */
        readonly comment: string;
        /**
         * The function's runtime environment version.
         *
         * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionconfig.html#cfn-cloudfront-function-functionconfig-runtime
         */
        readonly runtime: string;
    }

今回のアップデートの Pull Request でもコントリビューターの方が関連付けの未対応を指摘しています。

This adds an initial resource to support creating a Key Value Store and specifying an import source. Unfortunately, CloudFormation doesn't seem to support specifying the KeyValueStoreAssociations property of a function so there isn't a way to actually associate the store with a function.

よって、KeyValueStore の AWS CDK での CloudFront Functions との関連付は現時点ではサポートされておらず、リソースの作成のみとなります。

実装

インポートするデータをあらかじめ作成しておきます。ここでは以下のような JSON ファイルを用意しました。

kvs-data.json

{
  "data": [
    {
      "key": "key1",
      "value": "value"
    },
    {
      "key": "key2",
      "value": "value"
    }
  ]
}

aws_cloudfront.KeyValueStore クラスを使用して KeyValueStore を作成します。データをインポートしない場合とする場合で試してみます。

lib/cdk-sample-stack.ts

import { aws_cloudfront, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

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

    // CloudFront KeyValueStore の作成
    new aws_cloudfront.KeyValueStore(this, 'KeyValueStore');

    // CloudFront KeyValueStore の作成、データの投入
    new aws_cloudfront.KeyValueStore(this, 'KeyValueStoreWithData', {
      source: aws_cloudfront.ImportSource.fromAsset('kvs-data.json'),
    });
  }
}

CDK デプロイをすると、以下のような CloudFormation リソースが作成されます。データのインポートに伴うカスタムリソースの作成はされないようです。

CloudFront のコンソールから、データがインポートされていない KeyValueStore と、されていない KeyValueStore が作成されたことを確認できました。

投入データを変更する場合はリソースの再作成が必要

ここで、投入するデータを変更して再度 CDK デプロイを行ってみます。

kvs-data.json

{
  "data": [
    {
      "key": "key1",
      "value": "value"
    },
    {
      "key": "key2",
      "value": "value"
    },
    {
      "key": "key3",
      "value": "value"
    }
  ]
}

しかしデプロイが cannot update a stack when a custom-named resource requires replacing. Rename CdkSampleStackKeyValueStoreWithData というエラーとなりました。

$ npm run deploy

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


✨  Synthesis time: 3.38s

CdkSampleStack:  start: Building 9c0c42c1ee61ea786ad7840cb8809cefd3554138235087ff94532b3a9e5277fb:current_account-current_region
CdkSampleStack:  success: Built 9c0c42c1ee61ea786ad7840cb8809cefd3554138235087ff94532b3a9e5277fb:current_account-current_region
CdkSampleStack:  start: Publishing 9c0c42c1ee61ea786ad7840cb8809cefd3554138235087ff94532b3a9e5277fb:current_account-current_region
CdkSampleStack:  start: Building e63b40bb5b76c03aa7989a7532723e6ee66ad6e57474ee3f4aca9365b9b70451:current_account-current_region
CdkSampleStack:  success: Built e63b40bb5b76c03aa7989a7532723e6ee66ad6e57474ee3f4aca9365b9b70451:current_account-current_region
CdkSampleStack:  start: Publishing e63b40bb5b76c03aa7989a7532723e6ee66ad6e57474ee3f4aca9365b9b70451:current_account-current_region
CdkSampleStack:  success: Published 9c0c42c1ee61ea786ad7840cb8809cefd3554138235087ff94532b3a9e5277fb:current_account-current_region
CdkSampleStack:  success: Published e63b40bb5b76c03aa7989a7532723e6ee66ad6e57474ee3f4aca9365b9b70451:current_account-current_region
CdkSampleStack: deploying... [1/1]
CdkSampleStack: updating stack...
8:47:03 PM | UPDATE_FAILED        | AWS::CloudFront::KeyValueStore | KeyValueStoreWithData553D2977
CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename CdkSampleStackKeyValueStoreWithData
D700711C and update the stack again.

投入データを変更する場合は、結果としてリソースの作り直し(削除デプロイ→再作成デプロイ)をする必要がありました。また source プロパティの追加、削除の場合も同じ挙動となりました。物理 ID を指定していないので L2 Construct ならよろしくやってくれそうではありますが、ここは制限であるようです。

しかし、KeyValueStore のデータ投入は、マネジメントコンソールから手動で行いたい場合がほとんどだと思うので、上記のように CDK で管理することはあまりないかもしれません。

おわりに

AWS CDK で CloudFront KeyValueStore の L2 Construct がサポートされたのでご紹介しました。

今回は KeyValueStore の作成だけで、CloudFront Functions との関連付けが未対応なのは片手落ちな感が大きいですが、少なくともリソースは L2 Construct で管理可能になりました。遠くない将来に関連付けもサポートされると思うので、今後のアップデートに期待しておきましょう。(もしくは自らコントリビュートを行いましょう)

以上