Aws-cdk: [lambda-python] Abstraction for bundling code for use in either a Function or a Layer

Created on 24 Aug 2020  路  5Comments  路  Source: aws/aws-cdk

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.

Use Case

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).

Proposed Solution

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

Other

  • [ ] :wave: I may be able to implement this feature request
  • [ ] :warning: This feature might incur a breaking change

This is a :rocket: Feature Request

@aws-cdaws-lambda-python efforsmall feature-request p2

Most helpful comment

FYI, layer support will be coming soon in https://github.com/aws/aws-cdk/pull/9582

All 5 comments

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

鈿狅笍COMMENT VISIBILITY WARNING鈿狅笍

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nzspambot picture nzspambot  路  3Comments

cybergoof picture cybergoof  路  3Comments

mirazmamun picture mirazmamun  路  3Comments

eladb picture eladb  路  3Comments

pepastach picture pepastach  路  3Comments