constructor()

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),
      },
    });
  }