Skip to content

Commit

Permalink
fix(redshift-alpha): use same role for database-query singleton funct…
Browse files Browse the repository at this point in the history
…ion (aws#32363)

### Issue # (if applicable)

Closes aws#32089.

### Reason for this change



The Redshift tables use a singleton function as the invoker for various custom resource onEvent Lambda functions. Currently, each custom resource lambda function has a dedicated IAM role to assume. However, since it’s the same singleton function, a shared role could achieve the same outcome.

### Description of changes



Use the same IAM role for the singleton invoker function to assume.

### Description of how you validated changes



deployed to my local stack

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
5d authored Jan 3, 2025
1 parent de04742 commit db950b3
Show file tree
Hide file tree
Showing 121 changed files with 25,019 additions and 54,088 deletions.
16 changes: 16 additions & 0 deletions packages/@aws-cdk/aws-redshift-alpha/lib/private/database-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export class DatabaseQuery<HandlerProps> extends Construct implements iam.IGrant

const provider = new customresources.Provider(this, 'Provider', {
onEventHandler: handler,
role: this.getOrCreateInvokerRole(handler),
});

const queryHandlerProps: DatabaseQueryHandlerProps & HandlerProps = {
Expand Down Expand Up @@ -116,4 +117,19 @@ export class DatabaseQuery<HandlerProps> extends Construct implements iam.IGrant
}
return adminUser;
}

/**
* Get or create the IAM role for the singleton lambda function.
* We only need one function since it's just acting as an invoker.
* */
private getOrCreateInvokerRole(handler: lambda.SingletonFunction): iam.IRole {
const id = handler.constructName + 'InvokerRole';
const existing = cdk.Stack.of(this).node.tryFindChild(id);
return existing != null
? existing as iam.Role
: new iam.Role(cdk.Stack.of(this), id, {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole')],
});
}
}
3 changes: 3 additions & 0 deletions packages/@aws-cdk/aws-redshift-alpha/lib/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ abstract class UserBase extends Construct implements IUser {
...this.databaseProps,
user: this,
});

// The privilege should be granted or revoked when the table exists.
this.privileges.node.addDependency(table);
}

this.privileges.addPrivileges(table, ...actions);
Expand Down
21 changes: 21 additions & 0 deletions packages/@aws-cdk/aws-redshift-alpha/test/database-query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,25 @@ describe('database query', () => {
expect(stack.resolve(query.getAtt('attribute'))).toStrictEqual({ 'Fn::GetAtt': ['Query435140A1', 'attribute'] });
expect(stack.resolve(query.getAttString('attribute'))).toStrictEqual({ 'Fn::GetAtt': ['Query435140A1', 'attribute'] });
});

it('creates at most one IAM invoker role for handler', () => {
new DatabaseQuery(stack, 'Query0', {
...minimalProps,
});

new DatabaseQuery(stack, 'Query1', {
...minimalProps,
});

new DatabaseQuery(stack, 'Query2', {
...minimalProps,
});

const template = Template.fromStack(stack).toJSON();
const iamRoles = Object.entries(template.Resources)
.map(([k, v]) => [k, Object.getOwnPropertyDescriptor(v, 'Type')?.value])
.filter(([k, v]) => v === 'AWS::IAM::Role' && k.toString().includes('InvokerRole'));

expect(iamRoles.length === 1);
});
});
Binary file not shown.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit db950b3

Please sign in to comment.