The current bundling function that drives PythonFunction contains 99% of what I need to accomplish building a Layer, but doesn't allow me to place assets into runtime-specific directories.
It would be nice if there were a publicized construct of some sort that encapsulated the knowledge about runtime specific paths, and contained the bundling code that could be used for either a PythonFunction or a python-based Layer.
This would make integrating layer code into function code more intuitive since a python layer would put the code and dependencies in the right /opt path for me. It would also cut down on the amount of code currently needed to build a layer, which is almost completely redundant of what is currently in the bundle functions (for both lambda-nodejs and lambda-python).
I hacked this quickly by allowing an output subdirectory as part of my bundle options. But an abstraction that houses all those runtime specific paths and drops code into them would be cool.
/**
* Options for bundling
*/
export interface BundlingOptions {
/**
* Entry path
*/
readonly entry: string;
/**
* The runtime of the lambda function
*/
readonly runtime: lambda.Runtime;
/**
* Subdirectory in which to place bundled assets inside the output directory
*
* This is useful if building a layer and you need to place
* bundled assets inside the AWS specified runtime folders.
*
* e.g. /python for Python
*
* @default ""
*/
readonly outputSubdirectory?: string;
}
enum Installer {
PIP = 'pip',
PIP3 = 'pip3',
}
function chain(commands: string[]): string {
return commands.filter((c) => !!c).join(' && ');
}
/**
* Produce bundled Lambda asset code
*/
export function bundle(options: BundlingOptions): lambda.AssetCode {
const installer = options.runtime === lambda.Runtime.PYTHON_2_7 ? Installer.PIP : Installer.PIP3;
const outputSubdirectory = options.outputSubdirectory || '';
const targetDirectory = path.join(cdk.AssetStaging.BUNDLING_OUTPUT_DIR, outputSubdirectory);
const hasRequirements = fs.existsSync(path.join(options.entry, 'requirements.txt'));
const depsCommand = chain([
hasRequirements ? `${installer} install -r requirements.txt -t ${targetDirectory}` : '',
`cp -r . ${targetDirectory}`,
]);
return lambda.Code.fromAsset(options.entry, {
bundling: {
image: BundlingDockerImage.fromRegistry(`amazon/aws-sam-cli-build-image-${options.runtime.name}`),
command: ['bash', '-c', depsCommand],
},
});
}
This is a :rocket: Feature Request
FYI, layer support will be coming soon in https://github.com/aws/aws-cdk/pull/9582
Sounds useful. Would be happy to take a contribution
Thanks to some discussion and redesign, #9582 should also close this issue.
This was closed out by #9582 cc @eladb @SomayaB
Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.
Most helpful comment
FYI, layer support will be coming soon in https://github.com/aws/aws-cdk/pull/9582