Skip to main content
Version: 3.0 (beta)

Preview Environments

In this guide, we'll show how to use Loft and Github Actions to deploy preview environments for your application on every pull request. In this example we will create a new virtual cluster for each pull request and deploy ArgoCD into it. We'll make use of the sleep mode functionality of Loft to make sure the environments are not using any resources if they are unused.

Prepare Loft

Install Ingress Controller

Make sure to install an ingress controller into the Kubernetes cluster where the preview environments should get created. We recommend ingress-nginx which can be installed through Loft under Cluster > Apps.

Configure Preview Environments Domain

As a next step, make sure you have a wildcard domain configured under which the preview environments should be reachable, such as *.my-preview-environments.com. If you don't have access to a custom domain, Loft allows you to configure a *.CUSTOM.kubedev.sh domain in the Clusters > Cluster tab.

Create Virtual Cluster Template

Next we create a new virtual cluster template for our preview environments. Navigate to Templates > Virtual Clusters and press on the 'Add Virtual Cluster Template' button. Make sure to use the following helm values:

# Reuse the host ingress controller for your ingresses
sync:
ingresses:
enabled: true

# Make sure pods don't break out of the virtual cluster
isolation:
enabled: true
networkPolicy:
enabled: false

Next make sure sleep mode is configured to start after 30-60 minutes.

Optional: Ingress Authentication

In the Advanced Options tab, you can also enable 'Ingress Authentication' to only allow users that have access to your Loft instance to access the preview environments.

Create Preview Environments Project

Next create a new project preview to host our preview environments by pressing the plus button under the projects view. Make sure to only select our just created template as an allowed template and assign yourself and all other users or teams you want to have access to the preview environments in the members tab.

Create a Github Deploy Action

After we have our Loft project configured correctly, we can start creating the actual github action that will create our preview environments. On every pull request this action will create a new virtual cluster that hosts our example application (ArgoCD in this case) and can be accessed through an ingress.

The github action looks like this:

name: Create Preview Environment

# Run for pull requests to our main branch
on:
pull_request:
branches:
- main

# make sure the pipeline is only running once
concurrency:
group: preview-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true

# define a job that deploys the preview environment
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3

- name: Install Loft CLI
uses: loft-sh/setup-loft@v2
with:
version: v3.0.0
url: https://url-to-your-loft-instance.com
# Specify your Loft access key here
access-key: ${{ secrets.LOFT_PREVIEW_ACCESS_KEY }}
# Optional if your Loft domain certificate is insecure
#insecure: true

- name: Deploy Preview Environment
run: |
INGRESS_HOST=loft-preview-${{ github.event.pull_request.number }}.my-preview-environments.com

# Make sure to recreate if there is an already existing environment
loft create vcluster loft-preview-${{ github.event.pull_request.number }} --project preview --recreate

# Deploy the application here with an ingress
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --version 5.16.3 \
--create-namespace \
-n argocd \
--set server.ingress.enabled=true \
--set server.ingress.hosts={$INGRESS_HOST}

- uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ github.event.pull_request.number }}
header: release
message: |
Preview environment deployed at: http://loft-preview-${{ github.event.pull_request.number }}.my-preview-environments.com

Create a destroy action

We also want to cleanup environments if they are not needed anymore. In order to accomplish this, we create a separate workflow to cleanup the virtual cluster we have created for our preview environment as soon as the pull request is closed or merged:

name: Destroy Preview Environment

on:
pull_request:
branches:
- main
types:
- closed

jobs:
destroy:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3

- name: Install Loft CLI
uses: loft-sh/setup-loft@v2
with:
version: v3.0.0
url: https://url-to-your-loft-instance.com
# Specify your Loft access key here
access-key: ${{ secrets.LOFT_PREVIEW_ACCESS_KEY }}
#insecure: true

- name: Destroy Preview Environment
run: |
loft delete vcluster loft-preview-${{ github.event.pull_request.number }} --project preview

Conclusion

And that's it, we built a complete flow for creating preview environments with Loft and GitHub actions! After creation, the preview environments will start sleeping if they are not used and consume no computing resources in the cluster. If you want to access a preview environment, just click on the link in the pull request comment and Loft will wake up the environment automatically. This way you can build preview environments that are fast to create, flexible like separate Kubernetes clusters and with no costs at all for unused environments.