Preview Environments for AWS apps on every Pull Request with LocalStack
Integrating LocalStack's Ephemeral Environments with your GitHub Actions CI workflows allows you to automatically generate a fully functioning preview of your AWS applications, eliminating the need for costly-staging environments.

Introduction
LocalStack’s core cloud emulator allows you to set up your cloud infrastructure on your local machine. You can access databases, queues, and other managed services without needing to connect to a remote cloud provider. This speeds up your Software Development Life Cycle (SDLC) by making development and testing more efficient.
Despite this, you still need a staging environment to do final acceptance tests before deploying your application to production. In many cases, staging environments are costly and deploying changes to them takes a lot of time. Also, teams can only use one staging environment at a time, which makes it difficult to test changes quickly.
With LocalStack’s Ephemeral Instances, you can create short-lived, self-contained deployments of LocalStack in the cloud. These Ephemeral Instances also let you deploy your application on a remote LocalStack container on every pull/merge request, creating an Application Preview. This allows you to run end-to-end tests, preview features, and collaborate within your team or across teams asynchronously.
In this tutorial, we’ll set up a full-stack AWS serverless application and serve it in a short-lived preview environment for each pull request using LocalStack and GitHub Actions.
About the application
This tutorial uses a public LocalStack sample to showcase a serverless quiz application. The example application is a traditional three-tier architecture that uses the following AWS resources:
- S3: Hosts static frontend assets in a bucket for CloudFront distribution.
- CloudFront: Delivers frontend assets from S3 globally for fast user access.
- Lambda: Executes serverless functions for creating, submitting, scoring, and fetching quizzes.
- API Gateway: Exposes REST endpoints for quiz operations, linking HTTP methods to Lambda functions.
- DynamoDB: Stores the quiz, associated metadata and user data for persistence.
There are several other AWS resources that are part of the application, but these are the main ones we’ll focus on. The application is deployed using the AWS CLI and a helper script (bin/deploy.sh
) to set it up from scratch locally with the awslocal
wrapper and LocalStack.
We can now write a GitHub Action workflow to deploy the sample application on an Ephemeral Instance and create a preview environment.
Prerequisites
Create the GitHub Action workflow
GitHub Actions serves as a continuous integration and continuous delivery (CI/CD) platform, automating software development workflows directly from GitHub. It allows customization of actions and automation throughout the software development lifecycle.
We can implement a workflow that:
- Checks out the repository from GitHub.
- Installs necessary dependencies.
- Deploys the application on a ephemeral LocalStack Instance using a GitHub Action Runner to generate a sharable application preview.
To begin, let’s fork the LocalStack sample repository on GitHub.
If you’re using GitHub’s gh
CLI, fork and clone the repository with this command:
gh repo fork https://github.com/localstack-samples/serverless-quiz-app
Alternatively, you can fork the repository manually by clicking the “Fork” button on the repository page and then cloning it to your local machine using the git clone
command.
After forking and cloning, navigate to the .github/workflows
directory in your forked repository. Open the preview.yml
file, which contains the GitHub Action workflow configuration, required to setup the preview environment.
The file is included in this repo for convenience. If starting from scratch, you can optionally delete and recreate it or simply open it to review its contents.
Set Up the Actions & dependencies
To achieve our goal, we can utilize a few prebuilt Actions:
actions/checkout
: Checkout the application code with Git.setup-localstack
: Configure the workflow to generate the application preview.actions/setup-node
: Set up Node.js for the workflow to install dependencies.
We can now add the following content to the preview.yml
file:
name: 'Create Preview on Pull Request'on: workflow_dispatch: pull_request: types: [opened, synchronize, reopened]
This configuration triggers the workflow on every pull request event and allows manual execution via the GitHub Actions UI.
Create a new job named localstack
to define the GitHub-hosted runner for executing workflow steps and checking out the code for deployment to the preview environment:
jobs: localstack: permissions: write-all name: Setup LocalStack Preview runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4
To ensure our dependencies are installed, we can add the following step to the job:
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20
Setup the preview environment workflow
To deploy the preview environment, use the LocalStack/setup-localstack
action with the following parameters:
github-token
: Automatically set on the GitHub Action runner.state-backend
: Set toephemeral
to create an Ephemeral Instance.state-action
: Set tostart
to start the Ephemeral Instance.include-preview
: Set totrue
to include the Ephemeral Instance URL in the PR comment.install-awslocal
: Set totrue
to install theawslocal
AWS CLI wrapper.preview-cmd
: Commands required to deploy the application and its infrastructure on LocalStack.
The job step should look like this:
- name: LocalStack Preview uses: LocalStack/setup-localstack@main with: github-token: ${{ secrets.GITHUB_TOKEN }} state-backend: ephemeral state-action: start include-preview: 'true' install-awslocal: 'true' preview-cmd: | ./bin/deploy.sh distributionId=$(awslocal cloudfront list-distributions | jq -r '.DistributionList.Items[0].Id'); echo LS_PREVIEW_URL=$AWS_ENDPOINT_URL/cloudfront/$distributionId/ >> $GITHUB_ENV; env: LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
In the preview-cmd
section, the deploy.sh
script is executed to deploy the application on LocalStack. The CloudFront distribution ID is retrieved and appended to the LS_PREVIEW_URL
environment variable, which is then used to display the preview URL in the pull request comment. This provides quick access to the deployed URL for validating features or updates.
Configure a CI Auth Token
Before triggering the workflow, set up a Continuous Integration (CI) Auth Token for LocalStack. This token is required to activate licensed features like Ephemeral Instances in CI environments. As you can see in the env
section of the LocalStack Preview
step, we’re using the LOCALSTACK_AUTH_TOKEN
secret to authenticate with LocalStack.
To add the CI Auth Token to your GitHub repository:
-
Go to the LocalStack Web Application and open the Auth Token page.
-
Under the “CI Auth Tokens” section, provide a name and click “Generate new CI Auth Token” to create a token.
-
Add the token to your GitHub repository secrets with:
- “Name”:
LOCALSTACK_AUTH_TOKEN
- “Secret”: The generated CI Auth Token.
- “Name”:
Now, you can commit and push your workflow to your forked GitHub repository.
If you do not have access to creating CI keys, contact your LocalStack account administrator.
Run the GitHub Action workflow
With the GitHub Action workflow set up, each pull request in your forked repository will trigger the creation of a preview environment. LocalStack will build, deploy, and package the application in an Ephemeral Instance, accessible via a preview URL in the pull request comment.
This might take a short while to complete, depending on the infrastructure’s complexity and the build/deploy process. The workflow automatically updates the preview environment when new commits are pushed to the pull request.
Here is an example of a pull request comment with the preview URL:
You can now access the preview URL to test the application and validate the changes made in the pull request. You can also integrate the preview URL with tools like Slack or Teams to notify your team or run automated E2E tests using Cypress or Playwright to validate functionality.
The Ephemeral Instance is automatically terminated after a period of 2 hours, ensuring that resources are not left running unnecessarily. If you push further commits to the pull request, the preview environment is removed and recreated with the latest changes.
Conclusion
Preview environments are ubiquitous in in the frontend space, and with LocalStack you can now now spin up your entire application, including your AWS infrastructure, as a live environment with every change. This allows you to:
- Collaborate with GTM, RevOps, and Marketing teams to showcase new features to potential customers.
- Eliminate staging environments by providing each engineer with an isolated environment.
- Reduce staging costs by automatically tearing down environments to avoid unnecessary cloud expenses.
This preview-on-pull-request feature positions LocalStack a true cloud development platform — not only for developers but also for QA & management, to fully become the backbone of cloud development throughout the entire SDLC. In future blog posts, will explore more such use-cases including using Cloud Pods for fast infrastructure setup, E2E testing using popular frameworks, and setting up pre-production environments with synthesized test data for acceptance testing.