in typescript/s3-object-lambda/lib/s3-object-lambda-stack.ts [12:107]
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const accessPoint = `arn:aws:s3:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:accesspoint/${S3_ACCESS_POINT_NAME}`;
// Set up a bucket
const bucket = new s3.Bucket(this, 'example-bucket', {
accessControl: s3.BucketAccessControl.BUCKET_OWNER_FULL_CONTROL,
encryption: s3.BucketEncryption.S3_MANAGED,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL
});
// Delegating access control to access points
// https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points-policies.html
bucket.addToResourcePolicy(new iam.PolicyStatement({
actions: ['*'],
principals: [new iam.AnyPrincipal()],
resources: [
bucket.bucketArn,
bucket.arnForObjects('*')
],
conditions: {
'StringEquals':
{
's3:DataAccessPointAccount': `${cdk.Aws.ACCOUNT_ID}`
}
}
}
));
// lambda to process our objects during retrieval
const retrieveTransformedObjectLambda = new lambda.Function(this, 'retrieveTransformedObjectLambda', {
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'index.handler',
code: lambda.Code.fromAsset('resources/retrieve-transformed-object-lambda')
}
);
// Object lambda s3 access
retrieveTransformedObjectLambda.addToRolePolicy(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
resources: ['*'],
actions: ['s3-object-lambda:WriteGetObjectResponse']
}
));
// Restrict Lambda to be invoked from own account
retrieveTransformedObjectLambda.addPermission('invocationRestriction', {
action: 'lambda:InvokeFunction',
principal: new iam.AccountRootPrincipal(),
sourceAccount: cdk.Aws.ACCOUNT_ID
});
// Associate Bucket's access point with lambda get access
const policyDoc = new iam.PolicyDocument();
const policyStatement = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['s3:GetObject'],
principals: [
new iam.ArnPrincipal(<string>retrieveTransformedObjectLambda.role?.roleArn)
],
resources: [`${accessPoint}/object/*`]
});
policyStatement.sid = 'AllowLambdaToUseAccessPoint';
policyDoc.addStatements(policyStatement);
new s3.CfnAccessPoint(this, 'exampleBucketAP', {
bucket: bucket.bucketName,
name: S3_ACCESS_POINT_NAME,
policy: policyDoc
}
);
// Access point to receive GET request and use lambda to process objects
const objectLambdaAP = new s3ObjectLambda.CfnAccessPoint(this, 's3ObjectLambdaAP', {
name: OBJECT_LAMBDA_ACCESS_POINT_NAME,
objectLambdaConfiguration: {
supportingAccessPoint: accessPoint,
transformationConfigurations: [{
actions: ['GetObject'],
contentTransformation: {
'AwsLambda': {
'FunctionArn': `${retrieveTransformedObjectLambda.functionArn}`
}
}
}]
}
}
);
new cdk.CfnOutput(this, 'exampleBucketArn', {value: bucket.bucketArn});
new cdk.CfnOutput(this, 'objectLambdaArn', {value: retrieveTransformedObjectLambda.functionArn});
new cdk.CfnOutput(this, 'objectLambdaAccessPointArn', {value: objectLambdaAP.attrArn});
new cdk.CfnOutput(this, 'objectLambdaAccessPointUrl', {
value: `https://console.aws.amazon.com/s3/olap/${cdk.Aws.ACCOUNT_ID}/${OBJECT_LAMBDA_ACCESS_POINT_NAME}?region=${cdk.Aws.REGION}`
});
}