All files / src/handler/utils aws-clients.ts

100% Statements 93/93
100% Branches 7/7
100% Functions 1/1
100% Lines 93/93

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 941x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 1x 1x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 4x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
 
import { ConnectClient } from "@aws-sdk/client-connect";
import { GlueClient } from "@aws-sdk/client-glue";
import { LakeFormationClient } from "@aws-sdk/client-lakeformation";
import { RAMClient } from "@aws-sdk/client-ram";
import { STSClient, AssumeRoleCommand, AssumeRoleCommandOutput } from "@aws-sdk/client-sts";
import type { AwsCredentialIdentity } from "@aws-sdk/types";
 
/**
 * AWS service clients for Connect data lake integration operations
 */
export interface AwsClients {
  /**
   * Amazon Connect client for managing Connect analytics dataset associations
   * */
  connect: ConnectClient;
 
  /**
   * AWS Glue client for managing Glue Data Catalog databases and resource link tables
   * */
  glue: GlueClient;
 
  /**
   * Lake Formation client for managing data lake settings and permissions
   * */
  lakeformation: LakeFormationClient;
 
  /**
   * Resource Access Manager client for accepting resource share invitations
   * */
  ram: RAMClient;
}
 
/**
 * Creates AWS service clients for source and target accounts
 *
 * @param lambdaAccountId - AWS account ID where Lambda is executing
 * @param targetAccountId - AWS account ID where resources will be created
 * @param roleArn - ARN of the role to assume for operations
 * @returns AwsClients
 */
export async function createAwsClients(
  lambdaAccountId: string,
  targetAccountId: string,
  roleArn: string,
): Promise<AwsClients> {
  const config = {
    region: process.env.AWS_REGION!,
    retryMode: "adaptive",
  };
 
  // Same-account operations
  if (lambdaAccountId === targetAccountId) {
    return {
      connect: new ConnectClient(config),
      glue: new GlueClient(config),
      lakeformation: new LakeFormationClient(config),
      ram: new RAMClient(config),
    };
  }
 
  // Cross-account operations
  console.info(`Assuming cross-account role: ${roleArn}`);
 
  const assumeRoleResponse: AssumeRoleCommandOutput = await new STSClient(config).send(
    new AssumeRoleCommand({
      RoleArn: roleArn,
      RoleSessionName: "connect-datalake-operation",
    }),
  );
 
  const creds = assumeRoleResponse.Credentials;
  if (!creds?.AccessKeyId || !creds?.SecretAccessKey || !creds?.SessionToken) {
    throw new Error(`Invalid credentials from assume role`);
  }
 
  const credentials: AwsCredentialIdentity = {
    accessKeyId: creds.AccessKeyId,
    secretAccessKey: creds.SecretAccessKey,
    sessionToken: creds.SessionToken,
  };
 
  const targetConfig = { ...config, credentials };
 
  return {
    connect: new ConnectClient(config), // Association operations occur with deployment account credentials
    glue: new GlueClient(targetConfig),
    lakeformation: new LakeFormationClient(targetConfig),
    ram: new RAMClient(targetConfig),
  };
}