從 AWS 建構程式庫自訂建構 - AWS Cloud Development Kit (AWS CDK) v2

這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 於 2022 年 6 月 1 日進入維護,並於 2023 年 6 月 1 日結束支援。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

從 AWS 建構程式庫自訂建構

透過逃生艙、原始覆寫和自訂資源,從 AWS 建構程式庫自訂建構。

使用逸出艙門

AWS 建構程式庫提供不同抽象層級的建構

在最高層級,您的 AWS CDK 應用程式及其中的堆疊本身就是整個雲端基礎設施的摘要,或是其中的大量區塊。可以對它們進行參數化,以將其部署到不同的環境或不同的需求。

抽象是設計和實作雲端應用程式的強大工具。不僅 AWS CDK 可讓您使用其抽象內容建置 ,也可讓您建立新的抽象內容。使用現有的開放原始碼 L2 和 L3 建構做為指引,您可以建置自己的 L2 和 L3 建構,以反映組織的最佳實務和意見。

沒有任何抽象是完美的,即使是好的抽象也無法涵蓋每個可能的使用案例。在開發期間,您可能會找到幾乎符合您需求的建構,需要小型或大型自訂。

因此, AWS CDK 提供了分離建構模型的方法。這包括完全移至較低層級的抽象或不同的模型。逃生艙可讓您逃離範式,並以符合您需求的方式自訂 AWS CDK 。然後,您可以在新的建構中包裝變更,以抽象基礎複雜性,並為API其他開發人員提供簡潔。

以下是您可以使用逃生艙的情況範例:

  • AWS 服務功能可透過 使用 AWS CloudFormation,但沒有 L2 建構。

  • AWS 服務功能可透過 使用 AWS CloudFormation,且服務有 L2 建構,但這些結構尚未公開該功能。由於 L2 建構是由CDK團隊所策劃,因此可能無法立即用於新功能。

  • 此功能完全無法透過 使用 AWS CloudFormation 。

    若要判斷 功能是否可透過 使用 AWS CloudFormation,請參閱AWS 資源和屬性類型參考

開發 L1 建構的逃生艙

如果 L2 建構不適用於 服務,您可以使用自動產生的 L1 建構。這些資源可以透過名稱識別,開頭為 Cfn,例如 CfnBucketCfnRole。您可以像使用對等 AWS CloudFormation 資源一樣進行實例化。

例如,若要在啟用分析的情況下現化低階 Amazon S3 儲存貯體 L1,您會撰寫如下內容。

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

在極少數情況下,您想要定義沒有對應CfnXxx類別的資源。這可能是尚未在資源規格中發佈的新 AWS CloudFormation 資源類型。在這種情況下,您可以cdk.CfnResource直接實例化 並指定資源類型和屬性。如以下範例所示。

TypeScript
new cdk.CfnResource(this, 'amzn-s3-demo-bucket', { type: 'AWS::S3::Bucket', properties: { // Note the PascalCase here! These are CloudFormation identifiers. AnalyticsConfigurations: [ { Id: 'Config', // ... } ] } });
JavaScript
new cdk.CfnResource(this, 'amzn-s3-demo-bucket', { type: 'AWS::S3::Bucket', properties: { // Note the PascalCase here! These are CloudFormation identifiers. AnalyticsConfigurations: [ { Id: 'Config' // ... } ] } });
Python
cdk.CfnResource(self, 'amzn-s3-demo-bucket', type="AWS::S3::Bucket", properties=dict( # Note the PascalCase here! These are CloudFormation identifiers. "AnalyticsConfigurations": [ { "Id": "Config", # ... } ] } )
Java
CfnResource.Builder.create(this, "amzn-s3-demo-bucket") .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, "amzn-s3-demo-bucket", 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" } } } });

開發 L2 建構的逃生艙

如果 L2 建構缺少特徵,或您嘗試解決某個問題,您可以修改L12 建構封裝的 L2 建構。

所有 L2 建構都包含對應的 L1 建構。例如,高階Bucket建構會包裝低階CfnBucket建構。由於 直接CfnBucket對應至 AWS CloudFormation 資源,因此會公開可透過 提供的所有功能 AWS CloudFormation。

存取 L1 建構的基本方法是使用 construct.node.defaultChild(Python:default_child),將其轉換為正確的類型 (如有必要),然後修改其屬性。同樣地,讓我們以 為例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 CloudFormation 選項,例如 MetadataUpdatePolicy

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 也提供提升抽象層級的功能,我們可能會將其稱為「取消逸出」艙門。如果您有 L1 建構,例如 CfnBucket,您可以建立新的 L2 建構 (Bucket 在此情況下) 來包裝 L1 建構。

當您建立 L1 資源,但想要將其與需要 L2 資源的建構搭配使用時,這很方便。當您想要使用 L1 建構上無法使用的便利方法.grantXxxxx()時,這也很有幫助。

您在名為 的 L2 類別上使用靜態方法移至較高的抽象層級.fromCfnXxxxx(),例如,Bucket.fromCfnBucket()針對 Amazon S3 儲存貯體。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 建構是參考 L1 資源的代理物件,類似於從資源名稱ARNs、 或 查詢建立的物件。這些建構的修改不會影響最終合成 AWS CloudFormation 範本 (因為您擁有 L1 資源,但您可以修改該範本)。如需代理物件的詳細資訊,請參閱 參考 AWS 帳戶中的資源

為避免混淆,請勿建立多個參考相同 L2 建構的 L12 建構。例如,如果您Bucket使用上一節中的技術CfnBucket從 中擷取 ,則不應Bucket.fromCfnBucket()透過使用該 呼叫來建立第二個Bucket執行個體CfnBucket開發 L2 建構的逃生艙它實際上如您預期般運作 (只會AWS::S3::Bucket合成一個),但會讓您的程式碼更難以維護。

使用原始覆寫

如果 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");

使用自訂資源

如果此功能無法透過 使用 AWS CloudFormation,但只能透過直接API通話使用,您必須撰寫 AWS CloudFormation 自訂資源以撥打所需的API通話。您可以使用 AWS CDK 撰寫自訂資源,並將其包裝到一般建構介面中。從建構的取用者角度來看,體驗會感到原生。

建置自訂資源涉及撰寫 Lambda 函數,以回應資源的 CREATEUPDATEDELETE生命週期事件。如果您的自訂資源只需要進行單一API呼叫,請考慮使用 AwsCustomResource。這可讓您在 AWS CloudFormation 部署期間執行任意SDK呼叫。否則,您應該撰寫自己的 Lambda 函數,以執行您需要完成的工作。

主題太廣泛,無法完全涵蓋此處,但以下連結應該會讓您開始: