Skip to content
Get Started for Free
Starting on March 23, 2026, LocalStack for AWS will consolidate into a single image that requires authentication. Learn more about what’s changing and what this means for your setup in this blog post.

Deploy LocalStack Operator

The LocalStack Operator provides a Kubernetes-native way to deploy and manage LocalStack instances. It abstracts Kubernetes-specific configuration and automates operational tasks, making LocalStack deployments more consistent and easier to maintain.

The Operator manages the full lifecycle of LocalStack resources and enables advanced Kubernetes integrations that are difficult to configure manually.

This guide explains how to deploy and manage LocalStack in a Kubernetes cluster using the LocalStack Operator.

The Operator supports the following advanced capabilities:

  • Cluster DNS configuration to correctly resolve AWS-style subdomains
  • Automatic loading of Cloud Pods on startup
  • Support for initialization hooks
  • Simplified logging configuration
  • Automatic mounting of a PersistentVolumeClaim (PVC) for the LocalStack data directory, enabling artifact caching and persistence

Before installing the LocalStack Operator, ensure you have:

  • A running Kubernetes cluster
  • A LocalStack license that includes Kubernetes features
  • An authentication token for that license

The easiest way to install the Operator controller is to apply the published manifests directly from GitHub.

Terminal window
# Install the latest version
kubectl apply -f https://github.com/localstack/localstack-operator/releases/latest/download/controller.yaml

To install a specific version:

Terminal window
# Example: install v0.4.0
kubectl apply -f https://github.com/localstack/localstack-operator/releases/v0.4.0/download/controller.yaml

See the Operator releases page for all available versions.

Once the Operator is running, you can deploy a LocalStack instance by creating a LocalStack custom resource.

A minimal example looks like this:

apiVersion: api.localstack.cloud/v1alpha1
kind: LocalStack
metadata:
name: localstack
namespace: my-namespace
spec:
image: localstack/localstack-pro:latest
dnsProvider: coredns
dnsConfigName: coredns
dnsConfigNamespace: kube-system
envFrom:
- secretRef:
name: localstack-auth-token

In this example, the LocalStack auth token is read from a Kubernetes Secret named localstack-auth-token.

You can create this Secret with:

Terminal window
kubectl create secret generic localstack-auth-token \
--from-literal=LOCALSTACK_AUTH_TOKEN="$LOCALSTACK_AUTH_TOKEN"

The auth token must be available in the LOCALSTACK_AUTH_TOKEN environment variable when creating the Secret.

notes::: More advanced examples are available in the LocalStack Operator GitHub repository. :::

By default, the Operator creates a ClusterIP Service named:

localstack-<crd-name>

For the example above (name: localstack), the Service name is:

localstack-localstack

This Service exposes:

  • The LocalStack gateway port (4566)
  • AWS service ports
  • Port 53 for DNS

Using standard Kubernetes DNS resolution, the Service can be reached at:

  • localstack-localstack (same namespace)
  • localstack-localstack.my-namespace
  • localstack-localstack.my-namespace.svc.cluster.local

When dnsProvider: coredns is configured, LocalStack can also be reached through any subdomain of these service names.

The LocalStack Operator introduces a LocalStack Custom Resource Definition (CRD) that controls how LocalStack instances are deployed and configured.

CRD documentation is currently maintained manually. For a full reference of available fields, see: https://github.com/localstack/localstack-operator/blob/v0.4.0/api-docs.md

The Operator manifest creates all required Roles, ClusterRoles, and bindings.

KindNameAPI GroupsResourcesVerbs
Rolelocalstack-operator-leader-election-roleconfigmapsget, list, watch, create, update, patch, delete
coordination.k8s.ioleasesget, list, watch, create, update, patch, delete
eventscreate, patch
ClusterRolelocalstack-operator-manager-roleconfigmapsdelete, get, list, patch, update, watch
eventscreate, patch
podspods/execpods/logcreate, delete, deletecollection, get, list, patch, update, watch
secretsget, list, watch
serviceaccountscreate, delete, get, list, update, watch
servicescreate, delete, get, list, patch, update, watch
api.localstack.cloudlocalstackscreate, delete, get, list, patch, update, watch
api.localstack.cloudlocalstacks/finalizersupdate
api.localstack.cloudlocalstacks/statusget, patch, update
appsdeploymentscreate, delete, get, list, patch, update, watch
appsdeployments/scalecreate, delete, get, list, patch, update, watch
rbac.authorization.k8s.iorolebindingsrolescreate, delete, list, update, watch
ClusterRolelocalstack-operator-metrics-reader(nonResourceURLs: /metrics)get
ClusterRolelocalstack-operator-proxy-roleauthentication.k8s.iotokenreviewscreate
authorization.k8s.iosubjectaccessreviewscreate

This ClusterRole allows the Operator to manage LocalStack resources and related Kubernetes objects.

Resources include:

  • Pods (including exec and logs)
  • Services
  • Secrets
  • Deployments
  • ServiceAccounts
  • LocalStack CRDs (localstacks, status, finalizers)
  • RBAC roles and role bindings

Verbs include:

create, delete, get, list, watch, patch, update

Additional ClusterRoles are created for:

  • Reading metrics (/metrics)
  • Authentication and authorization reviews (tokenreviews, subjectaccessreviews)

The LocalStack Operator configures cluster DNS to forward AWS-style subdomain requests to the LocalStack DNS server.

This enables features such as:

  • S3 virtual-host–style addressing
  • API Gateway domain name resolution

Example from another pod in the cluster:

Terminal window
aws apigatewayv2 create-api \
--name testGatewayProxy \
--protocol-type HTTP \
--target "https://httpbin.org"

Example response:

{
"ApiEndpoint": "http://1d4b6907.execute-api.localstack-localstack.my-namespace:4566",
"ApiId": "1d4b6907"
}

Calling the API:

Terminal window
curl http://1d4b6907.execute-api.localstack-localstack.my-namespace:4566/json

This works without additional DNS configuration in client applications.

The Operator can be upgraded by applying a newer controller manifest.

Example:

Terminal window
# Install an older version
kubectl apply -f https://github.com/localstack/localstack-operator/releases/download/v0.3.3/controller.yaml
# Upgrade to a newer version
kubectl apply -f https://github.com/localstack/localstack-operator/releases/download/v0.4.1/controller.yaml

Kubernetes will handle rolling updates of the Operator deployment.

To verify that the Operator and LocalStack instance are running:

Terminal window
kubectl get pods -n my-namespace
kubectl get localstacks -n my-namespace

Ensure that:

  • The Operator controller pod is running
  • The LocalStack resource reports a healthy status
  • The LocalStack Service is created