AWS CDK Mixinsが安定版になったので試してみた

AWS CDK Mixinsが安定版になったので試してみた

2026.03.27

どうも!オペ部の西村祐二です!

AWS CDKでインフラを定義していると、L2 Constructではまだサポートされていないプロパティを設定したくなる場面があります。従来はescape hatchesで直接CloudFormationリソースを操作するか、L1 Constructに切り替える必要がありました。

2025年11月にDeveloper Previewとして登場したCDK Mixinsが、2026年3月12日にGA(一般提供)が発表されました。v2.241.0でaws-cdk-libにコア機能が導入され、v2.242.0ではS3・ECSのサービスMixinsが、v2.243.0ではCFN Property Mixinsが安定版に昇格しています。さらにv2.244.0では、AspectsとMixinsの相互変換ヘルパー(Shimsクラス)が追加されました。

今回は、CDK Mixinsの基本的な使い方からカスタムMixinの作成まで試してみました。

結論

CDK Mixinsは、L1/L2 Constructに対して.with()メソッドで機能を後付けできる仕組みです。escape hatchesを使わずに、型安全にConstructの機能を拡張できます。

この記事で分かること:

  • CDK Mixinsの基本的な使い方(.with()メソッド)
  • aws-cdk-libに同梱されたサービスMixinsの利用方法
  • Mixins.of() APIによるスコープ全体への適用
  • カスタムMixinの作成方法
  • MixinsとAspectsの使い分け
  • ShimsクラスによるAspectsとMixinsの相互変換(v2.244.0〜)

前提条件

  • Node.js 18以上
  • AWS CDK CLI v2(npx cdkで使用するか、npm install -g aws-cdkでグローバルインストール)
  • AWS CDK v2.244.0以上(aws-cdk-lib)※v2.243.0以上で基本機能は利用可能
  • AWSアカウントとCLI設定済み

CDK Mixinsとは

CDK Mixinsは、Constructに対して合成可能な機能を追加するための仕組みです。

CDKにはL1(CloudFormationリソースの1対1マッピング)とL2(AWS推奨のデフォルト値付きの高レベル抽象)の2層のConstructがあります。AWSの新機能がリリースされると、L1には即座に反映されますが、L2への反映には時間がかかります。従来のCDKアーキテクチャでは、L2を使うかL1に切り替えるか選択を迫られていました。

新しいL2の設計思想:Mixins / Facades / Traits

Mixinsの導入に合わせて、CDKのL2 Constructは3つの構成要素に分解されました。

構成要素 役割
Mixins リソース自身の機能を拡張(内向き) BucketVersioning, BucketAutoDeleteObjects
Facades 外部向けの簡易インターフェース(外向き) BucketGrants, BucketMetrics
Traits サービス横断的な共通契約 IResourceWithPolicyV2, IEncryptedResource

つまり、概念的にL2 = L1 + Mixins + Facades + Traits + デフォルト値です。

各構成要素はL2から独立して使用できるため、L2が完成していないサービスでもMixinやFacadeを個別に利用できます。この記事ではMixinsに焦点を当てます。

Mixinsの仕組み

MixinsはL1(Cfn*)リソースをターゲットにしています。L2 Constructに対して.with()を呼ぶと、フレームワークが自動的にL2内部のL1デフォルトチャイルドに委譲します。ユーザーはL1/L2の違いを意識せずに使えます。

Mixinsは対象リソース自身の機能を拡張します。バージョニングの有効化、パブリックアクセスブロック、オブジェクト自動削除などは、すべてバケット自身の振る舞いに関するものです。一方、ロールへのアクセス許可のように外部の利用者に向けた機能はMixinsではなくFacadesの領域です。

Aspectsとの違い

CDKには以前からAspectsという仕組みがありますが、Mixinsとは役割が異なります。

特性 Mixins Aspects
実行タイミング 即座に実行 合成(synth)フェーズで実行
プログラミング方式 命令型 宣言型
推奨用途 個別リソースへの機能追加(暗号化、バージョニング等) スコープ全体のルール強制・検証(ポリシー準拠チェック等)
対象範囲 呼び出し時点のConstruct(Mixins.of()でスコープ適用も可能) Constructツリー全体(後から追加されたConstructも対象)

公式ドキュメントでは、Mixinsは「個別のリソースに具体的な機能を追加する」ために、Aspectsは「スコープ全体にルールの強制や検証を行う」ために使うことが推奨されています。つまり、リソースの設定変更はMixinで行い、組織のポリシーに準拠しているかのチェックはAspectで行う、という使い分けです。両者は併用でき、たとえばMixinで各バケットに暗号化を適用し、Aspectで「暗号化されていないバケットがないか」をsynth時に検証する、といった組み合わせが可能です。

Aspectsとの重要な違いとして、Mixinsは適用時点のConstructのみを対象としますが、Aspectsは後から追加されたConstructも対象になります。

lib/aspects-vs-mixins.ts
// Aspects: MyBucket2も対象になる
Aspects.of(construct).add(new CustomVersioningAspect());
new s3.Bucket(construct, 'MyBucket2'); // Aspectが適用される

// Mixins: MyBucket2は対象にならない
Mixins.of(construct).apply(new s3.mixins.BucketVersioning());
new s3.Bucket(construct, 'MyBucket2'); // Mixinは適用されない

Shimsによる相互変換(v2.244.0〜)

v2.244.0で追加されたShimsクラスを使うと、既存のAspectをMixinとして即座に適用したり、逆にMixinをAspectとしてsynth時に遅延実行したりできます。既存の資産を書き直さずに再利用できるため、段階的な移行に便利です。

この記事では、サービスMixins、CFN Property Mixins、Shimsによる相互変換を中心に試していきます。

試してみる

以下では、各ステップが独立した検証例になっています。ステップごとにlib/cdk-mixins-test-stack.tsを書き換えてnpx cdk synthで動作を確認してください。

1. CDKプロジェクトの作成

検証用のCDKプロジェクトを作成します。

mkdir cdk-mixins-test && cd cdk-mixins-test
npx cdk init app --language typescript

aws-cdk-libのバージョンがv2.243.0以上であることを確認します。

npm list aws-cdk-lib
# aws-cdk-lib@2.244.0

v2.244.0未満の場合はアップデートします。

npm install aws-cdk-lib@latest

2. .with()メソッドでS3 MixinsをL1 Constructに適用

L1 Construct(CfnBucket)に対して、型安全にプロパティを追加できます。従来はL1を直接操作するかescape hatchesに頼る必要がありましたが、.with()メソッドでサービスMixinsを適用するだけで済みます。

aws-cdk-lib/aws-s3mixins名前空間から利用可能なMixinsをインポートします。

lib/cdk-mixins-test-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';

export class CdkMixinsTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // L1 ConstructにMixinsを適用
    new s3.CfnBucket(this, 'MyL1Bucket')
      .with(new s3.mixins.BucketVersioning())
      .with(new s3.mixins.BucketBlockPublicAccess());
  }
}

.with()はチェーン可能で、複数のMixinsを順番に適用できます。複数Mixinsを一度に渡すこともできます。

lib/cdk-mixins-test-stack.ts
new s3.CfnBucket(this, 'MyL1Bucket')
  .with(
    new s3.mixins.BucketVersioning(),
    new s3.mixins.BucketBlockPublicAccess()
  );

synthしてCloudFormationテンプレートを確認します。

npx cdk synth
cdk.out/CdkMixinsTestStack.template.json
"MyL1Bucket": {
  "Type": "AWS::S3::Bucket",
  "Properties": {
    "VersioningConfiguration": {
      "Status": "Enabled"
    },
    "PublicAccessBlockConfiguration": {
      "BlockPublicAcls": true,
      "BlockPublicPolicy": true,
      "IgnorePublicAcls": true,
      "RestrictPublicBuckets": true
    }
  }
}

CfnBucketに対して、バージョニングとパブリックアクセスブロックの設定がMixins経由で追加されています。

3. L2 Constructへの適用

L1でもL2でも同じMixinを同じ書き方で使えます。L2に.with()で適用すると、内部のL1リソースに自動的に委譲されるため、Constructのレベルを途中で変更してもMixin側のコードを書き換える必要がありません。

前回のコードのconstructor内に以下を追加します。

lib/cdk-mixins-test-stack.ts
// L2 ConstructにMixinsを適用(constructor内に追加)
new s3.Bucket(this, 'MyL2Bucket', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
}).with(new s3.mixins.BucketAutoDeleteObjects());

BucketAutoDeleteObjectsは、スタック削除時にバケット内のオブジェクトを自動削除するMixinです。従来はL2 ConstructのautoDeleteObjectsプロパティで設定していましたが、Mixinとしても提供されています。実際、L2のautoDeleteObjectsプロパティは内部でBucketAutoDeleteObjects Mixinに委譲するようリファクタリングされています。

L2のBucketにはすでにautoDeleteObjectsプロパティがありますが、L1のCfnBucketを使っている場合はMixinで同じ機能を追加できるのがポイントです。MixinsはL1をターゲットにしているため、L2に.with()で適用すると内部のL1デフォルトチャイルドに自動的に委譲されます。

S3以外のサービスでも使える:ECR RepositoryAutoDeleteImages

MixinsはS3だけではありません。v2.242.0ではECRにもRepositoryAutoDeleteImages Mixinが追加されています。

lib/cdk-mixins-test-stack.ts
import * as ecr from 'aws-cdk-lib/aws-ecr';

new ecr.CfnRepository(this, 'MyRepo')
  .with(new ecr.mixins.RepositoryAutoDeleteImages());

CloudFormationネイティブのemptyOnDeleteプロパティを設定するだけの軽量なMixinで、カスタムリソースやLambdaは不要です。BucketAutoDeleteObjectsと合わせて使うと、スタック削除時にS3バケットとECRリポジトリの中身を自動的にクリーンアップできます。

4. Mixins.of()でスコープ全体に適用

「すべてのS3バケットにパブリックアクセスブロックを適用」のようなポリシーの一括適用を、コンパクトに記述できます。個々のConstructに.with()を書いて回る必要がなく、適用漏れも防げます。

Mixins.of() APIを使うと、特定のスコープ内の複数のConstructにMixinsを一括適用できます。lib/cdk-mixins-test-stack.tsを以下の内容に書き換えます。

lib/cdk-mixins-test-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Mixins, ConstructSelector } from 'aws-cdk-lib/core';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';

export class CdkMixinsTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new s3.CfnBucket(this, 'Bucket1');
    new s3.CfnBucket(this, 'Bucket2');
    new s3.CfnBucket(this, 'Bucket3');

    // スタック内のすべてのS3バケットにバージョニングを適用
    Mixins.of(
      this,
      ConstructSelector.resourcesOfType('AWS::S3::Bucket')
    ).apply(new s3.mixins.BucketVersioning());
  }
}

ConstructSelectorには以下のセレクタが用意されています。

セレクタ 説明
ConstructSelector.all() スコープ内の全Construct
ConstructSelector.resourcesOfType(type) 指定したCloudFormationリソースタイプに一致するConstruct
ConstructSelector.cfnResource() L1またはL2のリソースConstruct
ConstructSelector.byId(pattern) IDパターン(ワイルドカード)に一致するConstruct

requireAll()で適用漏れを検出

requireAll()を使うと、セレクタで選択されたすべてのConstructにMixinが適用されたことをアサートできます。

lib/cdk-mixins-test-stack.ts
Mixins.of(this, ConstructSelector.resourcesOfType('AWS::S3::Bucket'))
  .requireAll()
  .apply(new s3.mixins.BucketVersioning());

もしMixinが対応していないConstructがセレクタに含まれていた場合、エラーが発生します。ガバナンスの強制に使えます。

5. カスタムMixinの作成

組織固有のセキュリティポリシーやベストプラクティスをMixinとしてパッケージ化できます。チーム内で共有すれば、ポリシーの適用が.with()一行で済み、実装のばらつきを防げます。

Mixinクラスを継承し、supports()applyTo()を実装します。

以下は、S3バケットにサーバーサイド暗号化(SSE-S3)を強制するカスタムMixinの例です。

lib/encryption-mixin.ts
import { Mixin } from 'aws-cdk-lib/core';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { IConstruct } from 'constructs';

export class BucketEncryptionSSES3 extends Mixin {
  supports(construct: any): construct is s3.CfnBucket {
    return s3.CfnBucket.isCfnBucket(construct);
  }

  applyTo(bucket: IConstruct): void {
    (bucket as s3.CfnBucket).bucketEncryption = {
      serverSideEncryptionConfiguration: [
        {
          serverSideEncryptionByDefault: {
            sseAlgorithm: 'AES256',
          },
        },
      ],
    };
  }
}

使用側ではサービスMixinsと同じように.with()で適用します。

lib/cdk-mixins-test-stack.ts
import { BucketEncryptionSSES3 } from './encryption-mixin';

new s3.CfnBucket(this, 'EncryptedBucket')
  .with(new BucketEncryptionSSES3());

supports()falseを返すConstructに対して.with()で適用した場合はスキップされます。Mixins.of().apply()も同様です。確実に適用したい場合はrequireAll()を併用します。

デザインガイドラインによると、カスタムMixinには3種類のバリデーションを実装できます。

  1. 初期化時: コンストラクタでMixinのプロパティをバリデート
  2. 適用時: applyTo()内でターゲットConstructの前提条件をバリデート
  3. 遅延バリデーション: node.addValidation()でsynth時にバリデート
lib/encryption-mixin.ts
export class BucketEncryptionSSES3 extends Mixin {
  supports(construct: any): construct is s3.CfnBucket {
    return s3.CfnBucket.isCfnBucket(construct);
  }

  applyTo(bucket: IConstruct): void {
    const cfnBucket = bucket as s3.CfnBucket;

    // 適用時バリデーション: すでに暗号化が設定済みならエラー
    if (cfnBucket.bucketEncryption) {
      throw new Error('Bucket encryption is already configured');
    }

    cfnBucket.bucketEncryption = {
      serverSideEncryptionConfiguration: [
        {
          serverSideEncryptionByDefault: { sseAlgorithm: 'AES256' },
        },
      ],
    };
  }
}

カスタムMixinの命名規則として、クラス名はターゲットリソース名をプレフィックスにします(BucketVersioningのように。Versioning単体はNG)。ファイルはサービスモジュール内のlib/mixins/ディレクトリに配置します。

6. CFN Property Mixinsで任意のL1プロパティを設定

L2がまだサポートしていないL1プロパティを、escape hatchesのaddPropertyOverride()なしで型安全に設定できます。従来のescape hatchesは文字列ベースでタイポに気づきにくいという課題がありましたが、CFN Property MixinsならTypeScriptの型チェックが効くため、プロパティ名やネスト構造の誤りをコンパイル時に検出できます。

v2.243.0で安定版に昇格したCFN Property Mixinsは、@aws-cdk/cfn-property-mixinsパッケージとして提供されています。aws-cdk-lib本体とは別にインストールが必要です。

npm install @aws-cdk/cfn-property-mixins
lib/cdk-mixins-test-stack.ts
import { CfnBucketPropsMixin } from '@aws-cdk/cfn-property-mixins/aws-s3';

new s3.Bucket(this, 'MyBucket').with(
  new CfnBucketPropsMixin({
    analyticsConfigurations: [
      {
        id: 'entire-bucket',
        storageClassAnalysis: {
          dataExport: {
            destination: {
              bucketArn: 'arn:aws:s3:::analytics-dest',
              format: 'CSV',
            },
            outputSchemaVersion: 'V_1',
          },
        },
      },
    ],
  })
);

L2 ConstructのBucketにはまだanalyticsConfigurationsのサポートがありませんが、CFN Property Mixinを使えばescape hatchesを使わずに設定できます。

PropertyMergeStrategy

CfnBucketPropsMixinは既存のプロパティとのマージ戦略を指定できます。

lib/cdk-mixins-test-stack.ts
import { PropertyMergeStrategy } from 'aws-cdk-lib/core';

// combine(デフォルト): ネストされたオブジェクトを再帰的にマージ
new s3.CfnBucket(this, 'Bucket1').with(
  new CfnBucketPropsMixin(
    { publicAccessBlockConfiguration: { blockPublicAcls: true } },
    { strategy: PropertyMergeStrategy.combine() }
  )
);

// override: 既存のプロパティを完全に置き換え
new s3.CfnBucket(this, 'Bucket2').with(
  new CfnBucketPropsMixin(
    {
      corsConfiguration: {
        corsRules: [{ allowedMethods: ['GET'], allowedOrigins: ['*'] }],
      },
    },
    { strategy: PropertyMergeStrategy.override() }
  )
);

combine()はネストされたオブジェクトを再帰的にマージし、プリミティブや配列は新しい値で上書きします。override()は既存値を完全に破棄します。CORS設定やライフサイクルルールなど、部分マージが意味をなさないプロパティにはoverride()を使います。

7. 他の言語での使用

Mixinsは全CDKサポート言語で利用できます。Developer Preview時代はTypeScript/JavaScriptのみでしたが、全言語に対応となりました。

Python:

import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())

Java、C#でも同様に.with()/.With()メソッドが使えます。コード例は公式ドキュメントを参照してください。

8. ShimsでAspectとMixinを相互変換する(v2.244.0〜)

既存のAspectsをそのままMixinとして再利用できるため、Mixinsへの移行時にコードを書き直す必要がありません。逆にMixinをAspectに変換すれば、後から追加されたConstructにも自動で適用される遅延実行の恩恵を受けられます。

v2.244.0で追加されたShimsクラスを使って、両方向の変換を試してみます。

8-1. 既存のAspectをMixinとして使う(Shims.asMixin)

まず、既存のAspectを用意します。S3バケットにタグを付与するシンプルなAspectです。

lib/tagging-aspect.ts
import { IAspect, Tags } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { IConstruct } from 'constructs';

export class BucketTaggingAspect implements IAspect {
  constructor(private readonly environment: string) {}

  visit(node: IConstruct): void {
    if (node instanceof s3.CfnBucket) {
      Tags.of(node).add('Environment', this.environment);
    }
  }
}

通常このAspectはAspects.of(scope).add(...)で使いますが、Shims.asMixin()でMixinに変換して.with()で即座に適用できます。

lib/cdk-mixins-test-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Shims } from 'aws-cdk-lib/core';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
import { BucketTaggingAspect } from './tagging-aspect';

export class CdkMixinsTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // AspectをMixinに変換して即座に適用
    const taggingMixin = Shims.asMixin(new BucketTaggingAspect('production'));

    new s3.CfnBucket(this, 'TaggedBucket')
      .with(taggingMixin)
      .with(new s3.mixins.BucketVersioning());
  }
}

synthして確認します。

npx cdk synth
cdk.out/CdkMixinsTestStack.template.json(抜粋)
"TaggedBucket": {
  "Type": "AWS::S3::Bucket",
  "Properties": {
    "VersioningConfiguration": {
      "Status": "Enabled"
    },
    "Tags": [
      {
        "Key": "Environment",
        "Value": "production"
      }
    ]
  }
}

Shims.asMixin()で変換されたMixinは、supports()が常にtrueを返します。これはAspectがスコープ内のすべてのConstructを訪問するのと同じ動作です。対象の絞り込みはAspect側のvisit()内のロジック(上記のinstanceofチェック)で行われるため、変換後もそのまま機能します。

8-2. MixinをAspectとして使う(Shims.asAspect)

逆に、MixinをAspectに変換してsynth時に遅延実行することもできます。Aspectsの「後から追加されたConstructも対象になる」という特性を活かしたい場合に有用です。

lib/cdk-mixins-test-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Aspects } from 'aws-cdk-lib';
import { Shims } from 'aws-cdk-lib/core';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';

export class CdkMixinsTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // MixinをAspectに変換してsynth時に遅延実行
    const versioningAspect = Shims.asAspect(new s3.mixins.BucketVersioning());
    Aspects.of(this).add(versioningAspect);

    // Aspect登録後に追加したバケットにも適用される
    new s3.CfnBucket(this, 'Bucket1');
    new s3.CfnBucket(this, 'Bucket2');
    new s3.CfnBucket(this, 'Bucket3');
  }
}
npx cdk synth

3つのバケットすべてにVersioningConfigurationが設定されていることを確認します。

cat cdk.out/CdkMixinsTestStack.template.json | jq '.Resources | to_entries[] | select(.value.Type == "AWS::S3::Bucket") | {key: .key, versioning: .value.Properties.VersioningConfiguration}'

期待される出力:

{
  "key": "Bucket1",
  "versioning": {
    "Status": "Enabled"
  }
}
{
  "key": "Bucket2",
  "versioning": {
    "Status": "Enabled"
  }
}
{
  "key": "Bucket3",
  "versioning": {
    "Status": "Enabled"
  }
}

Shims.asAspect()はMixinのsupports()メソッドをフィルタとして保持します。BucketVersioningはS3バケットのみをサポートするため、スコープ内に他のリソース(例えばDynamoDBテーブル)があってもスキップされます。

Shims使い分けのポイント

変換方向 メソッド ユースケース
Aspect → Mixin Shims.asMixin() 既存Aspectを特定のConstructに即座に適用したい場合。段階的なMixins移行時に便利
Mixin → Aspect Shims.asAspect() Mixinをスコープ全体に遅延適用したい場合。後から追加されるConstructにも適用される

Mixins.of()との違いとして、Mixins.of()は適用時点のConstructのみが対象ですが、Shims.asAspect()はAspectの特性により後から追加されたConstructも対象になります。スコープ全体への適用で「漏れなく」適用したい場合はShims.asAspect()が適しています。

つまずきポイントと対処法

すべてのMixinsがaws-cdk-libにあるわけではない

S3、ECR、ECSのサービスMixinsはaws-cdk-libに組み込まれていますが、EventBridgeやCloudFrontのログ配信Mixins、CloudWatch Logsの監査ログMixinsなど、まだ@aws-cdk/mixins-previewパッケージにしかないMixinsも多数あります。

aws-cdk-libから目当てのMixinsが見つからない場合は、@aws-cdk/mixins-previewを確認してみてください。

npm install @aws-cdk/mixins-preview

なお、aws-cdk-libに組み込み済みのMixinsと@aws-cdk/mixins-previewのMixinsを同じプロジェクトで併用すること自体は可能ですが、aws-cdk-libに組み込まれているものはaws-cdk-libからインポートするようにしてください。

試してみた感想

  • L1/L2の区別を気にせず使える
    • 同じMixinがL1にもL2にも適用できるので、Constructのレベルを途中で変更してもMixinのコードを書き換える必要がありません。L2に.with()すると内部のL1に自動委譲される仕組みがよくできています
  • escape hatchesからの脱却
    • 従来は(bucket.node.defaultChild as s3.CfnBucket).addPropertyOverride(...)のように書いていた箇所を、型安全な.with()で置き換えられます
  • 「L2 = L1 + Mixins + Facades + Traits + デフォルト値」の設計思想が明確
    • デザインドキュメントを読むと、従来のL2が抱えていた「Coverage・Completeness・Customizationの3つのトレッドミル問題」を解消する設計意図が分かります。L2の完成を待たずに個別の構成要素(Mixins、Facades、Traits)を使えるようになるのは、実運用上ありがたい変化です
  • ConstructSelectorで一括適用できるのが実用的
    • 「本番環境のすべてのS3バケットにパブリックアクセスブロックを適用」のようなポリシーの一括適用がコンパクトに書けます
  • まだaws-cdk-libにないMixinsも多い
    • EventBridgeやCloudFrontのログ配信Mixins、CloudWatch Logsの監査ログMixinsなどは引き続き@aws-cdk/mixins-previewパッケージが必要です。今後のリリースで順次aws-cdk-libに組み込まれていくと思われます
  • Shimsで既存資産を活かせる
    • v2.244.0のShimsクラスにより、すでに作成済みのAspectをMixinとして再利用できます。逆にMixinをAspectとして遅延実行することもできるので、チーム内で段階的にMixinsへ移行する際に便利です
  • 既存のL2プロパティとの棲み分け
    • Bucketversioned: trueBucketVersioning Mixinは同じことを実現します。L2で十分な場合は従来通りプロパティで設定し、L2で未対応の機能やL1を使っている場合にMixinsを活用する、という使い分けになりそうです。実際、L2の既存プロパティは内部でMixinに委譲するようリファクタリングが進んでいます

まとめ

CDK Mixinsは、L1/L2 Constructに対して.with()メソッドで機能を合成的に追加できる仕組みです。2025年11月のDeveloper Previewを経て、2026年3月にaws-cdk-libに正式導入されました。

主なポイントは以下のとおりです。

  • .with()メソッドで任意のConstructに機能を追加できる(L2→L1への自動委譲あり)
  • Mixins.of()とConstructSelectorでスコープ全体への一括適用が可能
  • カスタムMixinを作成して独自のポリシーを適用できる(命名規則・バリデーションパターンあり)
  • CFN Property Mixinsで、L2未対応のL1プロパティをescape hatchesなしで設定できる
  • MixinsとAspectsは用途が異なる(Mixinは個別リソースへの機能追加、Aspectはスコープ全体のルール強制・検証)
  • Shimsクラスで既存のAspectをMixinに、MixinをAspectに相互変換できる(v2.244.0〜)
  • 全CDKサポート言語(TypeScript、JavaScript、Python、Java、C#、Go)で利用可能

もしescape hatchesに頼っていた箇所がある場合は、Mixinsへの移行を検討してみてください。

誰かの参考になれば幸いです。


参考リンク:

この記事をシェアする

FacebookHatena blogX

関連記事