Skip to content
This repository was archived by the owner on Jul 16, 2024. It is now read-only.

Commit 0c9bea7

Browse files
authored
feature: add a helper construct for a glue default role (#150)
1 parent 9732612 commit 0c9bea7

File tree

6 files changed

+199
-7
lines changed

6 files changed

+199
-7
lines changed

core/API.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,43 @@ SingletonBucket.getOrCreate(scope: Construct, bucketName: string)
409409

410410

411411

412+
### SingletonGlueDefaultRole <a name="aws-analytics-reference-architecture.SingletonGlueDefaultRole"></a>
413+
414+
SingletonGlueDefaultRole Construct to automatically setup a new Amazon IAM role to use with AWS Glue jobs.
415+
416+
The role is created with AWSGlueServiceRole policy and authorize all actions on S3.
417+
The Construct provides a getOrCreate method for SingletonInstantiation
418+
419+
420+
#### Static Functions <a name="Static Functions"></a>
421+
422+
##### `getOrCreate` <a name="aws-analytics-reference-architecture.SingletonGlueDefaultRole.getOrCreate"></a>
423+
424+
```typescript
425+
import { SingletonGlueDefaultRole } from 'aws-analytics-reference-architecture'
426+
427+
SingletonGlueDefaultRole.getOrCreate(scope: Construct)
428+
```
429+
430+
###### `scope`<sup>Required</sup> <a name="aws-analytics-reference-architecture.SingletonGlueDefaultRole.parameter.scope"></a>
431+
432+
- *Type:* [`@aws-cdk/core.Construct`](#@aws-cdk/core.Construct)
433+
434+
---
435+
436+
#### Properties <a name="Properties"></a>
437+
438+
##### `iamRole`<sup>Required</sup> <a name="aws-analytics-reference-architecture.SingletonGlueDefaultRole.property.iamRole"></a>
439+
440+
```typescript
441+
public readonly iamRole: Role;
442+
```
443+
444+
- *Type:* [`@aws-cdk/aws-iam.Role`](#@aws-cdk/aws-iam.Role)
445+
446+
---
447+
448+
412449
### SynchronousAthenaQuery <a name="aws-analytics-reference-architecture.SynchronousAthenaQuery"></a>
413450

414451
SynchronousAthenaQuery Construct to execute an Amazon Athena query synchronously.

core/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ export { SynchronousAthenaQueryProps, SynchronousAthenaQuery } from './synchrono
1010
export { SingletonBucket } from './singleton-bucket';
1111
export { Ec2SsmRole } from './ec2-ssm-role';
1212
export { DataLakeCatalog } from './data-lake-catalog';
13-
export { AthenaDefaultSetup, AthenaDefaultSetupProps } from './athena-default-setup';
13+
export { AthenaDefaultSetup, AthenaDefaultSetupProps } from './athena-default-setup';
14+
export { SingletonGlueDefaultRole } from './singleton-glue-default-role';

core/src/integ.default.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// SPDX-License-Identifier: MIT-0
33

44
import { App, Stack } from '@aws-cdk/core';
5-
import { AthenaDefaultSetup } from './athena-default-setup';
5+
import { SingletonGlueDefaultRole } from '.';
66

77
const mockApp = new App();
8-
const stack = new Stack(mockApp, 'teststack');
9-
new AthenaDefaultSetup(stack, 'testlake');
8+
const stack = new Stack(mockApp, 'testStack');
9+
SingletonGlueDefaultRole.getOrCreate(stack);
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: MIT-0
3+
4+
import { ManagedPolicy, PolicyDocument, PolicyStatement, Role, ServicePrincipal } from '@aws-cdk/aws-iam';
5+
import { Construct, Stack } from '@aws-cdk/core';
6+
7+
/**
8+
* SingletonGlueDefaultRole Construct to automatically setup a new Amazon IAM role to use with AWS Glue jobs.
9+
* The role is created with AWSGlueServiceRole policy and authorize all actions on S3.
10+
* The Construct provides a getOrCreate method for SingletonInstantiation
11+
*/
12+
13+
export class SingletonGlueDefaultRole extends Construct {
14+
15+
public static getOrCreate(scope: Construct) {
16+
const stack = Stack.of(scope);
17+
const id = 'glueDefaultRole';
18+
return stack.node.tryFindChild(id) as SingletonGlueDefaultRole || new SingletonGlueDefaultRole(stack, id);
19+
}
20+
21+
public readonly iamRole: Role;
22+
23+
/**
24+
* Constructs a new instance of the GlueDefaultRole class
25+
* @param {Construct} scope the Scope of the CDK Construct
26+
* @param {string} id the ID of the CDK Construct
27+
* @param {GlueDefaultRoleProps} props the GlueDefaultRole [properties]{@link GlueDefaultRoleProps}
28+
* @access public
29+
*/
30+
31+
private constructor(scope: Construct, id: string) {
32+
super(scope, id);
33+
34+
const stack = Stack.of(this);
35+
36+
this.iamRole = new Role(this, 'glueDefaultRole', {
37+
assumedBy: new ServicePrincipal('glue.amazonaws.com'),
38+
managedPolicies: [ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSGlueServiceRole')],
39+
inlinePolicies: {
40+
DataAccess: new PolicyDocument({
41+
statements: [
42+
new PolicyStatement({
43+
resources: [
44+
stack.formatArn({
45+
region: '',
46+
account: '',
47+
service: 's3',
48+
resource: '*',
49+
resourceName: '*',
50+
}),
51+
],
52+
actions: [
53+
's3:ListBucket',
54+
's3:*Object*',
55+
's3:AbortMultipartUpload',
56+
's3:ListBucketMultipartUploads',
57+
's3:ListMultipartUploadParts',
58+
],
59+
}),
60+
new PolicyStatement({
61+
resources: ['*'],
62+
actions: ['lakeformation:GetDataAccess'],
63+
}),
64+
],
65+
}),
66+
},
67+
});
68+
}
69+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: MIT-0
3+
4+
import * as assertCDK from '@aws-cdk/assert';
5+
import { Stack } from '@aws-cdk/core';
6+
import { SingletonGlueDefaultRole } from '../src/singleton-glue-default-role';
7+
import '@aws-cdk/assert/jest';
8+
9+
test('SingletonGlueDefaultRole', () => {
10+
11+
const singletonGlueDefaultRoleStack = new Stack();
12+
13+
// Instantiate 2 SingletonGlueDefaultRole Constructs
14+
SingletonGlueDefaultRole.getOrCreate(singletonGlueDefaultRoleStack);
15+
SingletonGlueDefaultRole.getOrCreate(singletonGlueDefaultRoleStack);
16+
17+
18+
// Test if SingletonGlueDefaultRole is a singleton
19+
expect(singletonGlueDefaultRoleStack).toCountResources('AWS::IAM::Role', 1);
20+
21+
// Test the created Amazon IAM Role
22+
expect(singletonGlueDefaultRoleStack).toHaveResource('AWS::IAM::Role', {
23+
AssumeRolePolicyDocument: {
24+
Statement: [
25+
{
26+
Action: 'sts:AssumeRole',
27+
Effect: 'Allow',
28+
Principal: {
29+
Service: 'glue.amazonaws.com',
30+
},
31+
},
32+
],
33+
Version: '2012-10-17',
34+
},
35+
ManagedPolicyArns: [
36+
{
37+
'Fn::Join': [
38+
'',
39+
[
40+
'arn:',
41+
{
42+
Ref: 'AWS::Partition',
43+
},
44+
':iam::aws:policy/service-role/AWSGlueServiceRole',
45+
],
46+
],
47+
},
48+
],
49+
Policies: [
50+
{
51+
PolicyDocument: assertCDK.objectLike({
52+
Statement: assertCDK.arrayWith(
53+
{
54+
Action: [
55+
's3:ListBucket',
56+
's3:*Object*',
57+
's3:AbortMultipartUpload',
58+
's3:ListBucketMultipartUploads',
59+
's3:ListMultipartUploadParts',
60+
],
61+
Effect: 'Allow',
62+
Resource: {
63+
'Fn::Join': [
64+
'',
65+
[
66+
'arn:',
67+
{
68+
Ref: 'AWS::Partition',
69+
},
70+
':s3:::*/*',
71+
],
72+
],
73+
},
74+
},
75+
{
76+
Action: 'lakeformation:GetDataAccess',
77+
Effect: 'Allow',
78+
Resource: '*',
79+
}),
80+
}),
81+
PolicyName: 'DataAccess',
82+
},
83+
],
84+
});
85+
});

core/yarn.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)