這是 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
,例如 CfnBucket
或 CfnRole
。您可以像使用對等 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 選項,例如 Metadata
和 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 也提供提升抽象層級的功能,我們可能會將其稱為「取消逸出」艙門。如果您有 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 函數,以回應資源的 CREATE
、 UPDATE
和DELETE
生命週期事件。如果您的自訂資源只需要進行單一API呼叫,請考慮使用 AwsCustomResource。這可讓您在 AWS CloudFormation 部署期間執行任意SDK呼叫。否則,您應該撰寫自己的 Lambda 函數,以執行您需要完成的工作。
主題太廣泛,無法完全涵蓋此處,但以下連結應該會讓您開始: