The aws:lambda/layerVersion:LayerVersion resource, part of the Pulumi AWS provider, publishes a versioned Lambda Layer that packages shared code and dependencies for reuse across multiple Lambda functions. This guide focuses on three capabilities: local and S3-based deployment, runtime and architecture compatibility, and change detection.
Layers are standalone resources that functions reference by ARN. S3-based layers require existing S3 objects containing the layer ZIP. The examples are intentionally small. Combine them with your own Lambda functions and layer 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; functions using other runtimes cannot reference it. Each deployment creates a new immutable layer version.
Deploy a layer from S3 with multiple runtimes
For larger packages or CI/CD workflows, S3 provides better upload performance and integrates with existing artifact storage.
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 reference an existing S3 object containing your layer ZIP. The compatibleRuntimes property supports multiple runtime families (Node.js and Python here), while compatibleArchitectures declares support for both x86_64 and arm64 Lambda functions.
Add metadata and change detection to layers
Production layers benefit from descriptive metadata and automatic redeployment 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 layer version creation when the ZIP file changes; use filebase64sha256 to compute the hash from your local file. This ensures functions always get the latest code without manual version management.
Beyond these examples
These snippets focus on specific layer-level features: local and S3-based deployment, runtime and architecture compatibility, and metadata and change detection. 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 publishing the layer rather than provisioning storage or configuring function access.
To keep things focused, common layer patterns are omitted, including:
- Version retention (skipDestroy property)
- Layer permissions for cross-account access
- Integration with Lambda functions (layers property on Function resource)
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
You have two options:
- Local file - Use
codewithFileArchive:code: new pulumi.asset.FileArchive("file.zip") - S3 bucket - Use
s3Bucket,s3Key, and optionallys3ObjectVersion
These options conflict; you cannot use both simultaneously.
sourceCodeHash to a base64-encoded SHA256 hash of your package file using filebase64sha256("file.zip") or base64sha256(file("file.zip")). When the hash changes, Pulumi creates a new layer version.Versioning & Lifecycle
skipDestroy is true, Pulumi won’t destroy layer versions even during pulumi destroy. These become intentional dangling resources that remain in your AWS account and may incur extra storage expense. The default is false.skipDestroy is false (default), changing properties like compatibleRuntimes, description, layerName, licenseInfo, sourceCodeHash, or deployment source forces deletion of the existing layer version and creation of a new one.layerArn is the ARN without version (e.g., arn:aws:lambda:region:account:layer:name), while arn includes the version number (e.g., arn:aws:lambda:region:account:layer:name:1).Compatibility & Configuration
compatibleRuntimes list.x86_64 and arm64 architectures, specified via the compatibleArchitectures property.Common Issues
code property conflicts with the S3-prefixed options (s3Bucket, s3Key, s3ObjectVersion). You must choose either local file deployment or S3 deployment, not both.compatibleRuntimes you specify. Each runtime has specific directory structure requirements for layer contents.Using a different cloud?
Explore serverless guides for other cloud providers: