View a markdown version of this page

Create your first Lambda MicroVM - Amazon Lambda
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Create your first Lambda MicroVM

This tutorial walks you through creating a Amazon Lambda MicroVM image and running a MicroVM from it. By the end, you'll have a running application accessible over HTTPS.

Prerequisites

You need two things before you start:

  1. An Amazon S3 bucket in your preferred Amazon Region to store your application artifact (the zip file you'll create in Step 2).

  2. An IAM build role that Lambda assumes during image creation. Lambda uses this role to download your code artifact from Amazon S3 and write build logs to CloudWatch.

Create the IAM role with the following trust policy. This allows the Lambda service to assume the role:

{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": ["sts:AssumeRole", "sts:TagSession"] }] }

Attach the following permissions policy to the role. Replace <your-bucket-name> with your Amazon S3 bucket name:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::<your-bucket-name>/*" }, { "Effect": "Allow", "Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"], "Resource": "arn:aws:logs:*:*:*" } ] }
Note

If your Dockerfile pulls from a private Amazon ECR repository, also add ecr:GetAuthorizationToken and ecr:BatchGetImage to the permissions policy.

Creating your first MicroVM image

A MicroVM image captures your application in a fully initialized state. When you run a MicroVM from this image, your application starts immediately – no boot or initialization delay.

Step 1: Write your application and Dockerfile

Create a simple HTTP server that will run inside your MicroVM. This example uses Node.js with no external dependencies:

app.js

// Minimal HTTP server — listens on port 8080 const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ status: 'ok', path: req.url })); }); server.listen(8080, () => { console.log('Listening on port 8080'); });

Next, create a Dockerfile that packages and starts your application:

Dockerfile

# Use a lightweight Node.js runtime for your application layers FROM node:24-alpine # Set the working directory inside the container WORKDIR /app # Copy your application code COPY app.js . # Declare the port your app listens on EXPOSE 8080 # Start the application — Lambda snapshots the running state CMD ["node", "app.js"]
Note

The FROM instruction sets the container image for your application layers. You can use any compatible container image. The Lambda managed base image (which provides the MicroVM operating system and service components) is specified separately with --base-image-arn in Step 3.

If your application generates unique values (IDs, secrets, or cryptographic material), use your language's standard cryptographically secure pseudorandom number generator (CSPRNG) library to ensure uniqueness across MicroVMs. If your application uses OpenSSL, use the Lambda base container image which includes a snapshot-compatible version. For details, see the snapshot compatibility section in MicroVM Images.

Step 2: Package and upload to Amazon S3

Package your app.js and Dockerfile into a zip archive, then upload it to your Amazon S3 bucket. Run the following commands in your terminal:

zip app.zip app.js Dockerfile aws s3 cp app.zip s3://your-bucket-name/app.zip

Step 3: Create the MicroVM image

Call create-microvm-image to start the build. Lambda downloads your zip from Amazon S3, runs your Dockerfile, starts your application, and captures a Firecracker snapshot of the fully initialized state:

aws lambda-microvms create-microvm-image \ --name my-first-microvm-image \ --code-artifact uri=s3://your-bucket-name/app.zip \ --base-image-arn arn:aws:lambda:us-east-1:aws:microvm-image:al2023-1 \ --build-role-arn arn:aws:iam::123456789012:role/MicrovmBuildRole

The image starts in CREATING state. Check the build status with:

aws lambda-microvms get-microvm-image \ --image-identifier my-first-microvm-image

When the build completes, the state field changes to CREATED:

{ "imageName": "my-first-microvm-image", "imageArn": "arn:aws:lambda:us-east-1:123456789012:microvm-image:my-first-microvm-image", "state": "CREATED", "imageVersion": "1.0", ... }

If the state is CREATE_FAILED, check the build logs in CloudWatch under /aws/lambda/microvms/my-first-microvm-image.

Running your first MicroVM

Once your MicroVM image reaches CREATED state, you can run MicroVMs from it. Each image can launch many MicroVMs – one per tenant, user session, or job.

Run a MicroVM with the following command:

aws lambda-microvms run-microvm \ --image-identifier my-first-microvm-image \ --ingress-network-connectors "arn:aws:lambda:us-east-1:aws:network-connector:aws-network-connector:ALL_INGRESS" \ --egress-network-connectors "arn:aws:lambda:us-east-1:aws:network-connector:aws-network-connector:INTERNET_EGRESS" \ --idle-policy '{"autoResumeEnabled":true,"maxIdleDurationSeconds":900,"suspendedDurationSeconds":300}'

Parameters explained:

  • --ingress-network-connectors – Enables inbound HTTPS traffic to your MicroVM on all ports. This is a Lambda-managed connector.

  • --egress-network-connectors – Enables outbound internet access from your MicroVM. This is a Lambda-managed connector.

  • --idle-policy – Configures automatic suspend-resume behavior. This policy suspends the MicroVM after 15 minutes of inactivity, keeps it suspended for up to 5 minutes, and resumes automatically when traffic arrives.

The response includes the MicroVM ID and endpoint URL:

{ "microvmId": "mvm-01234567-abcd-ef01-2345-6789abcdef01", "state": "PENDING", "endpoint": "mvm-01234567-abcd-ef01-2345-6789abcdef01.lambda-microvm.us-east-1.on.aws", ... }

Wait for the state to reach RUNNING:

aws lambda-microvms get-microvm \ --microvm-identifier mvm-01234567-abcd-ef01-2345-6789abcdef01

Connecting to your MicroVM

All requests to a MicroVM endpoint require an authentication token. Generate one with:

aws lambda-microvms create-microvm-auth-token \ --microvm-identifier mvm-01234567-abcd-ef01-2345-6789abcdef01 \ --expiration-in-minutes 30 \ --allowed-ports '[{"allPorts":{}}]'

The response includes a token in the authToken field. Use it to send a request to your running application:

curl https://mvm-01234567-abcd-ef01-2345-6789abcdef01.lambda-microvm.us-east-1.on.aws/ \ -H "X-aws-proxy-auth: <token-value>"

You should see the response from your application:

{"status":"ok","path":"/"}

Your MicroVM is running and serving traffic. The application you wrote in Step 1 is live at the endpoint URL.

Clean up

To avoid ongoing charges, terminate the MicroVM when you're done:

aws lambda-microvms terminate-microvm \ --microvm-identifier mvm-01234567-abcd-ef01-2345-6789abcdef01

Next steps

  • Learn about Core concepts to understand the snapshot process, lifecycle states, and base images.

  • Explore MicroVM Images to learn about image build hooks, versioning, and snapshot compatibility.

  • See Running MicroVMs for SDK examples, lifecycle hooks, and scaling strategies.