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

Commit d9f06ff

Browse files
bouhajerAnady208
andauthored
feat: lf s3 location (#273)
* add lf s3 location construct * removed const type from the cfnconstruct * feat: lf s3 location add comments and unit test Co-authored-by: bouhajer <bouhajer@amazon.com> Co-authored-by: ahmed12500 <annady@amazon.com>
1 parent 3f03ae2 commit d9f06ff

File tree

8 files changed

+5769
-5638
lines changed

8 files changed

+5769
-5638
lines changed

core/.projen/deps.json

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

core/.projen/tasks.json

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

core/.projenrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ const project = new awscdk.AwsCdkConstructLibrary({
6868
'@aws-cdk/lambda-layer-awscli',
6969
'@aws-cdk/aws-emr',
7070
'@aws-cdk/aws-kms',
71+
'@aws-cdk/aws-lakeformation'
7172
],
7273

7374
deps: [

core/jsconfig.json

Lines changed: 0 additions & 7 deletions
This file was deleted.

core/package.json

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

core/src/lf-s3-location.ts

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import * as lakeformation from '@aws-cdk/aws-lakeformation';
2+
import { Construct} from '@aws-cdk/core';
3+
import * as s3 from '@aws-cdk/aws-s3';
4+
import { Location } from '@aws-cdk/aws-s3';
5+
import { PolicyStatement, Role, ServicePrincipal, } from '@aws-cdk/aws-iam';
6+
7+
/**
8+
* The props for LF-S3-Location Construct.
9+
*/
10+
export interface LakeFormationS3LocationProps {
11+
/**
12+
* S3 bucket to be registered with Lakeformation
13+
*/
14+
s3bucket:Location;
15+
}
16+
17+
/**
18+
* This CDK construct aims to register an S3 Location for Lakeformation with Read and Write access.
19+
*
20+
* This construct is based on an IAM role with 2 policies folowing the least privilege AWS best practices:
21+
* * Policy 1 is for GetObject, PutObject, DeleteObject from S3 bucket
22+
* * Policy 2 is to list S3 Buckets
23+
*
24+
* Policy 1 takes as an input S3 object arn
25+
* Policy 2 takes as an input S3 bucket arn
26+
*
27+
*
28+
* The CDK construct instantiate the cfnresource in order to register the S3 location with Lakeformation using the IAM role defined above.
29+
*
30+
* Usage example:
31+
* ```typescript
32+
* import * as cdk from '@aws-cdk/core';
33+
* import { LakeformationS3Location } from 'aws-analytics-reference-architecture';
34+
*
35+
* const exampleApp = new cdk.App();
36+
* const stack = new cdk.Stack(exampleApp, 'LakeformationS3LocationStack');
37+
*
38+
* new LakeformationS3Location(stack, 'MyLakeformationS3Location', {
39+
* s3bucket:{
40+
bucketName: 'test',
41+
objectKey: 'test',
42+
}
43+
* });
44+
* ```
45+
*/
46+
export class LakeformationS3Location extends Construct {
47+
48+
constructor(scope: Construct, id: string, props: LakeFormationS3LocationProps) {
49+
super(scope, id);
50+
51+
/**
52+
* Create an Amazon IAM Role used by Lakeformation to register S3 location
53+
*/
54+
const role = new Role(this, 'LFS3AccessRole', {
55+
assumedBy: new ServicePrincipal('lakeformation.amazonaws.com'),
56+
});
57+
58+
// add policy to access S3 for Read and Write
59+
role.addToPolicy(
60+
new PolicyStatement({
61+
resources: [
62+
s3.Bucket.fromBucketName(
63+
this,
64+
"BucketByName",
65+
props.s3bucket.bucketName
66+
).arnForObjects(props.s3bucket.objectKey)
67+
],
68+
actions: [
69+
's3:GetObject',
70+
's3:PutObject',
71+
's3:DeleteObject',
72+
],
73+
}),
74+
);
75+
76+
// add policy to list S3 bucket
77+
role.addToPolicy(
78+
new PolicyStatement({
79+
resources: [
80+
s3.Bucket.fromBucketName(
81+
this,
82+
"BucketName",
83+
props.s3bucket.bucketName
84+
).bucketArn
85+
],
86+
actions: [
87+
's3:ListBucket'
88+
],
89+
}),
90+
);
91+
92+
93+
94+
//// The code below shows an example of how to instantiate the cfnresource
95+
new lakeformation.CfnResource(this, 'MyCfnResource', {
96+
resourceArn: s3.Bucket.fromBucketName(
97+
this,
98+
"BucketByNameCfn",
99+
props.s3bucket.bucketName
100+
).arnForObjects(props.s3bucket.objectKey),
101+
102+
useServiceLinkedRole: false,
103+
104+
// the properties below are optional
105+
roleArn: role.roleArn
106+
});
107+
108+
}
109+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: MIT-0
3+
/**
4+
* Tests LakeformationS3Location
5+
*
6+
* @group unit/feature/lf-s3-location
7+
*/
8+
9+
// import * as cdk from '@aws-cdk/core';
10+
// import * from '@types/jest';
11+
//import { SdkProvider } from 'aws-cdk/lib/api/aws-auth';
12+
//import { CloudFormationDeployments } from 'aws-cdk/lib/api/cloudformation-deployments';
13+
import { LakeformationS3Location } from '../../src/lf-s3-location';
14+
import '@aws-cdk/assert/jest';
15+
import { Stack } from '@aws-cdk/core';
16+
17+
test('LakeformationS3Location construct', () => {
18+
19+
const lfS3Stack = new Stack();
20+
21+
new LakeformationS3Location(lfS3Stack, 'CustomExample',
22+
{
23+
s3bucket: {
24+
bucketName: 'test',
25+
objectKey: 'test',
26+
}
27+
}
28+
);
29+
30+
31+
// Check if the Stack has a Role
32+
//expect(lfS3Stack).toContain('LFS3AccessRole');
33+
expect(lfS3Stack).toHaveResource('AWS::IAM::Role');
34+
35+
// TODO: check the role has AmazonSSMManagedInstanceCore managed policy
36+
});
37+

0 commit comments

Comments
 (0)