in core/src/synchronous-athena-query/synchronous-athena-query.ts [50:166]
constructor(scope: Construct, id: string, props: SynchronousAthenaQueryProps) {
super(scope, id);
const stack = Stack.of(this);
// AWS Lambda function for the AWS CDK Custom Resource responsible to start query
const athenaQueryStartFn = new PreBundledFunction(this, 'athenaQueryStartFn', {
runtime: Runtime.PYTHON_3_8,
codePath: 'synchronous-athena-query/resources/lambdas',
handler: 'lambda.on_event',
logRetention: RetentionDays.ONE_DAY,
timeout: Duration.seconds(20),
});
// Add permissions from the Amazon IAM Policy Statements
props.executionRoleStatements?.forEach( (element) => {
athenaQueryStartFn.addToRolePolicy(element);
});
// Add permissions to the Function fro starting the query
athenaQueryStartFn.addToRolePolicy(new PolicyStatement({
resources: [
stack.formatArn({
region: Aws.REGION,
account: Aws.ACCOUNT_ID,
service: 'athena',
resource: 'workgroup',
resourceName: 'primary',
}),
],
actions: [
'athena:StartQueryExecution',
],
}));
// add permissions to the Function to store result in the result path
athenaQueryStartFn.addToRolePolicy(new PolicyStatement({
resources: [
stack.formatArn({
region: '',
account: '',
service: 's3',
resource: props.resultPath.bucketName,
resourceName: props.resultPath.objectKey,
}),
stack.formatArn({
region: '',
account: '',
service: 's3',
resource: props.resultPath.bucketName,
resourceName: props.resultPath.objectKey + '/*',
}),
stack.formatArn({
region: '',
account: '',
service: 's3',
resource: props.resultPath.bucketName,
}),
],
actions: [
's3:GetBucketLocation',
's3:GetObject',
's3:ListBucket',
's3:ListBucketMultipartUploads',
's3:ListMultipartUploadParts',
's3:AbortMultipartUpload',
's3:PutObject',
's3:CreateBucket',
],
}));
// AWS Lambda function for the AWS CDK Custom Resource responsible to wait for query completion
const athenaQueryWaitFn = new PreBundledFunction(this, 'athenaQueryStartWaitFn', {
runtime: Runtime.PYTHON_3_8,
codePath: 'synchronous-athena-query/resources/lambdas',
handler: 'lambda.is_complete',
logRetention: RetentionDays.ONE_DAY,
timeout: Duration.seconds(20),
});
// Add permissions to the Function
athenaQueryWaitFn.addToRolePolicy(new PolicyStatement({
resources: [
stack.formatArn({
region: Aws.REGION,
account: Aws.ACCOUNT_ID,
service: 'athena',
resource: 'workgroup',
resourceName: 'primary',
}),
],
actions: [
'athena:GetQueryExecution',
'athena:GetQueryResults',
],
}));
// Create an AWS CDK Custom Resource Provider for starting the source crawler and waiting for completion
const synchronousAthenaQueryCRP = new Provider(this, 'synchronousAthenaQueryCRP', {
onEventHandler: athenaQueryStartFn,
isCompleteHandler: athenaQueryWaitFn,
queryInterval: Duration.seconds(10),
totalTimeout: Duration.minutes(props.timeout || 1),
logRetention: RetentionDays.ONE_DAY,
});
const resultPathBucket = Bucket.fromBucketName(this, 'resultPathBucket', props.resultPath.bucketName);
// Create an AWS CDK Custom Resource for starting the source crawler and waiting for completion
new CustomResource(this, 'synchronousAthenaQueryCR', {
serviceToken: synchronousAthenaQueryCRP.serviceToken,
properties: {
Statement: props.statement,
ResultPath: resultPathBucket.s3UrlForObject(props.resultPath.objectKey),
},
});
}