Skip to content

(aws-lambda-python): cache Docker layer with dependencies #23829

@m-radzikowski

Description

@m-radzikowski

Describe the feature

Bundling Python Lambdas that contain requirements.txt, Pipfile, or poetry.lock file happens in a Docker container. Firstly, the requirements.txt file is generated (for pipenv and Poetry), and then dependencies are installed.

However, this happens each time any code change is made. Each time you change Lambda code (not its dependencies), the Docker build performs the above steps, downloading libraries from the internet.

This is the responsible code:

private createBundlingCommand(options: BundlingCommandOptions): string[] {
const packaging = Packaging.fromEntry(options.entry, options.poetryIncludeHashes);
let bundlingCommands: string[] = [];
bundlingCommands.push(...options.commandHooks?.beforeBundling(options.inputDir, options.outputDir) ?? []);
bundlingCommands.push(`cp -rTL ${options.inputDir}/ ${options.outputDir}`);
bundlingCommands.push(`cd ${options.outputDir}`);
bundlingCommands.push(packaging.exportCommand ?? '');
if (packaging.dependenciesFile) {
bundlingCommands.push(`python -m pip install -r ${DependenciesFile.PIP} -t ${options.outputDir}`);
}
bundlingCommands.push(...options.commandHooks?.afterBundling(options.inputDir, options.outputDir) ?? []);
return bundlingCommands;
}
}

Dependencies change far less often than the code. Best practices for building in Docker are to firstly download dependencies and only then copy the code. This allows the dependencies layer to be cached, and on consecutive runs, only the code is updated while the dependencies layer is cached.

Use Case

This will greatly reduce consecutive Lambda bundling times, as dependencies will be fetched from the internet only when they change. When only the code changes, a cached Docker layer with dependencies will be used.

Proposed Solution

In short, bundling Python Lambda should be changed from:

  1. Copy all source files (line 113)
  2. Generate requirements.txt (line 115)
  3. Install dependencies (line 117)

to:

  1. Copy dependencies files (i.e. poetry.lock)
  2. Generate requirements.txt
  3. Install dependencies
  4. Copy the rest of the files

Other Information

I am willing to implement it after greenlighting by the CDK team.

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

CDK version used

2.61.1

Environment details (OS name and version, etc.)

any

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions