The aws:lambda/layerVersion:LayerVersion resource, part of the Pulumi AWS provider, defines a Lambda Layer version: its code package, compatible runtimes and architectures, and metadata. This guide focuses on three capabilities: local and S3-based deployment, runtime and architecture compatibility, and metadata and version management.
Lambda Layers are standalone resources that functions reference to share code and dependencies. S3-based layers require existing S3 objects containing the layer ZIP. The examples are intentionally small. Combine them with your own Lambda functions and permission policies.
Deploy a layer from a local ZIP file
Most deployments package shared code into a ZIP and specify which runtimes can use it.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.lambda.LayerVersion("example", {
code: new pulumi.asset.FileArchive("lambda_layer_payload.zip"),
layerName: "lambda_layer_name",
compatibleRuntimes: ["nodejs20.x"],
});
import pulumi
import pulumi_aws as aws
example = aws.lambda_.LayerVersion("example",
code=pulumi.FileArchive("lambda_layer_payload.zip"),
layer_name="lambda_layer_name",
compatible_runtimes=["nodejs20.x"])
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lambda"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := lambda.NewLayerVersion(ctx, "example", &lambda.LayerVersionArgs{
Code: pulumi.NewFileArchive("lambda_layer_payload.zip"),
LayerName: pulumi.String("lambda_layer_name"),
CompatibleRuntimes: pulumi.StringArray{
pulumi.String("nodejs20.x"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.Lambda.LayerVersion("example", new()
{
Code = new FileArchive("lambda_layer_payload.zip"),
LayerName = "lambda_layer_name",
CompatibleRuntimes = new[]
{
"nodejs20.x",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lambda.LayerVersion;
import com.pulumi.aws.lambda.LayerVersionArgs;
import com.pulumi.asset.FileArchive;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new LayerVersion("example", LayerVersionArgs.builder()
.code(new FileArchive("lambda_layer_payload.zip"))
.layerName("lambda_layer_name")
.compatibleRuntimes("nodejs20.x")
.build());
}
}
resources:
example:
type: aws:lambda:LayerVersion
properties:
code:
fn::FileArchive: lambda_layer_payload.zip
layerName: lambda_layer_name
compatibleRuntimes:
- nodejs20.x
The code property points to your local ZIP file. The compatibleRuntimes property lists which Lambda runtimes can attach this layer. Each deployment creates a new immutable layer version that functions reference by ARN.
Deploy a layer from S3 with multiple runtimes
For larger packages or CI/CD workflows, teams upload layer ZIPs to S3 and reference them by bucket and key.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.lambda.LayerVersion("example", {
s3Bucket: lambdaLayerZip.bucket,
s3Key: lambdaLayerZip.key,
layerName: "lambda_layer_name",
compatibleRuntimes: [
"nodejs20.x",
"python3.12",
],
compatibleArchitectures: [
"x86_64",
"arm64",
],
});
import pulumi
import pulumi_aws as aws
example = aws.lambda_.LayerVersion("example",
s3_bucket=lambda_layer_zip["bucket"],
s3_key=lambda_layer_zip["key"],
layer_name="lambda_layer_name",
compatible_runtimes=[
"nodejs20.x",
"python3.12",
],
compatible_architectures=[
"x86_64",
"arm64",
])
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lambda"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := lambda.NewLayerVersion(ctx, "example", &lambda.LayerVersionArgs{
S3Bucket: pulumi.Any(lambdaLayerZip.Bucket),
S3Key: pulumi.Any(lambdaLayerZip.Key),
LayerName: pulumi.String("lambda_layer_name"),
CompatibleRuntimes: pulumi.StringArray{
pulumi.String("nodejs20.x"),
pulumi.String("python3.12"),
},
CompatibleArchitectures: pulumi.StringArray{
pulumi.String("x86_64"),
pulumi.String("arm64"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.Lambda.LayerVersion("example", new()
{
S3Bucket = lambdaLayerZip.Bucket,
S3Key = lambdaLayerZip.Key,
LayerName = "lambda_layer_name",
CompatibleRuntimes = new[]
{
"nodejs20.x",
"python3.12",
},
CompatibleArchitectures = new[]
{
"x86_64",
"arm64",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lambda.LayerVersion;
import com.pulumi.aws.lambda.LayerVersionArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new LayerVersion("example", LayerVersionArgs.builder()
.s3Bucket(lambdaLayerZip.bucket())
.s3Key(lambdaLayerZip.key())
.layerName("lambda_layer_name")
.compatibleRuntimes(
"nodejs20.x",
"python3.12")
.compatibleArchitectures(
"x86_64",
"arm64")
.build());
}
}
resources:
example:
type: aws:lambda:LayerVersion
properties:
s3Bucket: ${lambdaLayerZip.bucket}
s3Key: ${lambdaLayerZip.key}
layerName: lambda_layer_name
compatibleRuntimes:
- nodejs20.x
- python3.12
compatibleArchitectures:
- x86_64
- arm64
The s3Bucket and s3Key properties replace the code property for S3-based deployment. The compatibleRuntimes and compatibleArchitectures properties let you support multiple languages and CPU architectures in a single layer. AWS recommends S3 for packages larger than a few megabytes.
Add metadata and change detection to layer versions
Production layers benefit from descriptive metadata and automatic versioning when code changes.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as std from "@pulumi/std";
const example = new aws.lambda.LayerVersion("example", {
code: new pulumi.asset.FileArchive("lambda_layer_payload.zip"),
layerName: "multi_runtime_layer",
description: "Shared utilities for Lambda functions",
licenseInfo: "MIT",
sourceCodeHash: std.filebase64sha256({
input: "lambda_layer_payload.zip",
}).then(invoke => invoke.result),
compatibleRuntimes: [
"nodejs18.x",
"nodejs20.x",
"python3.11",
"python3.12",
],
compatibleArchitectures: [
"x86_64",
"arm64",
],
});
import pulumi
import pulumi_aws as aws
import pulumi_std as std
example = aws.lambda_.LayerVersion("example",
code=pulumi.FileArchive("lambda_layer_payload.zip"),
layer_name="multi_runtime_layer",
description="Shared utilities for Lambda functions",
license_info="MIT",
source_code_hash=std.filebase64sha256(input="lambda_layer_payload.zip").result,
compatible_runtimes=[
"nodejs18.x",
"nodejs20.x",
"python3.11",
"python3.12",
],
compatible_architectures=[
"x86_64",
"arm64",
])
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lambda"
"github.com/pulumi/pulumi-std/sdk/go/std"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
invokeFilebase64sha256, err := std.Filebase64sha256(ctx, &std.Filebase64sha256Args{
Input: "lambda_layer_payload.zip",
}, nil)
if err != nil {
return err
}
_, err = lambda.NewLayerVersion(ctx, "example", &lambda.LayerVersionArgs{
Code: pulumi.NewFileArchive("lambda_layer_payload.zip"),
LayerName: pulumi.String("multi_runtime_layer"),
Description: pulumi.String("Shared utilities for Lambda functions"),
LicenseInfo: pulumi.String("MIT"),
SourceCodeHash: pulumi.String(invokeFilebase64sha256.Result),
CompatibleRuntimes: pulumi.StringArray{
pulumi.String("nodejs18.x"),
pulumi.String("nodejs20.x"),
pulumi.String("python3.11"),
pulumi.String("python3.12"),
},
CompatibleArchitectures: pulumi.StringArray{
pulumi.String("x86_64"),
pulumi.String("arm64"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
using Std = Pulumi.Std;
return await Deployment.RunAsync(() =>
{
var example = new Aws.Lambda.LayerVersion("example", new()
{
Code = new FileArchive("lambda_layer_payload.zip"),
LayerName = "multi_runtime_layer",
Description = "Shared utilities for Lambda functions",
LicenseInfo = "MIT",
SourceCodeHash = Std.Filebase64sha256.Invoke(new()
{
Input = "lambda_layer_payload.zip",
}).Apply(invoke => invoke.Result),
CompatibleRuntimes = new[]
{
"nodejs18.x",
"nodejs20.x",
"python3.11",
"python3.12",
},
CompatibleArchitectures = new[]
{
"x86_64",
"arm64",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lambda.LayerVersion;
import com.pulumi.aws.lambda.LayerVersionArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.Filebase64sha256Args;
import com.pulumi.asset.FileArchive;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new LayerVersion("example", LayerVersionArgs.builder()
.code(new FileArchive("lambda_layer_payload.zip"))
.layerName("multi_runtime_layer")
.description("Shared utilities for Lambda functions")
.licenseInfo("MIT")
.sourceCodeHash(StdFunctions.filebase64sha256(Filebase64sha256Args.builder()
.input("lambda_layer_payload.zip")
.build()).result())
.compatibleRuntimes(
"nodejs18.x",
"nodejs20.x",
"python3.11",
"python3.12")
.compatibleArchitectures(
"x86_64",
"arm64")
.build());
}
}
resources:
example:
type: aws:lambda:LayerVersion
properties:
code:
fn::FileArchive: lambda_layer_payload.zip
layerName: multi_runtime_layer
description: Shared utilities for Lambda functions
licenseInfo: MIT
sourceCodeHash:
fn::invoke:
function: std:filebase64sha256
arguments:
input: lambda_layer_payload.zip
return: result
compatibleRuntimes:
- nodejs18.x
- nodejs20.x
- python3.11
- python3.12
compatibleArchitectures:
- x86_64
- arm64
The description and licenseInfo properties document what the layer contains and its licensing terms. The sourceCodeHash property triggers new layer version creation when the ZIP content changes. Without sourceCodeHash, Pulumi won’t detect code changes and won’t create new versions.
Beyond these examples
These snippets focus on specific layer version features: local and S3-based deployment, runtime and architecture compatibility, and metadata and version management. They’re intentionally minimal rather than full sharing solutions.
The examples may reference pre-existing infrastructure such as S3 buckets with layer ZIP files for S3-based deployment. They focus on configuring the layer version rather than provisioning storage or permissions.
To keep things focused, common layer patterns are omitted, including:
- Version retention (skipDestroy property)
- Layer permissions (aws.lambda.LayerVersionPermission resource)
- Cross-account sharing and organization access
- Code signing (signingJobArn, signingProfileVersionArn)
These omissions are intentional: the goal is to illustrate how each layer feature is wired, not provide drop-in sharing modules. See the Lambda LayerVersion resource reference for all available configuration options.
Let's create AWS Lambda Layer Versions
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Deployment & Code Management
code property (e.g., new pulumi.asset.FileArchive("file.zip")) or from S3 using s3Bucket, s3Key, and optionally s3ObjectVersion. These options are mutually exclusive. For larger deployment packages, S3 is recommended because the S3 API has better support for uploading large files efficiently.sourceCodeHash is a required, immutable property that triggers layer replacement when source code changes. It must be a base64-encoded SHA256 hash of your package file. Use filebase64sha256("file.zip") or base64sha256(file("file.zip")) to generate it.Versioning & Lifecycle
skipDestroy is false (the default), changing properties like compatibleArchitectures, compatibleRuntimes, description, layerName, licenseInfo, or sourceCodeHash forces deletion of the existing layer version and creation of a new one.skipDestroy to true prevents Pulumi from destroying layer versions, even when running pulumi destroy. This creates intentional dangling resources that remain in AWS and may incur extra storage costs. Only use this when you need to retain old layer versions permanently.skipDestroy: true to preserve old versions when updating layer configuration. Otherwise, the default behavior (skipDestroy: false) deletes the existing version when you change most properties.Compatibility & Limits
compatibleRuntimes property.x86_64 and arm64 in the compatibleArchitectures property.compatibleRuntimes, such as ["nodejs20.x", "python3.12"], as shown in the S3 source example.Resource Management
layerName, sourceCodeHash, code, compatibleArchitectures, compatibleRuntimes, description, licenseInfo, s3Bucket, s3Key, s3ObjectVersion, and skipDestroy. Changing these forces replacement when skipDestroy is false.Using a different cloud?
Explore serverless guides for other cloud providers: