Best practices - AWS Prescriptive Guidance

Best practices

L1 constructs

  • You can't always avoid using L1 constructs directly, but you should avoid it whenever possible. If a specific L2 construct doesn't support your edge case, you can explore these two options instead of using the L1 construct directly:

    • Access defaultChild: If the CloudFormation property you need isn't available in an L2 construct, you can access the underlying L1 construct by using L2Construct.node.defaultChild. You can update any public properties of the L1 construct by accessing them through this property instead of going through the trouble of creating the L1 construct yourself.

    • Use property overrides: What if the property that you want to update isn't public? The ultimate escape hatch that allows the AWS CDK to do anything that a CloudFormation template can do is to use a method that's available in every L1 construct: addPropertyOverride. You can manipulate your stack at the CloudFormation template level by passing the CloudFormation property name and value directly to this method.

L2 constructs

  • Remember to take advantage of the helper methods that L2 constructs often offer. With layer 2, you don't have to pass every property upon instantiation. L2 helper methods can make resource provisioning exponentially more convenient, especially when conditional logic is needed. One of the most convenient helper methods is derived from the Grant class. This class isn't used directly, but many L2 constructs use it to provide helper methods that make permissions much easier to implement. For example, if you want to give permission to an L2 Lambda function to access an L2 S3 bucket, you could call s3Bucket.grantReadWrite(lambdaFunction) instead of creating a new role and policy.

L3 constructs

  • Although L3 constructs can be very convenient when you want to make your stacks more reusable and customizable, we recommend that you use them carefully. Consider which type of L3 construct you need or whether you need an L3 construct at all:

    • If you aren't interacting with AWS resources directly, it's often more appropriate to make a helper class instead of extending the Construct class. This is because the Construct class performs many actions by default that are needed only if you're directly interacting with AWS resources. So if you don't need those actions performed, it's more efficient to avoid them.

    • If you determine that creating a new L3 construct is appropriate, in most cases you will want to extend the Constructclass directly. Extend other L2 constructs only when you want to update the default properties of the construct. If other L2 constructs or custom logic are involved, extend Construct directly and instantiate all resources within the constructor.