Created
April 22, 2024 05:01
-
-
Save tmokmss/aeb85fc8c3076cbc5d9ae1c6698969d1 to your computer and use it in GitHub Desktop.
Cross region AWS API proxy for Step Functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Handler } from 'aws-lambda'; | |
type Input = { | |
/** | |
* AWS Region name to call the service | |
*/ | |
targetRegion: string; | |
/** | |
* AWS service name (must be in AWS SDK for JS v3 style) | |
*/ | |
service: string; | |
/** | |
* API Action name (must be in PascalCase) | |
*/ | |
action: string; | |
/** | |
* request parameters to call the API (must be in AWS SDK for JS v3 style) | |
*/ | |
parameters: any; | |
}; | |
// reference: code from CDK AwsCustomResource | |
function findV3ClientConstructor(pkg: object) { | |
const [_clientName, ServiceClient] = Object.entries(pkg).find(([name]) => { | |
// Services expose a base __Client class that we don't want ever | |
return name.endsWith('Client') && name !== '__Client'; | |
}) as [ | |
string, | |
{ | |
new (config: any): { | |
send: (command: any) => Promise<any>; | |
config: any; | |
}; | |
}, | |
]; | |
return ServiceClient; | |
} | |
function findCommandClass(pkg: object, action: string) { | |
const commandName = `${action}Command`; | |
const Command = Object.entries(pkg).find(([name]) => name.toLowerCase() === commandName.toLowerCase())?.[1] as { | |
new (input: any): any; | |
}; | |
if (!Command) { | |
throw new Error(`Unable to find command named: ${commandName} for action: ${action} in service package ${pkg}`); | |
} | |
return Command; | |
} | |
export const handler: Handler<Input> = async (event, context) => { | |
// Log the event to understand the incoming request structure | |
console.log('Event: ', event); | |
try { | |
// eslint-disable-next-line @typescript-eslint/no-var-requires | |
const pkg = require(`@aws-sdk/client-${event.service}`); | |
const Client = findV3ClientConstructor(pkg); | |
const Command = findCommandClass(pkg, event.action); | |
const client = new Client({ region: event.targetRegion }); | |
const command = new Command(event.parameters); | |
const res = await client.send(command); | |
return res; | |
} catch (error) { | |
console.error('Error: ', error); | |
throw error; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment