Skip to content
© 2026 The ThingsBoard Authors
Try for free

ThingsBoard Cloud

Choose your data region

Your data stays in the region you choose, for residency and compliance. No credit card required.

Rather run it yourself? Install on your own servers

AWS EKS Microservices Setup

This guide walks you through deploying ThingsBoard in microservices mode on AWS EKS. We use Amazon RDS for managed PostgreSQL, Amazon MSK for managed Kafka, and Amazon ElastiCache for managed Redis.

Install kubectl, eksctl, and AWS CLI.

Configure your AWS credentials. To get Access and Secret keys, follow this guide. The default region should be the ID of the region where you want to deploy the cluster.

Terminal window
aws configure

Verify that you can pull the images from Docker Hub:

Terminal window
docker pull thingsboard/tb-node:4.4.0
docker pull thingsboard/tb-web-report:4.4.0
docker pull thingsboard/tb-web-ui:4.4.0
docker pull thingsboard/tb-js-executor:4.4.0
docker pull thingsboard/tb-http-transport:4.4.0
docker pull thingsboard/tb-mqtt-transport:4.4.0
docker pull thingsboard/tb-coap-transport:4.4.0
docker pull thingsboard/tb-lwm2m-transport:4.4.0
docker pull thingsboard/tb-snmp-transport:4.4.0
docker pull thingsboard/tb-integration-executor:4.4.0

Step 1. Clone ThingsBoard K8S Scripts Repository

Section titled “Step 1. Clone ThingsBoard K8S Scripts Repository”

Clone the repository containing the Kubernetes deployment scripts:

Terminal window
git clone -b release-4.4.0 https://github.com/thingsboard/thingsboard-pe-k8s.git --depth 1
cd thingsboard-pe-k8s/aws/microservices

In the cluster.yml file you can find the suggested cluster configuration. Key fields you can change:

Field Default Description
region us-east-1 AWS region for the cluster
availabilityZones [us-east-1a, us-east-1b, us-east-1c] Region availability zones
instanceType m5.xlarge EC2 instance type for nodes

Create the cluster:

Terminal window
eksctl create cluster -f cluster.yml

Step 3. Create AWS Load-Balancer Controller

Section titled “Step 3. Create AWS Load-Balancer Controller”

Once the cluster is ready, create the AWS load-balancer controller by following this guide.

The cluster provisioning scripts create several load balancers:

Load Balancer Type Purpose
tb-http-loadbalancer ALB Web UI, REST API, HTTP transport
tb-mqtt-loadbalancer NLB MQTT transport
tb-coap-loadbalancer NLB CoAP transport
tb-edge-loadbalancer NLB Edge instances connectivity

Set up PostgreSQL on Amazon RDS. ThingsBoard uses it as the main database for devices, dashboards, rule chains, and device telemetry. Follow this guide, but take into account the following requirements:

  • Keep your PostgreSQL password in a safe place. We will refer to it later as YOUR_RDS_PASSWORD.
  • Make sure your PostgreSQL version is latest 16.x.
  • Make sure your PostgreSQL RDS instance is accessible from the ThingsBoard cluster. The easiest way is to deploy the RDS instance in the same VPC and use the eksctl-thingsboard-cluster-ClusterSharedNodeSecurityGroup-* security group.
  • Make sure you use “thingsboard” as the initial database name. If you do not specify a database name, Amazon RDS does not create one.

Recommendations:

  • Use Production template for high availability.
  • Use Provisioned IOPS for better performance.
  • Consider creating a custom parameters group for your RDS instance.
  • Consider deploying the RDS instance into private subnets.

Once the database switches to the Available state, navigate to Connectivity and Security and copy the endpoint value. We will refer to it as YOUR_RDS_ENDPOINT_URL.

Using Cassandra is optional. We recommend it if you plan to insert more than 5K data points per second or want to optimize storage space.

Provision additional node groups to host Cassandra instances. At least 4 vCPUs and 16 GB of RAM is recommended.

Create 3 separate node pools with 1 node per zone:

Terminal window
eksctl create nodegroup --config-file=<path> --include='cassandra-*'

Create the namespace, then deploy Cassandra:

Terminal window
kubectl apply -f tb-namespace.yml
kubectl config set-context $(kubectl config current-context) --namespace=thingsboard

Deploy Cassandra:

Terminal window
kubectl apply -f receipts/cassandra.yml

Monitor the process:

Terminal window
kubectl get pods

Don’t forget to replace YOUR_AWS_REGION with the name of your AWS region.

Terminal window
echo " DATABASE_TS_TYPE: cassandra" >> tb-node-db-configmap.yml
echo " CASSANDRA_URL: cassandra:9042" >> tb-node-db-configmap.yml
echo " CASSANDRA_LOCAL_DATACENTER: YOUR_AWS_REGION" >> tb-node-db-configmap.yml

Verify:

Terminal window
cat tb-node-db-configmap.yml | grep DATABASE_TS_TYPE

Create the ThingsBoard keyspace inside Cassandra:

Terminal window
kubectl exec -it cassandra-0 -- bash -c "cqlsh -e \
\"CREATE KEYSPACE IF NOT EXISTS thingsboard \
WITH replication = { \
'class' : 'NetworkTopologyStrategy', \
'us-east' : '3' \
};\""

ThingsBoard uses Kafka as an external queue for exchanging data between microservices, storing unprocessed messages, and more. By default, the deployment uses local Kafka, but ThingsBoard is also compatible with managed services such as Amazon MSK.

Steps to create a basic Kafka MSK cluster:

  • Open the AWS console, go to MSK and click Create Cluster.
  • Select Custom creation method.
  • Specify a name for your cluster and select Cluster type → Provisioned.
  • Select Apache Kafka version 3.8.x to use Express brokers or version 4.0.x for Standard brokers.
  • Choose kafka.m7.large or similar instance types.
  • Select the storage size for the broker (with default ThingsBoard partition settings, Kafka can use up to 100 GB).
  • Deploy the MSK instance in the same VPC as the ThingsBoard cluster. Use private subnets.
  • Use the default security settings. Make sure Plaintext mode is enabled.
  • Use either Basic monitoring or Enhanced topic-level monitoring settings.

Once the MSK cluster switches to the Active state, navigate to Details and click View client information. Copy the bootstrap server information in plaintext — this is your Kafka endpoint.

Edit the tb-kafka.yml file, find the StatefulSet section named tb-kafka, and set spec.replicas to 0 to disable the default local Kafka deployment.

Edit tb-kafka-configmap.yml and replace TB_KAFKA_SERVERS value with your MSK endpoint.

Step 6. Amazon ElastiCache (Redis) Configuration

Section titled “Step 6. Amazon ElastiCache (Redis) Configuration”

ThingsBoard uses cache to improve performance and reduce frequent database reads. By default, the deployment uses a local Valkey cache, but ThingsBoard is also compatible with managed services such as Amazon ElastiCache.

Steps to create a basic ElastiCache Valkey cluster:

  • Open the AWS console and navigate to ElastiCache Valkey caches and click Create.
  • Choose the Deployment option Serverless or Design your own cache.
  • Specify Valkey Engine version 8.x and a node type with at least 1 GB of RAM.
  • Deploy the Valkey cluster in the same VPC as the ThingsBoard cluster. Use private subnets and your group ID.
  • Disable the Enable automatic backups option.

Once the Valkey cluster switches to the Available state, navigate to the Details section and copy the Endpoint field without the “:6379” port suffix.

Edit the tb-valkey.yml file, locate the StatefulSet section named tb-valkey, and set spec.replicas to 0 to disable the default local Valkey deployment.

Then, edit tb-cache-configmap.yml and replace the REDIS_HOST value with your Valkey endpoint.

Section titled “Step 7. Configure Links to Kafka (Amazon MSK)/Redis/Postgres”

Edit tb-node-db-configmap.yml and replace YOUR_RDS_ENDPOINT_URL and YOUR_RDS_PASSWORD with the values obtained during Step 4.

Edit tb-kafka-configmap.yml and replace YOUR_MSK_BOOTSTRAP_SERVERS_PLAINTEXT with the value obtained during Step 5.

Edit tb-redis-configmap.yml and replace YOUR_REDIS_ENDPOINT_URL_WITHOUT_PORT with the value obtained during Step 6.

We assume you have already chosen your subscription plan or decided to purchase a perpetual license. If not, navigate to the pricing page.

Create a docker secret with your license key:

Terminal window
export TB_LICENSE_KEY=PUT_YOUR_LICENSE_KEY_HERE
kubectl create -n thingsboard secret generic tb-license --from-literal=license-key=$TB_LICENSE_KEY

Step 9. CPU and Memory Resources Allocation

Section titled “Step 9. CPU and Memory Resources Allocation”

The scripts have preconfigured values of resources for each service. You can change them in .yml files under the resources section.

Recommended CPU/memory resources allocation:

Service CPU Memory
TB Node 1.5 6Gi
TB HTTP Transport 0.5 2Gi
TB MQTT Transport 0.5 2Gi
TB CoAP Transport 0.5 2Gi
TB Web UI 0.3 0.5Gi
JS Executor 0.1 0.3Gi
Zookeeper 0.3 1Gi
Trendz (optional) 2 4Gi
Trendz Python Executor (optional) 1 4Gi

Execute the following command to run the initial setup of the database:

Terminal window
./k8s-install-tb.sh

After this command finishes you should see:

Installation finished successfully!

Deploy ThingsBoard services:

Terminal window
./k8s-deploy-resources.sh

After a few minutes, call kubectl get pods. If everything went fine, you should see:

  • 5x tb-js-executor
  • 1x tb-node (scale to more nodes if you have additional license instances)
  • 2x tb-web-ui
  • 3x zookeeper

Every pod should be in the READY state.

Deploy the transport microservices you need. Omit protocols you don’t use to save resources:

Terminal window
# HTTP Transport (optional)
kubectl apply -f transports/tb-http-transport.yml
# MQTT Transport (optional)
kubectl apply -f transports/tb-mqtt-transport.yml
# CoAP Transport (optional)
kubectl apply -f transports/tb-coap-transport.yml
# LwM2M Transport (optional)
kubectl apply -f transports/tb-lwm2m-transport.yml
# SNMP Transport (optional)
kubectl apply -f transports/tb-snmp-transport.yml

You have 2 options:

  • HTTP — recommended for development. Simple configuration and minimum costs.
  • HTTPS — recommended for production. Acts as an SSL termination point with automatic redirect from HTTP to HTTPS.
Terminal window
kubectl apply -f receipts/http-load-balancer.yml

Check the status:

Terminal window
kubectl get ingress

Once provisioned, you should see:

NAME CLASS HOSTS ADDRESS PORTS AGE
tb-http-loadbalancer <none> * 34.111.24.134 80 7m25s

Use the address to access the HTTP web UI (port 80) and connect devices via HTTP API.

Administrator account creation on first access is covered next, in Step 13. Create Your Administrator Account.

12.2 Configure MQTT Load Balancer (Optional)

Section titled “12.2 Configure MQTT Load Balancer (Optional)”
Terminal window
kubectl apply -f receipts/mqtt-load-balancer.yml

The load balancer forwards all TCP traffic for ports 1883 and 8883.

Make the AWS NLB act as a TLS termination point. Traffic between devices and the load balancer is encrypted.

Use AWS Certificate Manager to create or import an SSL certificate. Edit the load balancer configuration:

Terminal window
nano receipts/mqtts-load-balancer.yml

Replace YOUR_MQTTS_CERTIFICATE_ARN, then deploy:

Terminal window
kubectl apply -f receipts/mqtts-load-balancer.yml

12.3 Configure UDP Load Balancer (Optional)

Section titled “12.3 Configure UDP Load Balancer (Optional)”
Terminal window
kubectl apply -f receipts/udp-load-balancer.yml

The load balancer forwards all UDP traffic for ports:

Port Protocol
5683 CoAP non-secure
5684 CoAP secure DTLS
5685 LwM2M non-secure
5686 LwM2M secure DTLS
5687 LwM2M bootstrap non-secure
5688 LwM2M bootstrap secure DTLS

For CoAP over DTLS, follow the CoAP over DTLS guide. For LwM2M over DTLS, follow the LwM2M over DTLS guide.

12.4 Configure Edge Load Balancer (Optional)

Section titled “12.4 Configure Edge Load Balancer (Optional)”
Terminal window
kubectl apply -f receipts/edge-load-balancer.yml

The load balancer forwards all TCP traffic on port 7070.

To get the external IP address:

Terminal window
kubectl get services | grep "EXTERNAL-IP\|tb-edge-loadbalancer"

Use the external IP address as CLOUD_RPC_HOST in Edge connection parameters.

Step 13. Create Your Administrator Account

Section titled “Step 13. Create Your Administrator Account”

After launching ThingsBoard, open the web UI at the load balancer address. ThingsBoard prompts you to create your System Administrator account — the account that manages the platform itself (tenants, system settings, platform-wide resources).

  1. Enter Email, Password, and Confirm password.
  2. The Set up a demo tenant option is selected by default: it creates a ready-made tenant with dashboards, devices, and rule chains for exploring the platform before building your own solution. Clear it if you want to start with an empty platform.
  3. Click Create account. You are signed in as the system administrator.

Your ThingsBoard instance is now installed and running.

Confirm that the load balancers created in Step 12 are provisioned and reachable, and note their addresses — you need them to open the web UI and to connect devices.

Get the DNS name of the HTTP load balancer:

Terminal window
kubectl get ingress

Use the address to open the ThingsBoard web interface in your browser.

Get the load balancer services:

Terminal window
kubectl get service

Two load balancers are available:

  • tb-mqtt-loadbalancer-external — for MQTT protocol
  • tb-coap-loadbalancer-external — for CoAP protocol

Use the EXTERNAL-IP field of the load balancers to connect to the cluster.

Pull the Trendz images from Docker Hub:

Terminal window
docker pull thingsboard/trendz:1.16.0
docker pull thingsboard/trendz-python-executor:1.16.0

Create a Trendz Database in the Existing RDS Instance

Section titled “Create a Trendz Database in the Existing RDS Instance”

Edit trendz/trendz-secret.yml and replace YOUR_RDS_ENDPOINT_URL and YOUR_RDS_PASSWORD, then apply:

Terminal window
kubectl apply -f ./trendz/trendz-secret.yml
kubectl apply -f ./trendz/trendz-create-db.yml

Check logs:

Terminal window
kubectl logs job/trendz-create-db -n thingsboard
Terminal window
./k8s-deploy-trendz.sh

After this command finishes you should see:

Trendz installed successfully!

To examine ThingsBoard node logs:

Terminal window
kubectl logs -f tb-node-0

Other useful commands:

  • kubectl get pods — see the state of all pods
  • kubectl get services — see the state of all services
  • kubectl get deployments — see the state of all deployments

See the kubectl Cheat Sheet for more details.

Delete all ThingsBoard pods:

Terminal window
./k8s-delete-resources.sh

Delete all ThingsBoard pods and configmaps:

Terminal window
./k8s-delete-all.sh

Delete the EKS cluster (change cluster name and region as needed):

Terminal window
eksctl delete cluster -r us-east-1 -n thingsboard -w

With ThingsBoard running, these concept guides help you build your first solution: