Lambda layers
Layers are attached to generated functions through LambdaApiConfig and
@layer. Use LambdaApi
as the entry point.
Common and named layers
Pass existing CDK layer objects in layers or add them with
add_common_layer. They are attached to every generated function:
from aws_cdk import aws_lambda as lambda_
from lambda_api_decorators import GET, layer
from lambda_api_decorators_cdk import LambdaApi, LambdaApiConfig
config = LambdaApiConfig(layers=[shared_layer])
config.register_layer("database", database_layer)
@GET("/orders")
@layer("database")
def orders(event, context):
return {"statusCode": 200, "body": "ok"}
api = LambdaApi(self, "Api", lambda_path="lambdas", config=config)
shared_layer is common to all functions; database_layer is added only to
orders. The resulting order is common layers first, followed by the selected
named layers. Common layer objects are de-duplicated when added through the
config mutator. A named layer must be an ILayerVersion object.
Autodiscovery with layers_path
layers_path is a LambdaApi constructor argument. It is not a
LambdaApiConfig argument:
api = LambdaApi(
self,
"Api",
lambda_path="lambdas",
layers_path="layers",
config=LambdaApiConfig(default_runtime="python3.14"),
)
Each eligible direct child directory of layers_path is a candidate named by
its directory name. A candidate is constructed only when a handler uses that
exact name with @layer("name"). Hidden entries and __pycache__ are ignored;
files and file symlinks are not candidates, while directory symlinks are.
Nested directories remain part of the parent layer rather than becoming names
of their own.
The expected layout is:
project/
├── lambdas/
│ ├── orders.py
│ └── requirements.txt # normal function dependencies
├── layers/
│ └── database/
│ ├── requirements.txt
│ └── python/ # optional layer source/package tree
└── stack.py
The directory itself is passed as the entry to CDK's
PythonLayerVersion. Put Python dependencies for that layer in its
layers/database/requirements.txt, following the CDK Python layer packaging
contract. Dependencies shared by normal functions belong in
lambdas/requirements.txt (or the corresponding packaging root selected by
SourceLayout);
that file is not a Lambda layer.
Autodiscovered layers require an effective Python runtime. The builder derives
their compatible runtimes from the handlers that request them. If no concrete
runtime exists, or the effective runtime is not Python, construction raises
ValueError.
Verified failure behavior
The current implementation and tests establish these cases:
- a missing
layers_path, or a path that is not a directory, raisesValueError; - an unknown
@layername raisesKeyError; - an explicit
register_layerentry wins over an autodiscovered directory of the same name, and that directory is not constructed; - incompatible explicit/common layers raise
ValueErrorwhen their exposed compatibility metadata does not include the effective runtime; - unreadable or unusable layer compatibility metadata raises
ValueError.
Repeated layer declarations are retained as repeated selections. The builder also de-duplicates runtime names when calculating the compatibility list for an autodiscovered layer. No broader duplicate-directory behavior is documented because the checked code does not define a separate duplicate-directory case.
For lower-level builds, ResourceBuilder.build
and build_http expose the same layers_path behavior; ResourceBuilder is
an advanced alternative, not the recommended starting point.