MicroVm
The MicroVm component lets you run your code in
AWS Lambda MicroVMs:
isolated, stateful sandboxes, each with its own HTTPS endpoint, that live for up to
8 hours. For example, to run code that an AI agent wrote.
The component creates the image. Your app then starts MicroVMs from it, and sends them requests, with the SDK.
Create a MicroVM image
const sandbox = new sst.aws.MicroVm("Sandbox", { image: { context: "./sandbox" }, dev: { command: "node app.js" }});Here ./sandbox has a Dockerfile that starts an app listening on port 8080.
Link it and run MicroVMs
new sst.aws.Function("MyFunction", { handler: "src/lambda.handler", link: [sandbox]});import { Resource } from "sst";import { microvm } from "sst/aws/microvm";
const vm = await microvm.run(Resource.Sandbox);const res = await vm.fetch("/exec", { method: "POST", body: JSON.stringify({ code: "print(1 + 1)" })});await vm.terminate();Reach private resources in a VPC
const vpc = new sst.aws.Vpc("MyVpc", { nat: "ec2" });
new sst.aws.MicroVm("Sandbox", { image: { context: "./sandbox" }, vpc});Limit how long MicroVMs live
A MicroVM you don’t terminate keeps running until it’s idle, or until its duration is
up. These defaults keep that short; change them for long sessions.
new sst.aws.MicroVm("Sandbox", { image: { context: "./sandbox" }, duration: "4 hours", idle: { suspendAfter: "10 minutes", terminateAfter: "1 hour" }});Your account has a quota for the memory of all its MicroVMs in a region, running and
suspended, and each MicroVM has 2 GB. Once it’s reached, microvm.run() fails until
some are terminated. You can ask for more in the Service Quotas console.
Constructor
new MicroVm(name, args?, opts?)Parameters
-
namestring -
args?MicroVmArgs -
opts?ComponentResourceOptions
MicroVmArgs
dev?
Type false | Object
Configure how this component works in sst dev.
By default, the image isn’t built in sst dev. Instead, dev.command runs your app on
your machine, in a tab of the sst dev multiplexer, with the links and the execution
role’s permissions.
In sst dev, the SDK sends the requests of every MicroVM you run to dev.url. So the
MicroVMs aren’t isolated from each other the way they are once deployed.
So that the CLI can assume it, the execution role trusts your AWS account in sst dev,
as Service’s and Task’s roles do. Any IAM user or role in the account whose
policies allow sts:AssumeRole on it can then assume it too.
To build the image and run real MicroVMs in sst dev, pass in false.
dev.command?
Type Input<string>
The command that sst dev runs to start your app.
dev.directory?
Type Input<string>
Default The image.context
The directory the command runs in.
dev.url?
Type Input<string>
Default "http://localhost:8080", with your port
The URL your app listens on in sst dev.
duration?
Type Input<“${number} minute” | “${number} minutes” | “${number} hour” | “${number} hours” | “${number} second” | “${number} seconds”>
Default “1 hour”
The longest a MicroVM can exist, running and suspended. Lambda terminates it after this, up to 8 hours.
This is the default for microvm.run() in the SDK, which can override it.
environment?
Type Input<Record<string, Input<string>>>
Key-value pairs set as environment variables in the image.
They’re part of the image, so changing them rebuilds it. Lambda allows up to 50.
idle?
Type Input<false | Object>
Default { suspendAfter: “15 minutes”, terminateAfter: “15 minutes”, autoResume: true }
When a MicroVM gets no requests for a while, Lambda suspends it, and you stop paying for compute. Its memory and disk are kept. Then, if it stays suspended for too long, Lambda terminates it.
Pass false to keep MicroVMs running until duration is up.
This is the default for microvm.run() in the SDK, which can override it.
idle.autoResume?
Type Input<boolean>
Default true
Resume a suspended MicroVM when a request arrives for it.
idle.suspendAfter?
Type Input<“${number} minute” | “${number} minutes” | “${number} hour” | “${number} hours” | “${number} second” | “${number} seconds”>
Default “15 minutes”
How long a MicroVM can go without a request before it’s suspended. At least 1 minute.
idle.terminateAfter?
Type Input<“${number} minute” | “${number} minutes” | “${number} hour” | “${number} hours” | “${number} second” | “${number} seconds”>
Default “15 minutes”
How long a MicroVM can stay suspended before it’s terminated.
image?
Type Input<Object>
Default { context: ”.”, dockerfile: “Dockerfile” }
The image to run. Lambda builds it from your Dockerfile, on top of its Amazon Linux
2023 base image.
SST zips the context directory, puts the dockerfile at the root of the zip, and
uploads it. Lambda builds the image from the zip, starts your app, and takes a snapshot
that every MicroVM starts from. So your app starts once, at build time: anything it
does on startup, like reading the time or generating an ID, is the same in every
MicroVM.
A build takes a few minutes, and runs again whenever the code, the environment or a
link’s values change. If it fails, the deploy fails, and the build’s logs are in the
log group. MicroVMs keep starting from the last version that built.
Each build adds a version to the image, and Lambda allows 50. After a build, SST deletes the old ones. It keeps the newest 5 that built, and any that MicroVMs still run from.
Lambda runs the Dockerfile itself, so Docker build args, targets, secrets and caches
don’t apply. Files matched by a .dockerignore in the context aren’t uploaded, and
neither are the sst-env.d.ts files SST generates, so writing them doesn’t rebuild
the image.
{ image: { context: "./sandbox", dockerfile: "Dockerfile" }}image.context?
Type Input<string>
Default ”.”
The path to the directory that’s zipped and uploaded, relative to your project root.
image.dockerfile?
Type Input<string>
Default “Dockerfile”
The path to the Dockerfile, relative to the context.
link?
Type Input<any[]>
Link resources to your MicroVMs. This grants the execution role the permissions of the linked resources, and sets them as environment variables in the image, so your app can read them through the SDK.
Changing a linked resource’s values rebuilds the image.
To read them with Resource, add sst to your app’s dependencies. It comes with the
SST CLI, about 75 MB, as an optional dependency that your app doesn’t need. To leave it
out of the image, install with npm install --omit=optional.
{ link: [bucket]}logging?
Type Input<Object>
Default { retention: “1 month” }
Configure the log group for your MicroVMs’ logs.
logging.retention?
Type Input<“1 day” | “3 days” | “5 days” | “1 week” | “2 weeks” | “1 month” | “2 months” | “3 months” | “4 months” | “5 months” | “6 months” | “1 year” | “13 months” | “18 months” | “2 years” | “3 years” | “5 years” | “6 years” | “7 years” | “8 years” | “9 years” | “10 years” | “forever”>
Default “1 month”
How long to keep the logs.
permissions?
Type Input<Object[]>
Permissions and the resources that your MicroVMs need to access. They’re added to the execution role.
{ permissions: [ { actions: ["bedrock:InvokeModel"], resources: ["*"] } ]}permissions[].actions
permissions[].conditions?
Type Input<Input<Object>[]>
Configure specific conditions for when the policy is in effect.
{ conditions: [ { test: "StringEquals", variable: "s3:x-amz-server-side-encryption", values: ["AES256"] }, { test: "IpAddress", variable: "aws:SourceIp", values: ["10.0.0.0/16"] } ]}permissions[].conditions[].test
Type Input<string>
Name of the IAM condition operator to evaluate.
permissions[].conditions[].values
Type Input<Input<string>[]>
The values to evaluate the condition against. If multiple values are provided, the condition matches if at least one of them applies. That is, AWS evaluates multiple values as though using an “OR” boolean operation.
permissions[].conditions[].variable
Type Input<string>
Name of a Context Variable to apply the condition to. Context variables may either be standard AWS variables starting with aws: or service-specific variables prefixed with the service name.
permissions[].effect?
Type “allow” | “deny”
Default “allow”
Configures whether the permission is allowed or denied.
{ effect: "deny"}permissions[].resources
Type Input<Input<string>[]>
The resourcess specified using the IAM ARN format.
{ resources: ["arn:aws:s3:::my-bucket/*"]}port?
Type Input<number>
Default 8080
The port your app listens on. The SDK sends requests to this port.
transform?
Type Object
Transform how this component creates its underlying resources.
transform.buildRole?
Type RoleArgs | (args: RoleArgs, opts: ComponentResourceOptions, name: string) => void
Transform the IAM role Lambda uses to build the image.
transform.executionRole?
Type RoleArgs | (args: RoleArgs, opts: ComponentResourceOptions, name: string) => void
Transform the IAM role your MicroVMs run with.
transform.image?
Type ImageArgs | (args: ImageArgs, opts: ComponentResourceOptions, name: string) => void
Transform the MicroVM image resource.
transform.logGroup?
Type LogGroupArgs | (args: LogGroupArgs, opts: ComponentResourceOptions, name: string) => void
Transform the CloudWatch log group.
transform.networkConnector?
Type CoreNetworkConnectorArgs | (args: CoreNetworkConnectorArgs, opts: ComponentResourceOptions, name: string) => void
Transform the Lambda network connector, created when vpc is set.
transform.operatorRole?
Type RoleArgs | (args: RoleArgs, opts: ComponentResourceOptions, name: string) => void
Transform the IAM role Lambda uses to create the network connector’s network interfaces in the VPC.
vpc?
Type Vpc | Input<Object>
Send your MicroVMs’ outbound traffic through the private subnets of a VPC, so they can reach private resources, like a database.
Requests to a MicroVM still come in through its HTTPS endpoint. Only its outbound traffic goes through the VPC, and it reaches the internet only through the VPC’s NAT.
This creates a Lambda network connector that every MicroVM is run with. Creating it takes about 5 minutes. Lambda’s docs say to terminate the MicroVMs that use it before it’s changed or removed.
Create a Vpc component, with a NAT if your MicroVMs need the internet.
const myVpc = new sst.aws.Vpc("MyVpc", { nat: "ec2" });And pass it in.
{ vpc: myVpc}Or pass in the subnets and security groups of an existing VPC.
{ vpc: { privateSubnets: ["subnet-0b6a2b73896dc8c4c", "subnet-021389ebee680c2f0"], securityGroups: ["sg-0399348378a4c256c"] }}vpc.privateSubnets
Type Input<Input<string>[]>
A list of VPC subnet IDs.
vpc.securityGroups
Type Input<Input<string>[]>
A list of VPC security group IDs.
Properties
arn
Type undefined | Output<string>
The ARN of the MicroVM image. Not created in sst dev, unless dev is false.
nodes
Type Object
The underlying resources this component creates.
nodes.buildRole
Type undefined | Role
The IAM role Lambda uses to build the image.
nodes.executionRole
Type Role
The IAM role your MicroVMs run with.
nodes.image
Type undefined | Image
The MicroVM image. Not created in sst dev, unless dev is false.
nodes.logGroup
Type LogGroup
The CloudWatch log group.
nodes.networkConnector
Type undefined | CoreNetworkConnector
The Lambda network connector. Only created when vpc is set, and not in
sst dev.
SDK
Use the SDK in your runtime to interact with your infrastructure.
The microvm client SDK is available through the following.
import { microvm } from "sst/aws/microvm";If you are not using Node.js, you can use the AWS SDK instead, with the link data in
Resource. For example, call
RunMicrovm
with its imageArn, imageVersion and executionRoleArn.
get
microvm.get(resource, id, options?)Parameters
Returns Promise<MicroVm>
Gets a MicroVM that’s already running, by its ID. Use this to reach the same MicroVM from a later request.
const vm = await microvm.get(Resource.Sandbox, id);const res = await vm.fetch("/status");run
microvm.run(resource, options?)Parameters
-
resourceResource -
options?RunOptions
Returns Promise<MicroVm>
Runs a new MicroVM from the image, and waits until it’s running.
For example, let’s say you have a MicroVM image.
new sst.aws.MicroVm("Sandbox", { image: { context: "./sandbox" } });Run a MicroVM from it, send it requests, and terminate it.
import { Resource } from "sst";import { microvm } from "sst/aws/microvm";
const vm = await microvm.run(Resource.Sandbox);const res = await vm.fetch("/hello");await vm.terminate();In sst dev, this doesn’t start a MicroVM. The requests go to your app running on
your machine, and terminate does nothing.
DescribeResponse
Type Object
DescribeResponse.id
Type string
The ID of the MicroVM.
DescribeResponse.response
Type any
The raw response from the AWS API.
DescribeResponse.state
Type State
The state of the MicroVM. AWS updates it eventually, so it can lag behind.
DescribeResponse.stateReason?
Type string
Why the MicroVM is in this state.
DescribeResponse.url
Type string
The URL of the MicroVM.
FetchInit
Type Object
FetchInit.port?
Type number
The port to send the request to, if not the component’s port.
MicroVm
MicroVm.id
Type string
The ID of the MicroVM. Keep it to reach the same MicroVM later, with get.
MicroVm.url
Type string
The URL of the MicroVM. A request to it needs a token from token, in the
X-aws-proxy-auth header. fetch adds it for you.
MicroVm.describe
MicroVm.fetch
fetch(path, init?)Parameters
-
pathstring -
init?FetchInit
Returns Promise<Response<>>
Sends a request to the app in the MicroVM. It works like fetch, with a path
instead of a URL, and adds the token.
const res = await vm.fetch("/exec", { method: "POST", body: JSON.stringify({ code })});MicroVm.resume
resume()Returns Promise<void>
Resumes a suspended MicroVM.
MicroVm.suspend
suspend()Returns Promise<void>
Suspends the MicroVM. Its memory and disk are kept, and you stop paying for compute.
MicroVm.terminate
terminate()Returns Promise<void>
Terminates the MicroVM.
MicroVm.token
token(port?)Parameters
-
port?number
Returns Promise<string>
A token for requests to a port of the MicroVM, valid for up to an hour. fetch
refreshes it before it expires. Use this to let something else, like a browser,
reach the MicroVM.
Options
Type Object
Options.aws?
Resource
Type Object
Resource.dev?
Type Object
Set in sst dev, where the app runs on your machine.
Resource.dev.url
Type string
Resource.duration?
Type number
The longest a MicroVM can exist, in seconds.
Resource.egressNetworkConnectors?
Type string[]
The network connectors a MicroVM reaches the internet through.
Resource.executionRoleArn?
Type string
The ARN of the role MicroVMs run with.
Resource.idle?
Type IdlePolicy
When an idle MicroVM is suspended, and then terminated.
Resource.imageArn?
Type string
The ARN of the MicroVM image.
Resource.imageVersion?
Type string
The version of the image that was deployed.
Resource.ingressNetworkConnectors?
Type string[]
The network connectors that let requests reach a MicroVM.
Resource.logGroup?
Type string
The log group the MicroVMs’ logs go to.
Resource.port
Type number
The port the app in a MicroVM listens on.
RunOptions
Type Object
-
idle?false|Object
RunOptions.aws?
RunOptions.duration?
Type “${number} second” | “${number} seconds” | “${number} minute” | “${number} minutes” | “${number} hour” | “${number} hours”
Overrides the component’s duration: the longest this MicroVM can exist, running
and suspended. Up to 8 hours.
RunOptions.idle?
Type false | Object
Overrides the component’s idle. Pass false to keep this MicroVM running until
its duration is up.
RunOptions.idle.autoResume?
Type boolean
RunOptions.idle.suspendAfter?
Type “${number} second” | “${number} seconds” | “${number} minute” | “${number} minutes” | “${number} hour” | “${number} hours”
RunOptions.idle.terminateAfter?
Type “${number} second” | “${number} seconds” | “${number} minute” | “${number} minutes” | “${number} hour” | “${number} hours”
RunOptions.timeout?
Type “${number} second” | “${number} seconds” | “${number} minute” | “${number} minutes” | “${number} hour” | “${number} hours”
Default “1 minute”
How long run waits for the MicroVM to be running.