資源和 AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

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

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

資源和 AWS CDK

資源是您設定為 AWS 服務 在應用程式中使用的資源。資源是 的一項功能 AWS CloudFormation。透過在 AWS CloudFormation 範本中設定資源及其屬性,您可以部署 AWS CloudFormation 以佈建資源。使用 AWS Cloud Development Kit (AWS CDK),您可以透過建構設定資源。然後,您可以部署CDK應用程式,其中包含合成 AWS CloudFormation 範本和部署 AWS CloudFormation 以佈建 資源。

使用 constructs 設定資源

如 中所述AWS CDK 建構, AWS CDK 提供豐富的建構類別程式庫,稱為AWS 建構 ,代表所有 AWS 資源。

若要使用其對應的建構建立資源執行個體,請在 範圍內傳遞為第一個引數、建構的邏輯 ID 和一組組態屬性 (props)。例如,以下說明如何使用 AWS Construct Library 中的 sqs.Queue construct SQS建立具有 AWS KMS 加密的 Amazon 佇列。 https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_sqs.Queue.html

TypeScript
import * as sqs from '@aws-cdk/aws-sqs'; new sqs.Queue(this, 'MyQueue', { encryption: sqs.QueueEncryption.KMS_MANAGED });
JavaScript
const sqs = require('@aws-cdk/aws-sqs'); new sqs.Queue(this, 'MyQueue', { encryption: sqs.QueueEncryption.KMS_MANAGED });
Python
import aws_cdk.aws_sqs as sqs sqs.Queue(self, "MyQueue", encryption=sqs.QueueEncryption.KMS_MANAGED)
Java
import software.amazon.awscdk.services.sqs.*; Queue.Builder.create(this, "MyQueue").encryption( QueueEncryption.KMS_MANAGED).build();
C#
using Amazon.CDK.AWS.SQS; new Queue(this, "MyQueue", new QueueProps { Encryption = QueueEncryption.KMS_MANAGED });
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" ) sqs.NewQueue(stack, jsii.String("MyQueue"), &sqs.QueueProps{ Encryption: sqs.QueueEncryption_KMS_MANAGED, })

有些組態道具是選用的,而且在許多情況下都有預設值。在某些情況下,所有道具都是選用的,而且可以完全省略最後一個引數。

資源屬性

AWS Construct Library 中的大多數資源都會公開屬性,這些屬性會在部署時間由 解析 AWS CloudFormation。屬性會以 資源類別上的屬性形式公開,並將類型名稱作為字首。下列範例示範如何使用 queueUrl(Python:queue_url) 屬性取得 Amazon SQS佇列URL的 。

TypeScript
import * as sqs from '@aws-cdk/aws-sqs'; const queue = new sqs.Queue(this, 'MyQueue'); const url = queue.queueUrl; // => A string representing a deploy-time value
JavaScript
const sqs = require('@aws-cdk/aws-sqs'); const queue = new sqs.Queue(this, 'MyQueue'); const url = queue.queueUrl; // => A string representing a deploy-time value
Python
import aws_cdk.aws_sqs as sqs queue = sqs.Queue(self, "MyQueue") url = queue.queue_url # => A string representing a deploy-time value
Java
Queue queue = new Queue(this, "MyQueue"); String url = queue.getQueueUrl(); // => A string representing a deploy-time value
C#
var queue = new Queue(this, "MyQueue"); var url = queue.QueueUrl; // => A string representing a deploy-time value
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" ) queue := sqs.NewQueue(stack, jsii.String("MyQueue"), &sqs.QueueProps{}) url := queue.QueueUrl() // => A string representing a deploy-time value

如需 如何將部署時間屬性 AWS CDK 編碼為字串的資訊,權杖和 AWS CDK請參閱 。

參考資源

設定資源時,您通常必須參考其他資源的屬性。範例如下:

  • Amazon Elastic Container Service (Amazon ECS) 資源需要其執行所在叢集的參考。

  • Amazon CloudFront 分佈需要參考包含原始程式碼的 Amazon Simple Storage Service (Amazon S3) 儲存貯體。

您可以使用下列任何方式參考資源:

  • 透過傳遞CDK應用程式中定義的資源,無論是在相同的堆疊中還是在不同的堆疊中

  • 透過傳遞參考您 AWS 帳戶中定義的資源的代理物件,該物件是從資源的唯一識別符 (例如 ARN) 建立的

如果建構的 屬性代表另一個資源的建構,則其類型是建構的介面類型。例如,Amazon ECS 建構會使用類型 cluster的屬性ecs.ICluster。另一個範例是採用類型 之 屬性 sourceBucket(Python:source_bucket) 的 CloudFront 分佈建構s3.IBucket

您可以直接傳遞相同 AWS CDK 應用程式中定義之適當類型的任何資源物件。下列範例會定義 Amazon ECS叢集,然後使用它來定義 Amazon ECS服務。

TypeScript
const cluster = new ecs.Cluster(this, 'Cluster', { /*...*/ }); const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster });
JavaScript
const cluster = new ecs.Cluster(this, 'Cluster', { /*...*/ }); const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster });
Python
cluster = ecs.Cluster(self, "Cluster") service = ecs.Ec2Service(self, "Service", cluster=cluster)
Java
Cluster cluster = new Cluster(this, "Cluster"); Ec2Service service = new Ec2Service(this, "Service", new Ec2ServiceProps.Builder().cluster(cluster).build());
C#
var cluster = new Cluster(this, "Cluster"); var service = new Ec2Service(this, "Service", new Ec2ServiceProps { Cluster = cluster });
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" ecs "github.com/aws/aws-cdk-go/awscdk/v2/awsecs" ) cluster := ecs.NewCluster(stack, jsii.String("MyCluster"), &ecs.ClusterProps{}) service := ecs.NewEc2Service(stack, jsii.String("MyService"), &ecs.Ec2ServiceProps{ Cluster: cluster, })

參考不同堆疊中的資源

您可以參考不同堆疊中的資源,只要它們是在相同的應用程式中定義的,並且位於相同的 AWS 環境中即可。通常會使用以下模式:

  • 將 建構的參考儲存為產生 資源之堆疊的屬性。(若要取得目前建構的堆疊參考,請使用 Stack.of(this)。)

  • 將此參考傳遞給使用資源作為參數或 屬性的堆疊建構者。然後,耗用堆疊會將其作為屬性傳遞給任何需要它的建構。

下列範例定義堆疊 stack1。此堆疊會定義 Amazon S3 儲存貯體,並將對儲存貯體建構的參考儲存為堆疊的屬性。然後,應用程式會定義第二個堆疊 stack2,它在初始化時接受儲存貯體。 stack2可能會例如定義使用儲存貯體進行資料儲存的 AWS Glue 資料表。

TypeScript
const prod = { account: '123456789012', region: 'us-east-1' }; const stack1 = new StackThatProvidesABucket(app, 'Stack1', { env: prod }); // stack2 will take a property { bucket: IBucket } const stack2 = new StackThatExpectsABucket(app, 'Stack2', { bucket: stack1.bucket, env: prod });
JavaScript
const prod = { account: '123456789012', region: 'us-east-1' }; const stack1 = new StackThatProvidesABucket(app, 'Stack1', { env: prod }); // stack2 will take a property { bucket: IBucket } const stack2 = new StackThatExpectsABucket(app, 'Stack2', { bucket: stack1.bucket, env: prod });
Python
prod = core.Environment(account="123456789012", region="us-east-1") stack1 = StackThatProvidesABucket(app, "Stack1", env=prod) # stack2 will take a property "bucket" stack2 = StackThatExpectsABucket(app, "Stack2", bucket=stack1.bucket, env=prod)
Java
// Helper method to build an environment static Environment makeEnv(String account, String region) { return Environment.builder().account(account).region(region) .build(); } App app = new App(); Environment prod = makeEnv("123456789012", "us-east-1"); StackThatProvidesABucket stack1 = new StackThatProvidesABucket(app, "Stack1", StackProps.builder().env(prod).build()); // stack2 will take an argument "bucket" StackThatExpectsABucket stack2 = new StackThatExpectsABucket(app, "Stack,", StackProps.builder().env(prod).build(), stack1.bucket);
C#
Amazon.CDK.Environment makeEnv(string account, string region) { return new Amazon.CDK.Environment { Account = account, Region = region }; } var prod = makeEnv(account: "123456789012", region: "us-east-1"); var stack1 = new StackThatProvidesABucket(app, "Stack1", new StackProps { Env = prod }); // stack2 will take a property "bucket" var stack2 = new StackThatExpectsABucket(app, "Stack2", new StackProps { Env = prod, bucket = stack1.Bucket});

如果 AWS CDK 確定資源位於相同環境,但在不同的堆疊中,則會自動合成生產堆疊中的 AWS CloudFormation 匯出,以及在耗用堆疊中 Fn::ImportValue,將該資訊從一個堆疊傳輸到另一個堆疊。

解決相依性鎖死

從不同堆疊中的一個堆疊參考資源,會在兩個堆疊之間建立相依性。這可確保以正確的順序部署它們。部署堆疊後,此相依性為具體的。之後,從耗用堆疊中移除共用資源的使用可能會導致非預期的部署失敗。如果兩個堆疊之間存在另一個相依性,而強制它們以相同的順序部署,則會發生這種情況。如果 CDK Toolkit 僅選擇要先部署的產生堆疊,也可能在沒有相依性的情況下發生這種情況。匯出 AWS CloudFormation 會從生產堆疊中移除,因為不再需要,但匯出的資源仍在耗用堆疊中使用,因為其更新尚未部署。因此,部署生產者堆疊失敗。

若要破壞此死結,請從耗用堆疊中移除共用資源的使用。(這會從生產堆疊中移除自動匯出。) 接下來,使用與自動產生的匯出完全相同的邏輯 ID,將相同的匯出手動新增至生產堆疊。移除耗用堆疊中共用資源的使用,並部署兩個堆疊。然後,移除手動匯出 (以及不再需要的共用資源),然後再次部署這兩個堆疊。堆疊exportValue()的方法是為此目的建立手動匯出的便利方法。(請參閱連結方法參考中的範例。)

參考 AWS 帳戶中的資源

假設您想要使用 AWS CDK 應用程式中 AWS 帳戶中已有的資源。這可能是透過主控台、 AWS SDK、直接使用 AWS CloudFormation或不同 AWS CDK 應用程式中定義的資源。您可以將資源的 ARN(或其他識別屬性或屬性群組) 轉換為代理物件。代理物件透過呼叫資源類別上的靜態工廠方法,做為資源的參考。

當您建立這類代理時,外部資源不會成為您 AWS CDK 應用程式的一部分。因此,您對 AWS CDK 應用程式中代理所做的變更不會影響部署的資源。不過,代理可以傳遞到需要該類型資源的任何 AWS CDK 方法。

下列範例示範如何根據具有 ARN arn:aws:s3::amzn-s3-demo-bucket1 的現有儲存貯體,以及根據VPC具有特定 ID 的現有 Amazon Virtual Private Cloud 來參考儲存貯體。

TypeScript
// Construct a proxy for a bucket by its name (must be same account) s3.Bucket.fromBucketName(this, 'amzn-s3-demo-bucket', 'amzn-s3-demo-bucket1'); // Construct a proxy for a bucket by its full ARN (can be another account) s3.Bucket.fromBucketArn(this, 'amzn-s3-demo-bucket', 'arn:aws:s3:::amzn-s3-demo-bucket1'); // Construct a proxy for an existing VPC from its attribute(s) ec2.Vpc.fromVpcAttributes(this, 'MyVpc', { vpcId: 'vpc-1234567890abcde', });
JavaScript
// Construct a proxy for a bucket by its name (must be same account) s3.Bucket.fromBucketName(this, 'amzn-s3-demo-bucket', 'amzn-s3-demo-bucket1'); // Construct a proxy for a bucket by its full ARN (can be another account) s3.Bucket.fromBucketArn(this, 'amzn-s3-demo-bucket', 'arn:aws:s3:::amzn-s3-demo-bucket1'); // Construct a proxy for an existing VPC from its attribute(s) ec2.Vpc.fromVpcAttributes(this, 'MyVpc', { vpcId: 'vpc-1234567890abcde' });
Python
# Construct a proxy for a bucket by its name (must be same account) s3.Bucket.from_bucket_name(self, "amzn-s3-demo-bucket", "amzn-s3-demo-bucket1") # Construct a proxy for a bucket by its full ARN (can be another account) s3.Bucket.from_bucket_arn(self, "amzn-s3-demo-bucket", "arn:aws:s3:::amzn-s3-demo-bucket1") # Construct a proxy for an existing VPC from its attribute(s) ec2.Vpc.from_vpc_attributes(self, "MyVpc", vpc_id="vpc-1234567890abcdef")
Java
// Construct a proxy for a bucket by its name (must be same account) Bucket.fromBucketName(this, "amzn-s3-demo-bucket", "amzn-s3-demo-bucket1"); // Construct a proxy for a bucket by its full ARN (can be another account) Bucket.fromBucketArn(this, "amzn-s3-demo-bucket", "arn:aws:s3:::amzn-s3-demo-bucket1"); // Construct a proxy for an existing VPC from its attribute(s) Vpc.fromVpcAttributes(this, "MyVpc", VpcAttributes.builder() .vpcId("vpc-1234567890abcdef").build());
C#
// Construct a proxy for a bucket by its name (must be same account) Bucket.FromBucketName(this, "amzn-s3-demo-bucket", "amzn-s3-demo-bucket1"); // Construct a proxy for a bucket by its full ARN (can be another account) Bucket.FromBucketArn(this, "amzn-s3-demo-bucket", "arn:aws:s3:::amzn-s3-demo-bucket1"); // Construct a proxy for an existing VPC from its attribute(s) Vpc.FromVpcAttributes(this, "MyVpc", new VpcAttributes { VpcId = "vpc-1234567890abcdef" });
Go
// Define a proxy for a bucket by its name (must be same account) s3.Bucket_FromBucketName(stack, jsii.String("amzn-s3-demo-bucket"), jsii.String("amzn-s3-demo-bucket1")) // Define a proxy for a bucket by its full ARN (can be another account) s3.Bucket_FromBucketArn(stack, jsii.String("amzn-s3-demo-bucket"), jsii.String("arn:aws:s3:::amzn-s3-demo-bucket1")) // Define a proxy for an existing VPC from its attributes ec2.Vpc_FromVpcAttributes(stack, jsii.String("MyVpc"), &ec2.VpcAttributes{ VpcId: jsii.String("vpc-1234567890abcde"), })

讓我們仔細看看 Vpc.fromLookup()方法。由於 建構很複雜,您可能想透過多種方式選擇要與CDK應用程式VPC搭配使用的 ec2.Vpc 。為了解決此問題,該建構具有fromLookup靜態方法 VPC (Python:from_lookup),可讓您VPC在合成時查詢 AWS 您的帳戶,以查詢所需的 Amazon。

若要使用 Vpc.fromLookup(),合成堆疊的系統必須能夠存取擁有 Amazon 的帳戶VPC。這是因為 CDK Toolkit 會在VPC合成時查詢 帳戶以尋找正確的 Amazon。

此外, Vpc.fromLookup() 僅適用於使用明確帳戶區域定義的堆疊 (請參閱 適用的環境 AWS CDK)。如果 AWS CDK 嘗試VPC從不區分環境的堆疊 中查詢 Amazon,CDK則 Toolkit 不知道要查詢哪個環境來尋找 VPC。

您必須提供足以唯一識別帳戶中 AWS VPC的Vpc.fromLookup()屬性。例如,只能有一個預設 VPC,因此將 指定VPC為預設值就足夠了。

TypeScript
ec2.Vpc.fromLookup(this, 'DefaultVpc', { isDefault: true });
JavaScript
ec2.Vpc.fromLookup(this, 'DefaultVpc', { isDefault: true });
Python
ec2.Vpc.from_lookup(self, "DefaultVpc", is_default=True)
Java
Vpc.fromLookup(this, "DefaultVpc", VpcLookupOptions.builder() .isDefault(true).build());
C#
Vpc.FromLookup(this, id = "DefaultVpc", new VpcLookupOptions { IsDefault = true });
Go
ec2.Vpc_FromLookup(this, jsii.String("DefaultVpc"), &ec2.VpcLookupOptions{ IsDefault: jsii.Bool(true), })

您也可以使用 tags 屬性依VPCs標籤查詢 。您可以在建立標籤VPC時,使用 AWS CloudFormation 或 將標籤新增至 Amazon AWS CDK。您可以在建立後隨時使用 AWS Management Console、 AWS CLI或 來編輯標籤 AWS SDK。除了您自行新增的任何標籤之外, AWS CDK 也會自動將下列標籤新增至VPCs其建立的所有標籤。

  • 名稱 – 的名稱VPC。

  • aws-cdk:subnet-name – 子網路的名稱。

  • aws-cdk:subnet-type – 子網路類型:公有、私有或隔離。

TypeScript
ec2.Vpc.fromLookup(this, 'PublicVpc', {tags: {'aws-cdk:subnet-type': "Public"}});
JavaScript
ec2.Vpc.fromLookup(this, 'PublicVpc', {tags: {'aws-cdk:subnet-type': "Public"}});
Python
ec2.Vpc.from_lookup(self, "PublicVpc", tags={"aws-cdk:subnet-type": "Public"})
Java
Vpc.fromLookup(this, "PublicVpc", VpcLookupOptions.builder() .tags(java.util.Map.of("aws-cdk:subnet-type", "Public")) // Java 9 or later .build());
C#
Vpc.FromLookup(this, id = "PublicVpc", new VpcLookupOptions { Tags = new Dictionary<string, string> { ["aws-cdk:subnet-type"] = "Public" });
Go
ec2.Vpc_FromLookup(this, jsii.String("DefaultVpc"), &ec2.VpcLookupOptions{ Tags: &map[string]*string{"aws-cdk:subnet-type": jsii.String("Public")}, })

的結果會Vpc.fromLookup()快取在專案的cdk.context.json檔案中。(請參閱 上下文值和 AWS CDK)。將此檔案遞交至版本控制,以便您的應用程式繼續參考相同的 Amazon VPC。即使您稍後VPCs以會導致VPC選取不同 的方式變更 的屬性,這仍然有效。如果您在無法存取定義 之 AWS 帳戶的環境中部署堆疊,例如CDK管道 VPC,這一點尤其重要。

雖然您可以在任何要使用 AWS CDK 應用程式中定義之類似資源的地方使用外部資源,但您無法修改它。例如,在外部呼叫 addToResourcePolicy(Python:add_to_resource_policy) 不會進行任何s3.Bucket動作。

資源實體名稱

中的資源邏輯名稱與 進行部署後顯示 AWS Management Console 的資源名稱 AWS CloudFormation 不同 AWS CloudFormation。 AWS CDK 會呼叫這些最終名稱實體名稱

例如, AWS CloudFormation 可能會使用實體名稱 的邏輯 ID Stack2amzn-s3-demo-bucket4DD88B4F 建立 Amazon S3 儲存貯體stack2amzn-s3-demo-bucket4dd88b4f-iuv1rbv9z3to

您可以在建立代表資源的建構時,使用 屬性指定實體名稱 <resourceType>名稱。下列範例會建立實體名稱為 的 Amazon S3 儲存貯體amzn-s3-demo-bucket

TypeScript
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', { bucketName: 'amzn-s3-demo-bucket', });
JavaScript
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', { bucketName: 'amzn-s3-demo-bucket' });
Python
bucket = s3.Bucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket")
Java
Bucket bucket = Bucket.Builder.create(this, "amzn-s3-demo-bucket") .bucketName("amzn-s3-demo-bucket").build();
C#
var bucket = new Bucket(this, "amzn-s3-demo-bucket", new BucketProps { BucketName = "amzn-s3-demo-bucket" });
Go
bucket := s3.NewBucket(this, jsii.String("amzn-s3-demo-bucket"), &s3.BucketProps{ BucketName: jsii.String("amzn-s3-demo-bucket"), })

將實體名稱指派給資源在 中有一些缺點 AWS CloudFormation。最重要的是,如果資源已指派實體名稱,則任何需要資源取代的已部署資源變更,例如建立後無法變更的資源屬性變更,都會失敗。如果您最終處於該狀態,唯一的解決方案是刪除 AWS CloudFormation 堆疊,然後再次部署 AWS CDK 應用程式。如需詳細資訊,請參閱 AWS CloudFormation 文件

在某些情況下,例如在建立具有跨環境參考 AWS CDK 的應用程式時, 需要實體名稱 AWS CDK 才能正確運作。在這些情況下,如果您不想自己提出實體名稱,可以讓 AWS CDK 名稱為您命名。若要這麼做,請使用特殊值 PhysicalName.GENERATE_IF_NEEDED,如下所示。

TypeScript
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', { bucketName: core.PhysicalName.GENERATE_IF_NEEDED, });
JavaScript
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', { bucketName: core.PhysicalName.GENERATE_IF_NEEDED });
Python
bucket = s3.Bucket(self, "amzn-s3-demo-bucket", bucket_name=core.PhysicalName.GENERATE_IF_NEEDED)
Java
Bucket bucket = Bucket.Builder.create(this, "amzn-s3-demo-bucket") .bucketName(PhysicalName.GENERATE_IF_NEEDED).build();
C#
var bucket = new Bucket(this, "amzn-s3-demo-bucket", new BucketProps { BucketName = PhysicalName.GENERATE_IF_NEEDED });
Go
bucket := s3.NewBucket(this, jsii.String("amzn-s3-demo-bucket"), &s3.BucketProps{ BucketName: awscdk.PhysicalName_GENERATE_IF_NEEDED(), })

傳遞唯一的資源識別符

盡可能透過參考傳遞資源,如上一節所述。不過,在某些情況下,您無法選擇其他選項,而是透過其中一個屬性來參考資源。範例使用案例包括下列項目:

  • 當您使用低階 AWS CloudFormation 資源時。

  • 當您需要將資源公開至 AWS CDK 應用程式的執行期元件時,例如透過環境變數參考 Lambda 函數時。

這些識別碼可作為 資源上的屬性,例如下列項目。

TypeScript
bucket.bucketName lambdaFunc.functionArn securityGroup.groupArn
JavaScript
bucket.bucketName lambdaFunc.functionArn securityGroup.groupArn
Python
bucket.bucket_name lambda_func.function_arn security_group_arn
Java

Java AWS CDK 繫結使用屬性的 getter 方法。

bucket.getBucketName() lambdaFunc.getFunctionArn() securityGroup.getGroupArn()
C#
bucket.BucketName lambdaFunc.FunctionArn securityGroup.GroupArn
Go
bucket.BucketName() fn.FunctionArn()

下列範例示範如何將產生的儲存貯體名稱傳遞至 AWS Lambda 函數。

TypeScript
const bucket = new s3.Bucket(this, 'Bucket'); new lambda.Function(this, 'MyLambda', { // ... environment: { BUCKET_NAME: bucket.bucketName, }, });
JavaScript
const bucket = new s3.Bucket(this, 'Bucket'); new lambda.Function(this, 'MyLambda', { // ... environment: { BUCKET_NAME: bucket.bucketName } });
Python
bucket = s3.Bucket(self, "Bucket") lambda.Function(self, "MyLambda", environment=dict(BUCKET_NAME=bucket.bucket_name))
Java
final Bucket bucket = new Bucket(this, "Bucket"); Function.Builder.create(this, "MyLambda") .environment(java.util.Map.of( // Java 9 or later "BUCKET_NAME", bucket.getBucketName())) .build();
C#
var bucket = new Bucket(this, "Bucket"); new Function(this, "MyLambda", new FunctionProps { Environment = new Dictionary<string, string> { ["BUCKET_NAME"] = bucket.BucketName } });
Go
bucket := s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{}) lambda.NewFunction(this, jsii.String("MyLambda"), &lambda.FunctionProps{ Environment: &map[string]*string{"BUCKET_NAME": bucket.BucketName()}, })

在資源之間授予許可

更高層級的建構提供簡單、以意圖為基礎的APIs表達許可要求,讓最低權限許可得以實現。例如,許多 L2 建構提供授予方法,您可以用來授予實體 (例如IAM角色或使用者) 使用 資源的許可,而不必手動建立IAM許可陳述式。

下列範例會建立許可,以允許 Lambda 函數的執行角色讀取和寫入物件至特定 Amazon S3 儲存貯體。如果 Amazon S3 儲存貯體使用 AWS KMS 金鑰加密,此方法也會授予 Lambda 函數執行角色許可,以使用金鑰解密。

TypeScript
if (bucket.grantReadWrite(func).success) { // ... }
JavaScript
if ( bucket.grantReadWrite(func).success) { // ... }
Python
if bucket.grant_read_write(func).success: # ...
Java
if (bucket.grantReadWrite(func).getSuccess()) { // ... }
C#
if (bucket.GrantReadWrite(func).Success) { // ... }
Go
if *bucket.GrantReadWrite(function, nil).Success() { // ... }

授予方法會傳回iam.Grant物件。使用 Grant 物件的success屬性來判斷授予是否有效套用 (例如,它可能尚未套用到外部資源 )。您也可以使用 Grant 物件的 assertSuccess(Python:assert_success) 方法強制執行授予已成功套用。

如果特定授予方法不適用於特定使用案例,您可以使用一般授予方法定義具有指定動作清單的新授予。

下列範例顯示如何授予 Lambda 函數對 Amazon DynamoDB CreateBackup動作的存取權。

TypeScript
table.grant(func, 'dynamodb:CreateBackup');
JavaScript
table.grant(func, 'dynamodb:CreateBackup');
Python
table.grant(func, "dynamodb:CreateBackup")
Java
table.grant(func, "dynamodb:CreateBackup");
C#
table.Grant(func, "dynamodb:CreateBackup");
Go
table := dynamodb.NewTable(this, jsii.String("MyTable"), &dynamodb.TableProps{}) table.Grant(function, jsii.String("dynamodb:CreateBackup"))

許多資源,例如 Lambda 函數,都需要在執行程式碼時擔任角色。組態屬性可讓您指定 iam.IRole。如果未指定角色,則函數會自動建立專門用於此用途的角色。然後,您可以在 資源上使用授予方法,將陳述式新增至角色。

授予方法使用較低層級來建置APIs,以使用 IAM 政策來處理。政策會建模為PolicyDocument物件。使用 addToRolePolicy 方法 (Python:) 將陳述式直接新增至角色 (或建構的連接角色add_to_role_policy),或使用 (Python:) 方法將陳述式新增至資源的政策 addToResourcePolicy(例如Bucket政策add_to_resource_policy)。

資源指標和警示

許多資源發出指標 CloudWatch ,可用來設定監控儀表板和警示。更高層級的建構具有指標方法,可讓您存取指標,而無需查詢要使用的正確名稱。

下列範例顯示如何在 Amazon SQS佇列ApproximateNumberOfMessagesNotVisible的 超過 100 時定義警示。

TypeScript
import * as cw from '@aws-cdk/aws-cloudwatch'; import * as sqs from '@aws-cdk/aws-sqs'; import { Duration } from '@aws-cdk/core'; const queue = new sqs.Queue(this, 'MyQueue'); const metric = queue.metricApproximateNumberOfMessagesNotVisible({ label: 'Messages Visible (Approx)', period: Duration.minutes(5), // ... }); metric.createAlarm(this, 'TooManyMessagesAlarm', { comparisonOperator: cw.ComparisonOperator.GREATER_THAN_THRESHOLD, threshold: 100, // ... });
JavaScript
const cw = require('@aws-cdk/aws-cloudwatch'); const sqs = require('@aws-cdk/aws-sqs'); const { Duration } = require('@aws-cdk/core'); const queue = new sqs.Queue(this, 'MyQueue'); const metric = queue.metricApproximateNumberOfMessagesNotVisible({ label: 'Messages Visible (Approx)', period: Duration.minutes(5) // ... }); metric.createAlarm(this, 'TooManyMessagesAlarm', { comparisonOperator: cw.ComparisonOperator.GREATER_THAN_THRESHOLD, threshold: 100 // ... });
Python
import aws_cdk.aws_cloudwatch as cw import aws_cdk.aws_sqs as sqs from aws_cdk.core import Duration queue = sqs.Queue(self, "MyQueue") metric = queue.metric_approximate_number_of_messages_not_visible( label="Messages Visible (Approx)", period=Duration.minutes(5), # ... ) metric.create_alarm(self, "TooManyMessagesAlarm", comparison_operator=cw.ComparisonOperator.GREATER_THAN_THRESHOLD, threshold=100, # ... )
Java
import software.amazon.awscdk.core.Duration; import software.amazon.awscdk.services.sqs.Queue; import software.amazon.awscdk.services.cloudwatch.Metric; import software.amazon.awscdk.services.cloudwatch.MetricOptions; import software.amazon.awscdk.services.cloudwatch.CreateAlarmOptions; import software.amazon.awscdk.services.cloudwatch.ComparisonOperator; Queue queue = new Queue(this, "MyQueue"); Metric metric = queue .metricApproximateNumberOfMessagesNotVisible(MetricOptions.builder() .label("Messages Visible (Approx)") .period(Duration.minutes(5)).build()); metric.createAlarm(this, "TooManyMessagesAlarm", CreateAlarmOptions.builder() .comparisonOperator(ComparisonOperator.GREATER_THAN_THRESHOLD) .threshold(100) // ... .build());
C#
using cdk = Amazon.CDK; using cw = Amazon.CDK.AWS.CloudWatch; using sqs = Amazon.CDK.AWS.SQS; var queue = new sqs.Queue(this, "MyQueue"); var metric = queue.MetricApproximateNumberOfMessagesNotVisible(new cw.MetricOptions { Label = "Messages Visible (Approx)", Period = cdk.Duration.Minutes(5), // ... }); metric.CreateAlarm(this, "TooManyMessagesAlarm", new cw.CreateAlarmOptions { ComparisonOperator = cw.ComparisonOperator.GREATER_THAN_THRESHOLD, Threshold = 100, // .. });
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" cw "github.com/aws/aws-cdk-go/awscdk/v2/awscloudwatch" sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" ) queue := sqs.NewQueue(this, jsii.String("MyQueue"), &sqs.QueueProps{}) metric := queue.MetricApproximateNumberOfMessagesNotVisible(&cw.MetricOptions{ Label: jsii.String("Messages Visible (Approx)"), Period: awscdk.Duration_Minutes(jsii.Number(5)), }) metric.CreateAlarm(this, jsii.String("TooManyMessagesAlarm"), &cw.CreateAlarmOptions{ ComparisonOperator: cw.ComparisonOperator_GREATER_THAN_THRESHOLD, Threshold: jsii.Number(100), })

如果沒有特定指標的方法,您可以使用一般指標方法手動指定指標名稱。

指標也可以新增至 CloudWatch 儀表板。請參閱 CloudWatch

網路流量

在許多情況下,您必須在網路上啟用許可,應用程式才能運作,例如運算基礎設施需要存取持久性層時。建立或接聽連線的資源會公開啟用流量流程的方法,包括設定安全群組規則或網路 ACLs。

IConnectable 資源的 connections 屬性是網路流量規則組態的閘道。

您可以使用 allow方法讓資料在指定的網路路徑上流動。下列範例會啟用與 Web 的HTTPS連線,以及來自 Amazon EC2 Auto Scaling 群組 的傳入連線fleet2

TypeScript
import * as asg from '@aws-cdk/aws-autoscaling'; import * as ec2 from '@aws-cdk/aws-ec2'; const fleet1: asg.AutoScalingGroup = asg.AutoScalingGroup(/*...*/); // Allow surfing the (secure) web fleet1.connections.allowTo(new ec2.Peer.anyIpv4(), new ec2.Port({ fromPort: 443, toPort: 443 })); const fleet2: asg.AutoScalingGroup = asg.AutoScalingGroup(/*...*/); fleet1.connections.allowFrom(fleet2, ec2.Port.AllTraffic());
JavaScript
const asg = require('@aws-cdk/aws-autoscaling'); const ec2 = require('@aws-cdk/aws-ec2'); const fleet1 = asg.AutoScalingGroup(); // Allow surfing the (secure) web fleet1.connections.allowTo(new ec2.Peer.anyIpv4(), new ec2.Port({ fromPort: 443, toPort: 443 })); const fleet2 = asg.AutoScalingGroup(); fleet1.connections.allowFrom(fleet2, ec2.Port.AllTraffic());
Python
import aws_cdk.aws_autoscaling as asg import aws_cdk.aws_ec2 as ec2 fleet1 = asg.AutoScalingGroup( ... ) # Allow surfing the (secure) web fleet1.connections.allow_to(ec2.Peer.any_ipv4(), ec2.Port(PortProps(from_port=443, to_port=443))) fleet2 = asg.AutoScalingGroup( ... ) fleet1.connections.allow_from(fleet2, ec2.Port.all_traffic())
Java
import software.amazon.awscdk.services.autoscaling.AutoScalingGroup; import software.amazon.awscdk.services.ec2.Peer; import software.amazon.awscdk.services.ec2.Port; AutoScalingGroup fleet1 = AutoScalingGroup.Builder.create(this, "MyFleet") /* ... */.build(); // Allow surfing the (secure) Web fleet1.getConnections().allowTo(Peer.anyIpv4(), Port.Builder.create().fromPort(443).toPort(443).build()); AutoScalingGroup fleet2 = AutoScalingGroup.Builder.create(this, "MyFleet2") /* ... */.build(); fleet1.getConnections().allowFrom(fleet2, Port.allTraffic());
C#
using cdk = Amazon.CDK; using asg = Amazon.CDK.AWS.AutoScaling; using ec2 = Amazon.CDK.AWS.EC2; // Allow surfing the (secure) Web var fleet1 = new asg.AutoScalingGroup(this, "MyFleet", new asg.AutoScalingGroupProps { /* ... */ }); fleet1.Connections.AllowTo(ec2.Peer.AnyIpv4(), new ec2.Port(new ec2.PortProps { FromPort = 443, ToPort = 443 }); var fleet2 = new asg.AutoScalingGroup(this, "MyFleet2", new asg.AutoScalingGroupProps { /* ... */ }); fleet1.Connections.AllowFrom(fleet2, ec2.Port.AllTraffic());
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" autoscaling "github.com/aws/aws-cdk-go/awscdk/v2/awsautoscaling" ec2 "github.com/aws/aws-cdk-go/awscdk/v2/awsec2" ) fleet1 := autoscaling.NewAutoScalingGroup(this, jsii.String("MyFleet1"), &autoscaling.AutoScalingGroupProps{}) fleet1.Connections().AllowTo(ec2.Peer_AnyIpv4(),ec2.NewPort(&ec2.PortProps{ FromPort: jsii.Number(443), ToPort: jsii.Number(443) }),jsii.String("secure web")) fleet2 := autoscaling.NewAutoScalingGroup(this, jsii.String("MyFleet2"), &autoscaling.AutoScalingGroupProps{}) fleet1.Connections().AllowFrom(fleet2, ec2.Port_AllTraffic(),jsii.String("all traffic"))

某些資源具有與其相關聯的預設連接埠。範例包括公有連接埠上負載平衡器的接聽程式,以及資料庫引擎接受 Amazon RDS 資料庫執行個體連線的連接埠。在這種情況下,您可以強制執行嚴格的網路控制,而不必手動指定連接埠。若要這麼做,請使用 allowDefaultPortFromallowToDefaultPort方法 (Python:allow_default_port_fromallow_to_default_port)。

下列範例示範如何從任何IPV4地址啟用連線,以及從 Auto Scaling 群組啟用連線以存取資料庫。

TypeScript
listener.connections.allowDefaultPortFromAnyIpv4('Allow public access'); fleet.connections.allowToDefaultPort(rdsDatabase, 'Fleet can access database');
JavaScript
listener.connections.allowDefaultPortFromAnyIpv4('Allow public access'); fleet.connections.allowToDefaultPort(rdsDatabase, 'Fleet can access database');
Python
listener.connections.allow_default_port_from_any_ipv4("Allow public access") fleet.connections.allow_to_default_port(rds_database, "Fleet can access database")
Java
listener.getConnections().allowDefaultPortFromAnyIpv4("Allow public access"); fleet.getConnections().AllowToDefaultPort(rdsDatabase, "Fleet can access database");
C#
listener.Connections.AllowDefaultPortFromAnyIpv4("Allow public access"); fleet.Connections.AllowToDefaultPort(rdsDatabase, "Fleet can access database");
Go
listener.Connections().AllowDefaultPortFromAnyIpv4(jsii.String("Allow public Access")) fleet.Connections().AllowToDefaultPort(rdsDatabase, jsii.String("Fleet can access database"))

事件處理

有些資源可以作為事件來源。使用 addEventNotification方法 (Python:add_event_notification) 將事件目標註冊至 資源發出的特定事件類型。此外,addXxxNotification方法還提供一種簡單的方式來註冊常見事件類型的處理常式。

下列範例顯示如何在將物件新增至 Amazon S3 儲存貯體時觸發 Lambda 函數。

TypeScript
import * as s3nots from '@aws-cdk/aws-s3-notifications'; const handler = new lambda.Function(this, 'Handler', { /*…*/ }); const bucket = new s3.Bucket(this, 'Bucket'); bucket.addObjectCreatedNotification(new s3nots.LambdaDestination(handler));
JavaScript
const s3nots = require('@aws-cdk/aws-s3-notifications'); const handler = new lambda.Function(this, 'Handler', { /*…*/ }); const bucket = new s3.Bucket(this, 'Bucket'); bucket.addObjectCreatedNotification(new s3nots.LambdaDestination(handler));
Python
import aws_cdk.aws_s3_notifications as s3_nots handler = lambda_.Function(self, "Handler", ...) bucket = s3.Bucket(self, "Bucket") bucket.add_object_created_notification(s3_nots.LambdaDestination(handler))
Java
import software.amazon.awscdk.services.s3.Bucket; import software.amazon.awscdk.services.lambda.Function; import software.amazon.awscdk.services.s3.notifications.LambdaDestination; Function handler = Function.Builder.create(this, "Handler")/* ... */.build(); Bucket bucket = new Bucket(this, "Bucket"); bucket.addObjectCreatedNotification(new LambdaDestination(handler));
C#
using lambda = Amazon.CDK.AWS.Lambda; using s3 = Amazon.CDK.AWS.S3; using s3Nots = Amazon.CDK.AWS.S3.Notifications; var handler = new lambda.Function(this, "Handler", new lambda.FunctionProps { .. }); var bucket = new s3.Bucket(this, "Bucket"); bucket.AddObjectCreatedNotification(new s3Nots.LambdaDestination(handler));
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3" s3nots "github.com/aws/aws-cdk-go/awscdk/v2/awss3notifications" ) handler := lambda.NewFunction(this, jsii.String("MyFunction"), &lambda.FunctionProps{}) bucket := s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{}) bucket.AddObjectCreatedNotification(s3nots.NewLambdaDestination(handler), nil)

移除政策

維護持久性資料的資源,例如資料庫、Amazon S3 儲存貯體和 Amazon ECR 登錄檔,都有移除政策 。移除政策會指示在包含物件的堆疊遭到銷毀時 AWS CDK ,是否刪除持久性物件。指定移除政策的值可透過模組中的RemovalPolicy AWS CDK core列舉取得。

注意

除了持續存放資料的資源之外removalPolicy,也可能會有用於不同用途的 。例如,Lambda 函數版本使用 removalPolicy 屬性來判斷在部署新版本時是否保留指定版本。相較於 Amazon S3 儲存貯體或 DynamoDB 資料表上的移除政策,這些具有不同的意義和預設值。

Value 意義

RemovalPolicy.RETAIN

在銷毀堆疊時保留資源的內容 (預設)。資源從堆疊中孤立,必須手動刪除。如果您嘗試在資源仍然存在時重新部署堆疊,由於名稱衝突,您將收到錯誤訊息。

RemovalPolicy.DESTROY

資源將與堆疊一起銷毀。

AWS CloudFormation 不會移除包含檔案的 Amazon S3 儲存貯體,即使其移除政策設定為 DESTROY。嘗試這樣做是 AWS CloudFormation 錯誤。若要讓 先從儲存貯體 AWS CDK 刪除所有檔案,再銷毀,請將儲存貯體的 autoDeleteObjects 屬性設定為 true

以下是使用 建立 Amazon S3 儲存貯體RemovalPolicyDESTROYautoDeleteOjbects設定為 的範例true

TypeScript
import * as cdk from '@aws-cdk/core'; import * as s3 from '@aws-cdk/aws-s3'; export class CdkTestStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const bucket = new s3.Bucket(this, 'Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, autoDeleteObjects: true }); } }
JavaScript
const cdk = require('@aws-cdk/core'); const s3 = require('@aws-cdk/aws-s3'); class CdkTestStack extends cdk.Stack { constructor(scope, id, props) { super(scope, id, props); const bucket = new s3.Bucket(this, 'Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, autoDeleteObjects: true }); } } module.exports = { CdkTestStack }
Python
import aws_cdk.core as cdk import aws_cdk.aws_s3 as s3 class CdkTestStack(cdk.stack): def __init__(self, scope: cdk.Construct, id: str, **kwargs): super().__init__(scope, id, **kwargs) bucket = s3.Bucket(self, "Bucket", removal_policy=cdk.RemovalPolicy.DESTROY, auto_delete_objects=True)
Java
software.amazon.awscdk.core.*; import software.amazon.awscdk.services.s3.*; public class CdkTestStack extends Stack { public CdkTestStack(final Construct scope, final String id) { this(scope, id, null); } public CdkTestStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); Bucket.Builder.create(this, "Bucket") .removalPolicy(RemovalPolicy.DESTROY) .autoDeleteObjects(true).build(); } }
C#
using Amazon.CDK; using Amazon.CDK.AWS.S3; public CdkTestStack(Construct scope, string id, IStackProps props) : base(scope, id, props) { new Bucket(this, "Bucket", new BucketProps { RemovalPolicy = RemovalPolicy.DESTROY, AutoDeleteObjects = true }); }
Go
import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/jsii-runtime-go" s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3" ) s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{ RemovalPolicy: awscdk.RemovalPolicy_DESTROY, AutoDeleteObjects: jsii.Bool(true), })

您也可以透過 applyRemovalPolicy()方法,將移除政策直接套用至基礎 AWS CloudFormation 資源。此方法適用於在其 L2 資源的道具中沒有removalPolicy屬性的某些具狀態資源。範例如下:

  • AWS CloudFormation 堆疊

  • Amazon Cognito 使用者集區

  • Amazon DocumentDB 資料庫執行個體

  • Amazon EC2磁碟區

  • Amazon OpenSearch Service 網域

  • Amazon FSx 檔案系統

  • Amazon SQS佇列

TypeScript
const resource = bucket.node.findChild('Resource') as cdk.CfnResource; resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
JavaScript
const resource = bucket.node.findChild('Resource'); resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
Python
resource = bucket.node.find_child('Resource') resource.apply_removal_policy(cdk.RemovalPolicy.DESTROY);
Java
CfnResource resource = (CfnResource)bucket.node.findChild("Resource"); resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
C#
var resource = (CfnResource)bucket.node.findChild('Resource'); resource.ApplyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
注意

AWS CDK's 會RemovalPolicy轉譯為 AWS CloudFormation的 DeletionPolicy。不過, 中的預設值 AWS CDK 是保留資料,這與 AWS CloudFormation 預設值相反。