這是 AWS CDK v2 開發人員指南。較舊的 CDK 第 1 版已於 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, '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"
}
}
}
});
開發 L2 結構的逃生艙口
如果 L2 建構遺失特徵,或者您嘗試解決問題,您可以修改由 L2 建構封裝的 L1 建構。
所有 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()
例如 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 建構是參考 L1 資源的 Proxy 物件,類似於從資源名稱、ARN 或查詢建立的物件。對這些結構的修改不會影響最終的合成 AWS CloudFormation
模板(因為您有 L1 資源,但是,您可以改為修改它)。如需代理物件的更多資訊,請參閱參考您 AWS 帳戶中的資源。
為避免混淆,請勿建立多個參考相同 L1 建構的 L2 建構。例如,如果您CfnBucket
從上一節中的 using 技術中提取,則不應通過調Bucket
Bucket.fromCfnBucket()
用該Bucket
實例來創建第二個實例CfnBucket
。它實際上按照您的期望工作(只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 函數來執行完成所需的工作。
主題太廣泛了,無法完全涵蓋在這裡,但是以下鏈接應該可以幫助您開始: