DEV Community

Cover image for AWS Lambda MicroVMs: How to create isolated code environments per user

AWS Lambda MicroVMs: How to create isolated code environments per user

AWS Lambda MicroVMs is a lightweight virtualization technology that enables the creation of secure, isolated environments with a duration of up to 8 hours, which suspend at no compute cost when idle.

In this article we'll explore the experiences and challenges I faced while building a lab to evaluate Python function knowledge, providing each user with a code-server interface (VS Code web) where they could edit their code and run automated tests.

1. Benefits

  • Isolated code execution using Firecracker: These are not containers. When you first discover the service you might confuse it with containers, but they are actually virtual machines with their own kernel and hardware-level isolation.
  • Serverless: You get isolated servers with no networks or load balancers to configure — just define your Dockerfile and start using them.
  • Flexible vertical scaling: Up to 4x the configured base resources.
  • Millisecond startup: It restores from a pre-built snapshot; in seconds your app is already running.
  • No compute charges while suspended: When there is no traffic, the application suspends preserving disk and memory.
  • JWE Authentication: Each endpoint is protected by a token with configurable expiration.
  • Basic build model: Dockerfile > Code > Snapshot > Launch N MicroVMs from that base image

2. Use cases

  • Isolated development platforms per user
  • Security testing and scanning isolation, preventing malicious code from affecting other resources
  • Isolated environments with specific configurations for data analysis

3. Containers running inside Lambdas?

The answer is no. When using a Dockerfile, we might assume that's what's happening, but the Dockerfile plays a different role here. Lambda uses it only to define what needs to be installed and how to start the application during the build phase. The result is not a Docker image that runs as a container, but a Firecracker snapshot.

4. What happens behind the build model?

  • The Dockerfile defines what to install and how the application starts
  • Lambda provisions a VM, executes the Dockerfile instructions, and starts your app with CMD
  • A snapshot of the VM's full state is captured (disk, memory, and running processes)
  • When launching a MicroVM, Lambda restores that snapshot. Your application resumes exactly where it left off, without repeating the startup

5. File structure

  • Project: You can use any language or framework that can run on Linux
  • Dockerfile: The instructions needed to prepare the execution environment

6. Hands-on

We're going to define an environment suitable for isolated coding exercises, so that each user can complete a personalized coding challenge without affecting other users' tests.

Note: We disable code-server's built-in authentication (auth: none) because access to the MicroVM is already protected by the JWE token at the endpoint level. Nobody can reach port 8080 without a valid token.

Dockerfile

FROM codercom/code-server:latest

USER root

# Install Node.js (for hook server) and Python with pytest
RUN apt-get update && apt-get install -y \
    nodejs \
    python3 python3-pip \
    && rm -rf /var/lib/apt/lists/* \
    && pip3 install pytest --break-system-packages

# Install Python extension for code-server
RUN code-server --install-extension ms-python.python

# Config without auth
RUN mkdir -p /root/.config/code-server && \
    echo "bind-addr: 0.0.0.0:8080" > /root/.config/code-server/config.yaml && \
    echo "auth: none" >> /root/.config/code-server/config.yaml && \
    echo "cert: false" >> /root/.config/code-server/config.yaml

# Copy exercise to workspace
COPY ejercicio/ /home/coder/workspace/
RUN chown -R coder:coder /home/coder/workspace

COPY hook_server.js /hook_server.js
COPY start.sh /start.sh
RUN chmod +x /start.sh

EXPOSE 8080 8081

CMD ["/start.sh"]
Enter fullscreen mode Exit fullscreen mode

Python Exercise

main.py

def suma(a, b):
    """TODO: Return the sum of a and b"""
    pass


def es_palindromo(texto):
    """TODO: Return True if the text is a palindrome"""
    pass


def fibonacci(n):
    """TODO: Return the first n Fibonacci numbers"""
    pass
Enter fullscreen mode Exit fullscreen mode

tests/test_main.py

from main import suma, es_palindromo, fibonacci


def test_suma():
    assert suma(2, 3) == 5
    assert suma(-1, 1) == 0


def test_palindromo():
    assert es_palindromo("ana") == True
    assert es_palindromo("hola") == False


def test_fibonacci():
    assert fibonacci(5) == [0, 1, 1, 2, 3]
    assert fibonacci(1) == [0]
Enter fullscreen mode Exit fullscreen mode

7. How to build a snapshot?

  1. Create the base files
    • Project
    • Dockerfile
  2. Package into a zip
   zip -r bootcamp-lab.zip Dockerfile start.sh hook_server.js README.md ejercicio/
Enter fullscreen mode Exit fullscreen mode
  1. Upload to an S3 bucket
   aws s3 cp bootcamp-lab.zip s3://my-bucket/bootcamp-lab.zip
Enter fullscreen mode Exit fullscreen mode
  1. Create the snapshot

Note: When creating the snapshot, you can choose a default role that Lambda generates automatically. This role includes the necessary permissions to read from the S3 bucket you specified. For initial testing, I recommend using this option instead of dealing with custom roles.

8. Let's run our first Lambda MicroVM

  • Click the "Run MicroVM" button

  • Token creation: through this we can access the MicroVM URL

  • Start the MicroVM

With the generated endpoint we can access it from the browser. Every request requires the X-aws-proxy-auth header with the token we generated in the previous step, which you'll need to add to the browser. For this case I used the Chrome extension ModHeader.

Once you navigate to the generated endpoint you'll see the isolated environment. This way I can create as many environments as needed with the exact same structure so that users can run their tests without affecting existing resources or other users' environments.

9. Testing with a database IDE

The structure used for this case can be adapted for other scenarios that use an IDE — for example, a MicroVM used for database exercises (CloudBeaver, pgAdmin, Workbench, etc.). It's the same pattern: use a Dockerfile to configure the environment, create the snapshot, and launch the execution.

You can find the complete code in my repository:
https://github.com/lfdeleonramirez/aws-lambda-microvms


About the author

Luis Fernando de León — AWS Community Builder 🇬🇹

📸 Instagram: instagram.com/luisenlanube
📝 DEV: dev.to/luisferdeleon
👤 Facebook: facebook.com/luisenlanube
💼 LinkedIn: linkedin.com/in/luisfdeleonramirez

Resources
📖 Official documentation — AWS Lambda MicroVMs

Top comments (0)