Skip to content

Commit

Permalink
feat(core): expose custom resource provider's role
Browse files Browse the repository at this point in the history
The role ARN can then be used in resource-based policies.

See aws#9751 (comment)
jogold committed Dec 7, 2020
1 parent bfee58c commit 390327f
Showing 3 changed files with 56 additions and 1 deletion.
14 changes: 14 additions & 0 deletions packages/@aws-cdk/core/README.md
Original file line number Diff line number Diff line change
@@ -486,6 +486,20 @@ const sum = new Sum(this, 'MySum', { lhs: 40, rhs: 2 });
new CfnOutput(this, 'Result', { value: Token.asString(sum.result) });
```

To access the ARN of the provider's AWS Lambda function role, use the `getOrCreateProvider()`
built-in singleton:

```ts
const provider = CustomResourceProvider.getOrCreateProvider(this, 'Custom::MyCustomResourceType', {
codeDirectory: `${__dirname}/my-handler`,
runtime: CustomResourceProviderRuntime.NODEJS_12, // currently the only supported runtime
});

const roleArn = provider.roleArn;
```

This role ARN can then be used in resource-based policies.

#### The Custom Resource Provider Framework

The [`@aws-cdk/custom-resources`] module includes an advanced framework for
Original file line number Diff line number Diff line change
@@ -100,12 +100,27 @@ export class CustomResourceProvider extends CoreConstruct {
* used when defining a `CustomResource`.
*/
public static getOrCreate(scope: Construct, uniqueid: string, props: CustomResourceProviderProps) {
return this.getOrCreateProvider(scope, uniqueid, props).serviceToken;
}

/**
* Returns a stack-level singleton for the custom resource provider.
*
* @param scope Construct scope
* @param uniqueid A globally unique id that will be used for the stack-level
* construct.
* @param props Provider properties which will only be applied when the
* provider is first created.
* @returns the service token of the custom resource provider, which should be
* used when defining a `CustomResource`.
*/
public static getOrCreateProvider(scope: Construct, uniqueid: string, props: CustomResourceProviderProps) {
const id = `${uniqueid}CustomResourceProvider`;
const stack = Stack.of(scope);
const provider = stack.node.tryFindChild(id) as CustomResourceProvider
?? new CustomResourceProvider(stack, id, props);

return provider.serviceToken;
return provider;
}

/**
@@ -121,6 +136,11 @@ export class CustomResourceProvider extends CoreConstruct {
*/
public readonly serviceToken: string;

/**
* The ARN of the provider's AWS Lambda function role.
*/
public readonly roleArn: string;

protected constructor(scope: Construct, id: string, props: CustomResourceProviderProps) {
super(scope, id);

@@ -167,6 +187,7 @@ export class CustomResourceProvider extends CoreConstruct {
Policies: policies,
},
});
this.roleArn = Token.asString(role.getAtt('Arn'));

const timeout = props.timeout ?? Duration.minutes(15);
const memory = props.memorySize ?? Size.mebibytes(128);
Original file line number Diff line number Diff line change
@@ -232,5 +232,25 @@ nodeunitShim({
});
test.done();
},

'roleArn'(test: Test) {
// GIVEN
const stack = new Stack();

// WHEN
const cr = CustomResourceProvider.getOrCreateProvider(stack, 'Custom:MyResourceType', {
codeDirectory: TEST_HANDLER,
runtime: CustomResourceProviderRuntime.NODEJS_12,
});

// THEN
test.deepEqual(stack.resolve(cr.roleArn), {
'Fn::GetAtt': [
'CustomMyResourceTypeCustomResourceProviderRoleBD5E655F',
'Arn',
],
});
test.done();
},
});

0 comments on commit 390327f

Please sign in to comment.