🚀

AWS CDKでConstructのpropsからリソースを生成する場合・作成したリソースのメソッドからリソースを作成する場合の違い

2023/09/06に公開

AWS CDKで開発している際、インターネット上のサンプルなんかを見ると記事のタイトルにあるような記法の違いがみられることがあります。今まで特に気にせず何となく実装していたのですが、それでは良くないと思い、ちゃんと調べてみました。

サンプル

以下は、それぞれの方法によるサンプルコードです。この例では、S3バケットとCloudFrontディストリビューションを作成し、CloudFrontディストリビューションのオリジンとしてS3バケットを設定します。

  1. Constructのpropsを使用してリソースを生成する場合:
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';

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

    // S3バケットを作成
    const bucket = new s3.Bucket(this, 'MyBucket', {
      versioned: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });

    // CloudFrontディストリビューションを作成
    const distribution = new cloudfront.Distribution(this, 'MyDistribution', {
      defaultBehavior: {
        origin: new cloudfront.Origins.S3Origin(bucket),
      },
    });
  }
}
  1. 生成したリソースのメソッドを使用してリソースを作成する場合:
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';

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

    // S3バケットを作成
    const bucket = new s3.Bucket(this, 'MyBucket', {
      versioned: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });

    // CloudFrontディストリビューションを作成
    const distribution = new cloudfront.Distribution(this, 'MyDistribution');

    // CloudFrontディストリビューションにオリジンを追加
    distribution.addOrigin(new cloudfront.Origins.S3Origin(bucket));
  }
}

各手法の特徴

Constructのpropsを使用してリソースを生成する場合と、生成したリソースのメソッドを使用してリソースを作成する場合の違いは以下の通りです。

  1. Constructのpropsを使用する場合:
  • リソースの生成時に、リソースに関連するパラメータを指定できる
  • パラメータは、Constructのコンストラクタに渡され、リソースの作成時に使用される
  • リソースの作成と構成が一元化されており、コードが簡潔で読みやすくなる
  1. 生成したリソースのメソッドを使用してリソースを作成する場合:
  • リソースが生成された後に、当該のリソースに対してメソッドを呼び出すことで、リソースの構成を変更できる
  • リソースの構成が柔軟であり、リソースの生成後に構成の変更ができる
  • コードが冗長になりがちであり、リソースの構成が分散してしまうことがある

2の手法を使うケース

リソースの生成後に構成を変更する必要があるケースとしては、以下のような場合が考えられます。

  • あるリソースが別のリソースに依存しており、その依存関係がリソースの生成後に解決される場合

    • 例: S3バケットが作成された後に、CloudFrontディストリビューションがそのバケットをオリジンとして設定される場合
  • リソースの構成が実行時に決定される場合

    • 例: AWS Lambda関数の環境変数が、デプロイ時に外部から取得される値に基づいて設定される場合
  • リソースの構成が、特定の条件に基づいて変更される場合

    • 例: 開発環境と本番環境で異なる構成を持つリソースがある場合
  • リソースの構成が非常に複雑であり、Constructのpropsだけでは表現できない場合

    • 例: Amazon API Gatewayのリソースやメソッドの構成が多岐にわたる場合

これらのケースでは、リソースの生成後に構成を変更する必要があるため、2の方法で対応することができます。ただし、この方法ではコードが冗長になりがちであり、リソースの構成が分散してしまうことがあるため、適切なバランスを見つけることが重要です。

どちらの方法を選択するかは、プロジェクトの要件と開発者の好みによります。一般的には、可読性等の面からConstructのpropsを使用してリソースを生成する方法が推奨されますが、リソースの構成が非常に複雑である場合や、リソースの生成後に構成を変更する必要がある場合は、2の方法が適しています。

正直どちらの手法でも大差ないですが、個人的には1で統一されている方が読みやすい気がします。

Discussion