'How can I clone a CDK resource?

Let's say I'm using the AWS CDK with TypeScript. Is there a way to define a function that takes a resource as a parameter and creates a clone with tweaked parameters?

Alternatively, do CDK constructs allow extracting all their attributes so I can use them in a new constructor?

Perhaps there's a TypeScript trick to achieve this? I'm not that familiar with the language.


More specifically, I want to do this with IAM roles.

(Following is very pseudocode-y)

const role = new iam.Role(this, 'CloudWatchLogsLoggingRole', {
    ...
});
makeRoleVariant(role)

makeRoleVariant(role: iam.Role) {
    // newAttributes = <attributes from role, but edited>
    new iam.Role(
        ...newAttributes
    );
}


Solution 1:[1]

The recommended way here is to use simple extends from Object Oriented Programming.

E.g. if you want to have a reusable IAM role with some tweaks, that you want to pass to other constructs that expect an IRole object, you can do this:

export class RoleWithSNSPermissions extends iam.Role{
   construct(scope: Construct, id:string){
       super(scope, id);
       this.addToRolePolicy(new PolicyStatement({
           actions: ['sns:*'], resources: ['*'],
       }));
   }

}

Then you can start using it:

const role = new RoleWithSNSPermissions(this, 'Role');
new lambda.Function(this, 'fn', {
    ...
    role,

Alternatively, since MOST built-in CDK constructs are strongly typed to accept an Interface, rather than a concrete implementation (e.g. lambda.Function() construct expects an IRole object rather than a Role object), you are also free to create a completely custom class that conforms to the IRole interface.

class MyCustomRole implements IRole{
   // Implement all methods of IRole here
}

The disadvantage of this approach is that you need to reimplement all methods defined in the parent Interface, so pick the option that works best for your use case.

The general rule of thumb is:

  • If you want to apply only small changes like apply meaningful defaults or invoke methods under the hood - extend the base class.
  • If you want a completely custom behavior and flexibility to override code flow - implement the interface.
  • There's also a combined option for certain use cases

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1