AWS cdk documentation change
Summary
Added documentation for using Mixins and Facades to extend L1 constructs, including code examples in multiple languages. Also updated guidance about using Facades instead of wrapping L1s for permissions.
Security assessment
The changes document security-adjacent features like auto-delete bucket policies (Mixins) and granular permissions management (Facades), but there's no evidence of addressing a specific vulnerability. The additions show how to implement security best practices rather than fix vulnerabilities.
Diff
diff --git a/cdk/v2/guide/cfn-layer.md b/cdk/v2/guide/cfn-layer.md index 3093f58bc..5de397bfd 100644 --- a//cdk/v2/guide/cfn-layer.md +++ b//cdk/v2/guide/cfn-layer.md @@ -5 +5 @@ -Use escape hatchesUse un-escape hatchesUse raw overridesUse custom resources +Use Mixins to add features to L1 constructsUse Facades for integrations on L1 constructsUse escape hatchesUse un-escape hatchesUse raw overridesUse custom resources @@ -11 +11,184 @@ This is the AWS CDK v2 Developer Guide. The older CDK v1 entered maintenance on -Customize constructs from the AWS Construct Library through escape hatches, raw overrides, and custom resources. +Customize constructs from the AWS Construct Library through Mixins, Facades, escape hatches, raw overrides, and custom resources. + +## Use Mixins to add features to L1 constructs + +Mixins let you add high-level features to L1 constructs without needing a full L2 construct. This is useful when an L2 construct is not available for a service, or when you want to use L1 constructs with specific features that are normally only available through L2 constructs. + +For example, you can add auto-delete behavior to an L1 `CfnBucket`, which normally requires the L2 `Bucket` construct: + +###### Example + +TypeScript + + + + import * as cdk from 'aws-cdk-lib'; + import * as s3 from 'aws-cdk-lib/aws-s3'; + + const bucket = new s3.CfnBucket(this, 'MyBucket'); + bucket.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.DELETE; + + // Add auto-delete objects behavior using a Mixin + bucket.with(new s3.mixins.BucketAutoDeleteObjects()); + +JavaScript + + + + const cdk = require('aws-cdk-lib'); + const s3 = require('aws-cdk-lib/aws-s3'); + + const bucket = new s3.CfnBucket(this, 'MyBucket'); + bucket.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.DELETE; + + // Add auto-delete objects behavior using a Mixin + bucket.with(new s3.mixins.BucketAutoDeleteObjects()); + +Python + + + + import aws_cdk as cdk + import aws_cdk.aws_s3 as s3 + + bucket = s3.CfnBucket(self, "MyBucket") + bucket.cfn_options.deletion_policy = cdk.CfnDeletionPolicy.DELETE + + # Add auto-delete objects behavior using a Mixin + bucket.with_(s3.mixins.BucketAutoDeleteObjects()) + +Java + + + + import software.amazon.awscdk.*; + import software.amazon.awscdk.services.s3.*; + + CfnBucket bucket = new CfnBucket(this, "MyBucket"); + bucket.getCfnOptions().setDeletionPolicy(CfnDeletionPolicy.DELETE); + + // Add auto-delete objects behavior using a Mixin + bucket.with(new BucketAutoDeleteObjects()); + +C# + + + + using Amazon.CDK; + using Amazon.CDK.AWS.S3; + + var bucket = new CfnBucket(this, "MyBucket"); + bucket.CfnOptions.DeletionPolicy = CfnDeletionPolicy.DELETE; + + // Add auto-delete objects behavior using a Mixin + bucket.With(new BucketAutoDeleteObjects()); + +Go + + + + bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil) + bucket.CfnOptions().SetDeletionPolicy(awscdk.CfnDeletionPolicy_DELETE) + + bucket.With(awss3.NewBucketAutoDeleteObjects()) + +Mixins are available through the `mixins` namespace of each service module. You can combine Mixins with Facades to also get permissions and other integrations on L1 constructs. For more information about Mixins, see [Mixins](./mixins.html). + +## Use Facades for integrations on L1 constructs + +Facades are resource-specific classes that provide integrations — such as permissions, metrics, and reflections — for both L1 and L2 constructs. The most common Facades are Grants classes, which provide intent-based permission methods. + +You can use Facades directly on L1 constructs without wrapping them in an L2: + +###### Example + +TypeScript + + + + import * as s3 from 'aws-cdk-lib/aws-s3'; + import * as iam from 'aws-cdk-lib/aws-iam'; + + const bucket = new s3.CfnBucket(this, 'MyBucket'); + const role = new iam.Role(this, 'MyRole', { + assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), + }); + + // Use the Grants Facade directly on the L1 construct + s3.BucketGrants.fromBucket(bucket).read(role); + +JavaScript + + + + const s3 = require('aws-cdk-lib/aws-s3'); + const iam = require('aws-cdk-lib/aws-iam'); + + const bucket = new s3.CfnBucket(this, 'MyBucket'); + const role = new iam.Role(this, 'MyRole', { + assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), + }); + + // Use the Grants Facade directly on the L1 construct + s3.BucketGrants.fromBucket(bucket).read(role); + +Python + + + + import aws_cdk.aws_s3 as s3 + import aws_cdk.aws_iam as iam + + bucket = s3.CfnBucket(self, "MyBucket") + role = iam.Role(self, "MyRole", + assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"), + ) + + # Use the Grants Facade directly on the L1 construct + s3.BucketGrants.from_bucket(bucket).read(role) + +Java + + + + import software.amazon.awscdk.services.s3.*; + import software.amazon.awscdk.services.iam.*; + + CfnBucket bucket = new CfnBucket(this, "MyBucket"); + Role role = Role.Builder.create(this, "MyRole") + .assumedBy(new ServicePrincipal("lambda.amazonaws.com")) + .build(); + + // Use the Grants Facade directly on the L1 construct + BucketGrants.fromBucket(bucket).read(role); + +C# + + + + using Amazon.CDK.AWS.S3; + using Amazon.CDK.AWS.IAM; + + var bucket = new CfnBucket(this, "MyBucket"); + var role = new Role(this, "MyRole", new RoleProps + { + AssumedBy = new ServicePrincipal("lambda.amazonaws.com") + }); + + // Use the Grants Facade directly on the L1 construct + BucketGrants.FromBucket(bucket).Read(role); + +Go + + + + bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil) + role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{ + AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil), + }) + + awss3.BucketGrants_FromBucket(bucket).Read(role, nil) + +For more information about Facades, see [Facades](./facades.html). + +When Mixins and Facades don’t cover your use case, you can use escape hatches and raw overrides to customize constructs at a lower level. @@ -322 +505,5 @@ The AWS CDK also provides the capability to go _up_ an abstraction level, which -This is convenient when you create an L1 resource but want to use it with a construct that requires an L2 resource. It’s also helpful when you want to use convenience methods like `.grants.xxxx()` that aren’t available on the L1 construct. +This is convenient when you create an L1 resource but want to use it with a construct that requires an L2 resource. + +###### Tip + +If you only need permissions or other integrations on an L1 construct, you don’t need to wrap it in an L2. Use [Facades](./facades.html) like Grants classes directly on the L1 instead — for example, `BucketGrants.fromBucket(cfnBucket).read(role)`.