リソースと AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

これは v2 AWS CDK デベロッパーガイドです。古い CDKv1 は 2022 年 6 月 1 日にメンテナンスを開始し、2023 年 6 月 1 日にサポートを終了しました。

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

リソースと AWS CDK

リソースは、アプリケーション AWS のサービス で使用するように設定したものです。リソースは の機能です AWS CloudFormation。 AWS CloudFormation テンプレートでリソースとそのプロパティを設定することで、 にデプロイ AWS CloudFormation してリソースをプロビジョニングできます。では AWS Cloud Development Kit (AWS CDK)、 コンストラクトを使用してリソースを設定できます。次に、 AWS CloudFormation テンプレートを合成しCDK、 にデプロイ AWS CloudFormation してリソースをプロビジョニングするアプリをデプロイします。

コンストラクトを使用したリソースの設定

「」で説明されているようにAWS CDK コンストラクト、 AWS CDK には、すべての AWS リソースを表すコンストラクトと呼ばれるAWS コンストラクトの豊富なクラスライブラリが用意されています。

対応するコンストラクトを使用してリソースのインスタンスを作成するには、最初の引数、コンストラクトの論理 ID、一連の設定プロパティ (props) としてスコープを渡します。例えば、 コンストラクトライブラリの sqs.Queue AWS コンストラクトを使用して AWS KMS 暗号化された Amazon SQSキューを作成する方法は次のとおりです。

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, })

一部の設定 props はオプションであり、多くの場合デフォルト値があります。場合によってはすべての props がオプションであり、最後の引数は完全に省略できます。

リソース属性

AWS コンストラクトライブラリのほとんどのリソースは、デプロイ時に解決される属性を公開します 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。もう 1 つの例は、 型のプロパティ 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 バケットを定義し、バケットコンストラクトへの参照をスタックの属性として保存します。次に、アプリはインスタンス化のときにバケットを受け入れる 2 番目のスタックである 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 https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html生成スタックと消費スタックの Fn::ImportValue でエクスポートを自動的に合成して、その情報を 1 つのスタックから別のスタックに転送します。

依存関係のデッドロックの解決

別のスタックで 1 つのスタックからリソースを参照すると、2 つのスタック間に依存関係が作成されます。これにより、確実み正しい順序でデプロイされます。スタックがデプロイされたら、この依存関係は明確になります。その後、共有リソースを消費スタックから削除すると、予期しないデプロイの失敗が発生する可能性があります。2 つのスタック間に同じ順序でデプロイを強制する別の依存関係がある場合、失敗が発生します。また、生成スタックが Toolkit によって最初にデプロイCDKされるだけの場合は、依存関係なしで発生する可能性があります。 AWS CloudFormation エクスポートは、不要になったため生成スタックから削除されますが、エクスポートされたリソースは、更新がまだデプロイされていないため、消費スタックでまだ使用されています。したがって、生成スタックのデプロイは失敗します。

このデッドロックを解除するには、共有リソースの使用を消費スタックから削除します。(生成スタックから自動エクスポートが削除されます) 次に、自動生成されたエクスポートとまったく同じ論理 ID を使用し、生成スタックに同じエクスポートを手動で追加します。消費スタックの共有リソースの使用を削除し、両方のスタックをデプロイします。次に、手動エクスポート (共有リソースが不要になった場合、それも削除します) を削除し、両方のスタックを再度デプロイします。スタックの exportValue() メソッドは、この目的のために手動エクスポートを作成する便利な方法です。(リンクされたメソッドリファレンスで例を参照してください)

AWS アカウント内のリソースの参照

AWS CDK アプリの AWS アカウントで既に利用可能なリソースを使用するとします。これは、コンソール、、 を使用して直接 AWS SDK、 AWS CloudFormationまたは別の AWS CDK アプリケーションで定義されたリソースである場合があります。リソース ARN (または別の識別属性、または属性のグループ) をプロキシオブジェクトに変換できます。プロキシオブジェクトはリソースのクラスで静的ファクトリメソッドを呼び出すことにより、リソースへの参照として機能します。

このようなプロキシを作成すると、外部リソースはアプリの一部にはなりません。 AWS CDK したがって、 AWS CDK アプリでプロキシを変更しても、デプロイされたリソースには影響しません。ただし、プロキシは、そのタイプのリソースを必要とする任意の AWS CDK メソッドに渡すことができます。

次の例は、ARNarn:aws:s3::amzn-s3-demo-bucket1 を持つ既存のバケットと、特定の ID VPCを持つ既存の に基づく Amazon Virtual Private Cloud に基づいてバケットを参照する方法を示しています。

TypeScript
// Construct a proxy for a bucket by its name (must be same account) s3.Bucket.fromBucketName(this, 'MyBucket', 'amzn-s3-demo-bucket1'); // Construct a proxy for a bucket by its full ARN (can be another account) s3.Bucket.fromBucketArn(this, 'MyBucket', '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, 'MyBucket', 'amzn-s3-demo-bucket1'); // Construct a proxy for a bucket by its full ARN (can be another account) s3.Bucket.fromBucketArn(this, 'MyBucket', '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, "MyBucket", "amzn-s3-demo-bucket1") # Construct a proxy for a bucket by its full ARN (can be another account) s3.Bucket.from_bucket_arn(self, "MyBucket", "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, "MyBucket", "amzn-s3-demo-bucket1"); // Construct a proxy for a bucket by its full ARN (can be another account) Bucket.fromBucketArn(this, "MyBucket", "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, "MyBucket", "amzn-s3-demo-bucket1"); // Construct a proxy for a bucket by its full ARN (can be another account) Bucket.FromBucketArn(this, "MyBucket", "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("MyBucket"), 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("MyBucket"), 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() メソッドを詳しく見てみましょう。ec2.Vpc コンストラクトは複雑なため、CDKアプリVPCで使用する を選択する方法は多数あります。これに対処するために、 VPC コンストラクトにはfromLookup静的メソッド (Python: from_lookup) があり、合成時に AWS アカウントをクエリVPCすることで目的の Amazon を検索できます。

を使用するにはVpc.fromLookup()、スタックを合成するシステムが Amazon を所有するアカウントにアクセスできる必要がありますVPC。これは、CDKToolkit が合成VPC時にアカウントをクエリして適切な Amazon を見つけるためです。

さらに、Vpc.fromLookup() は明示的なアカウントおよびリージョンで定義されたスタックでのみ機能します (「AWS CDK の環境」を参照)。が環境に依存しないスタックVPCから Amazon を検索 AWS CDK しようとすると、CDKToolkit は を見つけるためにクエリを実行する環境を認識しませんVPC。

アカウントVPC AWS 内の を一意に識別するのに十分なVpc.fromLookup()属性を指定する必要があります。例えば、デフォルトの は 1 つしか存在できないため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でクエリを実行することもできます。 AWS CloudFormation または を使用して、作成VPC時に 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。これは、後で の属性を変更して、別の VPCが選択されVPCsるようにしても機能します。これは、CDKパイプラインなどの を定義する AWS アカウントにアクセスできない環境にスタックをデプロイする場合VPCに特に重要です。

外部リソースは、 AWS CDK アプリで定義された同様のリソースを使用する任意の場所で使用できますが、変更することはできません。例えば、外部 s3.BucketaddToResourcePolicy (Python: add_to_resource_policy) を呼び出しても何も行われません。

リソースの物理名

のリソースの論理名 AWS CloudFormation は、デプロイ後に AWS Management Console に表示されるリソースの名前とは異なります AWS CloudFormation。は、これらの最終名の物理名を AWS CDK 呼び出します。

例えば、Stack2MyBucket4DD88B4F前の例の論理 ID と物理名 を使用して Amazon S3 バケット AWS CloudFormation を作成できますstack2MyBucket4dd88b4f-iuv1rbv9z3to

プロパティ名を使用して、リソースを表すコンストラクトを作成するときに物理<resourceType>名を指定できます。次の例では、物理名の MyBucket を持つ Amazon S3 バケットを作成します。

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

一意のリソース識別子を渡す

前のセクションで説明したように、可能な限り、リソースをリファレンスで渡す必要があります。ただし、属性の 1 つでリソースを参照する以外に選択肢がない場合があります。ユースケースの例には次の内容が含まれます。

  • 低レベルの AWS CloudFormation リソースを使用している場合。

  • 環境変数を介して Lambda 関数を参照する場合など、 AWS CDK アプリケーションのランタイムコンポーネントにリソースを公開する必要がある場合。

これらの識別子は、次のようなリソースの属性として利用できます。

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 を指定できます。ロールが指定されていない場合、関数はこの用途に特化したロールを自動的に作成します。その後、リソースに付与メソッドを使用し、ロールにステートメントを追加できます。

グラントメソッドは、 IAMポリシーでの処理APIsに下位レベルを使用して構築されます。ポリシーは PolicyDocument オブジェクトとしてモデル化されます。addToRolePolicy メソッド (Python: add_to_role_policy) を使用して ロール (またはコンストラクトのアタッチされたロール)、あるいは addToResourcePolicy (Python: add_to_resource_policy) メソッドを使用してリソースのポリシー (Bucket ポリシーなど) にステートメントを直接追加するか、

リソースメトリクスとアラーム

多くのリソースは、モニタリングダッシュボードとアラームの設定に使用できる 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 メソッドを使用し、特定のネットワークパスでデータが流れるようにします。次の例では、ウェブ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 データベースのインスタンスへの接続を受け入れるポートなどがあります。このような場合、ポートを手動で指定しなくても、厳密なネットワーク制御を強制できます。これを行うには、allowDefaultPortFrom および allowToDefaultPort メソッド (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 テーブルの削除ポリシーとは異なる意味およびデフォルトを持ちます。

意味

RemovalPolicy.RETAIN

スタックを破棄するとき、リソースの内容を保持します (デフォルト)。リソースはスタックから孤立しているため、手動で削除する必要があります。リソースがまだ存在する間にスタックを再デプロイしようとした場合、名前の競合によってエラーメッセージが表示されます。

RemovalPolicy.DESTROY

リソースはスタックとともに破棄されます。

AWS CloudFormation は、削除ポリシーが に設定されている場合でも、ファイルを含む Amazon S3 バケットを削除しませんDESTROY。試行は AWS CloudFormation エラーです。バケットからすべてのファイル AWS CDK を削除してから破棄するには、バケットの autoDeleteObjectsプロパティを に設定しますtrue

次の内容は、DESTROYRemovalPolicy および autoDeleteOjbectstrue に設定して Amazon S3 バケットを作成する例を示します。

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 リソースの props に 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の は AWS CloudFormationの RemovalPolicyに変換されますDeletionPolicy。ただし、 のデフォルト AWS CDK はデータを保持することであり、デフォルトとは逆です AWS CloudFormation 。