アブストラクションとエスケープハッチ - AWS Cloud Development Kit (AWS CDK) v2

これはAWS CDK v2 開発者ガイドです。古いCDK v1は2022年6月1日にメンテナンスを開始し、今後は重大なバグ修正とセキュリティパッチのみが提供されます。新機能はCDK v2専用に開発されます。CDK v1 Support は、2023 年 6 月 1 日に完全に終了します。

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

アブストラクションとエスケープハッチ

AWS CDKでは、AWSさまざまな抽象化レベルで動作する構成を使用してリソースを記述できます。

  • レイヤー1 (L1) 構成は、AWS CloudFormation CloudFormation 仕様で定義されているリソースを直接表します。これらのコンストラクトは「Cfn」で始まる名前で識別できるため、「Cfn コンストラクト」とも呼ばれます。リソースがに存在する場合AWS CloudFormation、そのリソースは L1 構成として CDK に存在します。

  • レイヤー2(L2)または「精選された」構成は、その基盤となるL1構成と比較して、より人間工学に基づいた開発者体験を提供するように慎重に開発されています。一般的な CDK アプリでは、通常 L2 コンストラクトが最も広く使用されているタイプです。多くの場合、L2 コンストラクトは IAM ポリシー、Amazon SNS トピック、AWS KMSキーなどの追加のサポートリソースを定義します。L2 コンストラクトは、適切なデフォルト、ベストプラクティスのセキュリティポリシー、およびより人間工学に基づいた開発者エクスペリエンスを提供します。

  • レイヤー 3 (L3) の構成またはパターンは、AWS特定のユースケースに合わせてリソースのコレクション全体を定義します。L3 コンストラクトは、ビルドパイプライン、Amazon ECS アプリケーション、その他多くの種類の一般的なデプロイシナリオのいずれかを構築するのに役立ちます。L3 構成は、システム設計全体を構成する場合もあれば、大規模なシステムのかなりの部分を構成する場合もあるため、「意見が分かれている」ことがよくあります。彼らは目前の問題を解決するための特定のアプローチを中心に構築されており、彼らの先導に従うと物事はうまくいきます。

ヒント

AWS CDK構成の詳細については、を参照してくださいコンストラクト

最高レベルでは、AWS CDKアプリケーションとその中のスタック自体が、クラウドインフラストラクチャ全体、またはその大部分を抽象化したものです。パラメータ化して、さまざまな環境やさまざまなニーズに合わせて展開できます。

抽象化は、クラウドアプリケーションを設計および実装するための強力なツールです。AWS CDKを使用すると、その抽象化を使用して構築できるだけでなく、新しい抽象化を作成することもできます。既存のオープンソースのL2およびL3構成をガイダンスとして使用すると、組織のベストプラクティスや意見を反映した独自のL2およびL3構成を構築できます。

完璧な抽象化は存在しません。優れた抽象化であっても、考えられるすべてのユースケースを網羅できるわけではありません。AWS CDKのモデルの価値は明らかですが、小さな (または大きな) 微調整が欠けている、ニーズにほぼ適合する構成が見つかることもあります。

このため、には構成モデルから「脱却」AWS CDK する方法が用意されています。これにより、より低い抽象化レベルに移動したり、まったく別のモデルに移行したりすることができます。CDKのエスケープハッチは、その名前が示すように、AWS CDKパラダイムを「脱出」させ、AWS CDK設計者が予期していなかった方法でそれを拡張することを可能にします。そうすれば、これらすべてを新しい構造にまとめることで、根底にある複雑さを隠し、開発者にクリーンな API を提供できます。

脱出ハッチに手を伸ばす状況には次のようなものがあります。

  • AWSサービス機能はを介して使用できますがAWS CloudFormation、そのためのL2構成はありません。

  • AWSサービス機能はを介して利用できAWS CloudFormation、そのサービスには L2 構造がありますが、これらではまだ機能が公開されていません。L2 構成は「手作業で」開発されるため、L1 構成よりも遅れる場合があります。

  • AWS CloudFormationこの機能はまだ使用できません。

機能が使用可能かどうかを確認するにはAWS CloudFormation、「AWSリソースおよびプロパティタイプリファレンス」 を参照してください。

AWS CloudFormationコンストラクトを直接使用する

サービスに使用できる L2 クラスがない場合は、自動的に生成された L1 コンストラクトにフォールバックできます。AWS CloudFormationこれらは利用可能なすべてのリソースとプロパティに 1 対 1 で対応します。これらのリソースは、CfnCfnBucketまたはなどの名前で始まる名前で認識できますCfnRole。これらをインスタンス化するのは、AWS CloudFormation同等のリソースを使用する場合とまったく同じです。詳細については、「AWSリソースタイプリファレンス」を参照してください。

たとえば、分析を有効にして低レベルの Amazon S3 バケット L1 をインスタンス化するには、次のように記述します。

TypeScript
new s3.CfnBucket(this, 'MyBucket', { analyticsConfigurations: [ { id: 'Config', // ... } ] });
JavaScript
new s3.CfnBucket(this, 'MyBucket', { analyticsConfigurations: [ { id: 'Config' // ... } ] });
Python
s3.CfnBucket(self, "MyBucket", analytics_configurations: [ dict(id="Config", # ... ) ] )
Java
CfnBucket.Builder.create(this, "MyBucket") .analyticsConfigurations(Arrays.asList(java.util.Map.of( // Java 9 or later "id", "Config", // ... ))).build();
C#
new CfnBucket(this, 'MyBucket', new CfnBucketProps { AnalyticsConfigurations = new Dictionary<string, string> { ["id"] = "Config", // ... } });

まれに、CfnXxx対応するクラスがないリソースを定義したい場合があります。これは、AWS CloudFormationリソース仕様でまだ公開されていない新しいリソースタイプである可能性があります。このような場合は、cdk.CfnResourceを直接インスタンス化して、リソースタイプとプロパティを指定できます。これは次の例で示されます。

TypeScript
new cdk.CfnResource(this, 'MyBucket', { type: 'AWS::S3::Bucket', properties: { // Note the PascalCase here! These are CloudFormation identifiers. AnalyticsConfigurations: [ { Id: 'Config', // ... } ] } });
JavaScript
new cdk.CfnResource(this, 'MyBucket', { type: 'AWS::S3::Bucket', properties: { // Note the PascalCase here! These are CloudFormation identifiers. AnalyticsConfigurations: [ { Id: 'Config' // ... } ] } });
Python
cdk.CfnResource(self, 'MyBucket', type="AWS::S3::Bucket", properties=dict( # Note the PascalCase here! These are CloudFormation identifiers. "AnalyticsConfigurations": [ { "Id": "Config", # ... } ] } )
Java
CfnResource.Builder.create(this, "MyBucket") .type("AWS::S3::Bucket") .properties(java.util.Map.of( // Map.of requires Java 9 or later // Note the PascalCase here! These are CloudFormation identifiers "AnalyticsConfigurations", Arrays.asList( java.util.Map.of("Id", "Config", // ... )))) .build();
C#
new CfnResource(this, "MyBucket", new CfnResourceProps { Type = "AWS::S3::Bucket", Properties = new Dictionary<string, object> { // Note the PascalCase here! These are CloudFormation identifiers ["AnalyticsConfigurations"] = new Dictionary<string, string>[] { new Dictionary<string, string> { ["Id"] = "Config" } } } });

詳細については、「AWSリソースタイプリファレンス」を参照してください。

AWS CloudFormationAWSコンストラクトの背後にあるリソースの変更

L2 構成に機能が欠けている場合や問題を回避しようとしている場合は、L2 構成によってカプセル化されている L1 構成を変更できます。

すべての L2 構成には、対応する L1 構成が含まれています。たとえば、BucketCfnBucket高レベル構成は低レベル構成をラップします。CfnBucketAWS CloudFormationはリソースに直接対応しているため、で使用できるすべての機能が公開されますAWS CloudFormation。

L1 クラスにアクセスするための基本的な方法は、construct.node.defaultChild (Python:default_child) を使用して適切な型にキャストし (必要な場合)、そのプロパティを変更することです。繰り返しますが、aを例にとってみましょうBucket

TypeScript
// Get the CloudFormation resource const cfnBucket = bucket.node.defaultChild as s3.CfnBucket; // Change its properties cfnBucket.analyticsConfiguration = [ { id: 'Config', // ... } ];
JavaScript
// Get the CloudFormation resource const cfnBucket = bucket.node.defaultChild; // Change its properties cfnBucket.analyticsConfiguration = [ { id: 'Config' // ... } ];
Python
# Get the CloudFormation resource cfn_bucket = bucket.node.default_child # Change its properties cfn_bucket.analytics_configuration = [ { "id": "Config", # ... } ]
Java
// Get the CloudFormation resource CfnBucket cfnBucket = (CfnBucket)bucket.getNode().getDefaultChild(); cfnBucket.setAnalyticsConfigurations( Arrays.asList(java.util.Map.of( // Java 9 or later "Id", "Config", // ... ));
C#
// Get the CloudFormation resource var cfnBucket = (CfnBucket)bucket.Node.DefaultChild; cfnBucket.AnalyticsConfigurations = new List<object> { new Dictionary<string, string> { ["Id"] = "Config", // ... } };

このオブジェクトを使用して、AWS CloudFormationMetadataやなどのオプションを変更することもできますUpdatePolicy

TypeScript
cfnBucket.cfnOptions.metadata = { MetadataKey: 'MetadataValue' };
JavaScript
cfnBucket.cfnOptions.metadata = { MetadataKey: 'MetadataValue' };
Python
cfn_bucket.cfn_options.metadata = { "MetadataKey": "MetadataValue" }
Java
cfnBucket.getCfnOptions().setMetadata(java.util.Map.of( // Java 9+ "MetadataKey", "Metadatavalue"));
C#
cfnBucket.CfnOptions.Metadata = new Dictionary<string, object> { ["MetadataKey"] = "Metadatavalue" };

逃げ場のないハッチ

AWS CDKまた、抽象化レベルを上げる機能も提供されており、これを「エスケープ解除」ハッチと呼ぶこともあります。CfnBucketなどの L1 構成がある場合は、新しい L2 構成 (Bucketこの場合は) を作成して L1 構成をラップできます。

これは、L1 リソースを作成したが、L2 リソースを必要とする構成で使用したい場合に便利です。また、L1.grantXxxxx() コンストラクトにはないような便利なメソッドを使いたい場合にも役立ちます。

L2 クラスの静的メソッド.fromCfnXxxxx() (Amazon S3 バケットなど) を使用して、Bucket.fromCfnBucket()より高い抽象化レベルに移行します。L1 リソースは唯一のパラメータです。

TypeScript
b1 = new s3.CfnBucket(this, "buck09", { ... }); b2 = s3.Bucket.fromCfnBucket(b1);
JavaScript
b1 = new s3.CfnBucket(this, "buck09", { ...} ); b2 = s3.Bucket.fromCfnBucket(b1);
Python
b1 = s3.CfnBucket(self, "buck09", ...) b2 = s3.from_cfn_bucket(b1)
Java
CfnBucket b1 = CfnBucket.Builder.create(this, "buck09") // .... .build(); IBucket b2 = Bucket.fromCfnBucket(b1);
C#
var b1 = new CfnBucket(this, "buck09", new CfnBucketProps { ... }); var v2 = Bucket.FromCfnBucket(b1);

L1 構成から作成された L2 構成は、リソース名、ARN、または検索から作成されるものと同様に、L1 リソースを参照するプロキシオブジェクトです。これらの構成を変更しても、AWS CloudFormation最終的に合成されるテンプレートには影響しません (ただし、L1 リソースは用意されているため、代わりに変更できます)。プロキシオブジェクトの詳細については、を参照してくださいAWSアカウント内のリソースの参照

混乱を避けるため、同じ L1 構成を参照する L2 構成を複数作成しないでください。たとえば、CfnBucketBucket前のセクションの手法を使用してからを抽出する場合Bucket.fromCfnBucket()それを使ってを呼び出して 2Bucket つ目のインスタンスを作成しないでくださいCfnBucket。実際には期待どおりに動作しますが (AWS::S3::Bucket合成されるのは 1 つだけです)、コードの保守が難しくなります。

raw オーバーライド

L1 構造にないプロパティがある場合は、未処理のオーバーライドを使用して入力をすべて省略できます。これにより、合成プロパティを削除することもできます。

次の例に示すように、addOverrideいずれかのメソッド (Python:add_override) メソッドを使用します。

TypeScript
// Get the CloudFormation resource const cfnBucket = bucket.node.defaultChild as s3.CfnBucket; // Use dot notation to address inside the resource template fragment cfnBucket.addOverride('Properties.VersioningConfiguration.Status', 'NewStatus'); cfnBucket.addDeletionOverride('Properties.VersioningConfiguration.Status'); // use index (0 here) to address an element of a list cfnBucket.addOverride('Properties.Tags.0.Value', 'NewValue'); cfnBucket.addDeletionOverride('Properties.Tags.0'); // addPropertyOverride is a convenience function for paths starting with "Properties." cfnBucket.addPropertyOverride('VersioningConfiguration.Status', 'NewStatus'); cfnBucket.addPropertyDeletionOverride('VersioningConfiguration.Status'); cfnBucket.addPropertyOverride('Tags.0.Value', 'NewValue'); cfnBucket.addPropertyDeletionOverride('Tags.0');
JavaScript
// Get the CloudFormation resource const cfnBucket = bucket.node.defaultChild ; // Use dot notation to address inside the resource template fragment cfnBucket.addOverride('Properties.VersioningConfiguration.Status', 'NewStatus'); cfnBucket.addDeletionOverride('Properties.VersioningConfiguration.Status'); // use index (0 here) to address an element of a list cfnBucket.addOverride('Properties.Tags.0.Value', 'NewValue'); cfnBucket.addDeletionOverride('Properties.Tags.0'); // addPropertyOverride is a convenience function for paths starting with "Properties." cfnBucket.addPropertyOverride('VersioningConfiguration.Status', 'NewStatus'); cfnBucket.addPropertyDeletionOverride('VersioningConfiguration.Status'); cfnBucket.addPropertyOverride('Tags.0.Value', 'NewValue'); cfnBucket.addPropertyDeletionOverride('Tags.0');
Python
# Get the CloudFormation resource cfn_bucket = bucket.node.default_child # Use dot notation to address inside the resource template fragment cfn_bucket.add_override("Properties.VersioningConfiguration.Status", "NewStatus") cfn_bucket.add_deletion_override("Properties.VersioningConfiguration.Status") # use index (0 here) to address an element of a list cfn_bucket.add_override("Properties.Tags.0.Value", "NewValue") cfn_bucket.add_deletion_override("Properties.Tags.0") # addPropertyOverride is a convenience function for paths starting with "Properties." cfn_bucket.add_property_override("VersioningConfiguration.Status", "NewStatus") cfn_bucket.add_property_deletion_override("VersioningConfiguration.Status") cfn_bucket.add_property_override("Tags.0.Value", "NewValue") cfn_bucket.add_property_deletion_override("Tags.0")
Java
// Get the CloudFormation resource CfnBucket cfnBucket = (CfnBucket)bucket.getNode().getDefaultChild(); // Use dot notation to address inside the resource template fragment cfnBucket.addOverride("Properties.VersioningConfiguration.Status", "NewStatus"); cfnBucket.addDeletionOverride("Properties.VersioningConfiguration.Status"); // use index (0 here) to address an element of a list cfnBucket.addOverride("Properties.Tags.0.Value", "NewValue"); cfnBucket.addDeletionOverride("Properties.Tags.0"); // addPropertyOverride is a convenience function for paths starting with "Properties." cfnBucket.addPropertyOverride("VersioningConfiguration.Status", "NewStatus"); cfnBucket.addPropertyDeletionOverride("VersioningConfiguration.Status"); cfnBucket.addPropertyOverride("Tags.0.Value", "NewValue"); cfnBucket.addPropertyDeletionOverride("Tags.0");
C#
// Get the CloudFormation resource var cfnBucket = (CfnBucket)bucket.node.defaultChild; // Use dot notation to address inside the resource template fragment cfnBucket.AddOverride("Properties.VersioningConfiguration.Status", "NewStatus"); cfnBucket.AddDeletionOverride("Properties.VersioningConfiguration.Status"); // use index (0 here) to address an element of a list cfnBucket.AddOverride("Properties.Tags.0.Value", "NewValue"); cfnBucket.AddDeletionOverride("Properties.Tags.0"); // addPropertyOverride is a convenience function for paths starting with "Properties." cfnBucket.AddPropertyOverride("VersioningConfiguration.Status", "NewStatus"); cfnBucket.AddPropertyDeletionOverride("VersioningConfiguration.Status"); cfnBucket.AddPropertyOverride("Tags.0.Value", "NewValue"); cfnBucket.AddPropertyDeletionOverride("Tags.0");

カスタムリソース

この機能が直接API呼び出しでしか利用できない場合、解決策は1つだけです。AWS CloudFormation必要な API 呼び出しを行うには、AWS CloudFormationカスタムリソースを作成する必要があります。心配はいりません。これらを記述し、通常の構成インターフェースにまとめるのが簡単になります。AWS CDKコンストラクトのコンシューマーからすると、この機能はネイティブな感じがします。

カスタムリソースを構築するには、リソースのCREATE、、DELETEおよびライフサイクルイベントに応答する Lambda 関数を作成する必要があります。UPDATEカスタムリソースで API 呼び出しを 1 回だけ実行する必要がある場合は、の使用を検討してくださいAwsCustomResource。これにより、AWS CloudFormationデプロイ中に任意の SDK 呼び出しを実行することが可能になります。それ以外の場合は、必要な作業を実行する独自の Lambda 関数を作成する必要があります。

主題は広すぎてここでは完全に網羅できませんが、次のリンクから始めることができます。