Skip to main content
GuideServerConfigure and deploy Tabsdata servers on your machine.TutorialsConfigure data integration workflows within a running Tabsdata server.Advanced TutorialsBuild end-to-end workflows between two specific systems.API ReferenceCLI ReferenceRelease Notes
Version: 2.0.0

AWS Services Setup for Tabsdata on EKS

Tabsdata on EKS runs as long-running deployment pods in a single namespace, and dispatches every publisher, subscriber and transformer execution as its own Kubernetes job. It keeps no state in the cluster: table data lives in AWS S3 and all metadata lives in AWS RDS for PostgreSQL. This document covers the AWS-side setup those three services need before Tabsdata can be installed, and how to expose the instance once it is running.

The values produced here are the ones the Tabsdata admin needs at hand for Install Tabsdata on AWS EKS.

Before you begin

These instructions assume you have knowledge of, and full access to, the AWS IAM, EKS, RDS and S3 services, or that your AWS admins do. Each section indicates the type of admin access it requires.

It is recommended you read through the whole setup before you begin, so you can gather all the necessary information and have it ready.

Prepare the EKS cluster

(EKS admin)

Tabsdata must be installed into an existing cluster <TABSDATA_CLUSTER>, in an empty namespace.

Create an EKS namespace <TABSDATA_NAMESPACE>.

Node scheduling

(EKS admin)

Karpenter must be installed in the cluster and given the AWS resources it needs: an IAM role for the controller (IRSA or EKS Pod Identity) allowing it to run instances, create launch templates and pass the node role; a node IAM role admitted to the cluster via an EKS access entry or aws-auth; the SQS interruption queue with its EventBridge rules; and karpenter.sh/discovery tags on the subnets and security groups the EC2NodeClass selects. Because Karpenter cannot run on a node it manages, a small fixed managed node group must exist beforehand, outside the pools, to hold it and the cluster addons.

Two EC2NodeClass/NodePool pairs are then created, distinguished mainly by local disk. The services pool is untainted, sized for the long-running instance pods, with the instance store exposed to the kubelet, expiry disabled and consolidation enabled so the fleet shrinks. The functions pool is sized for the substantially larger disk a run stages, with an explicit memory floor since that does not follow from vCPU or disk, and is tainted so a function pod that lost its toleration fails visibly rather than running slowly on a small machine. All sizes in the reference pools are initial suggested values. Set them from the instance's own requests and expected concurrency and volumetry. Pool and node class names are free; placement follows the pods' resource requests, so function pods land on the functions pool because only it provisions machines that large.

Three strings are binding and must match exactly. Two PriorityClass objects named tabsdata-service and tabsdata-function must exist, with the service class ranked higher, because the API server rejects a pod naming a class that is absent. The functions pool's taint key, value and effect must be identical to pods.function.placement.tolerations in the instance's configs/tabsdata.yaml, edited via tdkserver get-cfg / tdkserver put-cfg. Resource requests and the aut-services disruption budget arrive with the instance and need no administrator action.

Map your AWS user to a Kubernetes group

(EKS admin)

Map the AWS username <AWS_USERNAME> that will install and manage Tabsdata to the Kubernetes group <TABSDATA_GROUP> in the cluster <TABSDATA_CLUSTER>, region <TABSDATA_CLUSTER_REGION>.

Create the namespace role and binding

(EKS admin)

This role grants Tabsdata the permissions it needs inside its own namespace.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: <TABSDATA_ROLE>
namespace: <TABSDATA_NAMESPACE>
rules:
- apiGroups: [ "" ]
resources: [ "pods" ]
verbs: [ "get", "list", "watch", "create", "update", "patch", "delete", "deletecollection" ]
- apiGroups: [ "" ]
resources: [ "services", "configmaps", "secrets", "serviceaccounts" ]
verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ]
- apiGroups: [ "" ]
resources: [ "pods/log" ]
verbs: [ "get", "list" ]
- apiGroups: [ "" ]
resources: [ "pods/portforward" ]
verbs: [ "create" ]
- apiGroups: [ "apps" ]
resources: [ "deployments" ]
verbs: [ "get", "list", "watch", "create", "update", "patch", "delete", "deletecollection" ]
- apiGroups: [ "policy" ]
resources: [ "poddisruptionbudgets" ]
verbs: [ "get", "list", "create", "update", "delete" ]
- apiGroups: [ "networking.k8s.io" ]
resources: [ "ingresses" ]
verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ]
- apiGroups: [ "batch" ]
resources: [ "jobs", "cronjobs" ]
verbs: [ "get", "list", "watch", "create", "update", "patch", "delete", "deletecollection" ]
- apiGroups: [ "rbac.authorization.k8s.io" ]
resources: [ "roles", "rolebindings" ]
verbs: [ "get", "list", "create", "update", "delete" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: <TABSDATA_ROLE>
namespace: <TABSDATA_NAMESPACE>
subjects:
- kind: Group
name: <TABSDATA_GROUP>
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: <TABSDATA_ROLE>
apiGroup: rbac.authorization.k8s.io

Create the cluster role and binding

(EKS admin)

A few of the checks Tabsdata runs cannot be expressed in a namespaced role, so they need a cluster role. All of them are read-only, and none grants any access beyond reading.

Create the cluster role <TABSDATA_CLUSTER_ROLE> and bind it to the group <TABSDATA_GROUP>.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <TABSDATA_CLUSTER_ROLE>
rules:
- apiGroups: [ "" ]
resources: [ "namespaces", "services", "nodes" ]
verbs: [ "get", "list" ]
- apiGroups: [ "karpenter.sh" ]
resources: [ "nodepools" ]
verbs: [ "get", "list" ]

Finally, provide a <KUBECONFIG> file to the Tabsdata operator so the installation steps below can reach the cluster.

Verify your permissions

(Tabsdata admin)

Run these checks with the <KUBECONFIG> you were given, before going any further.

kubectl auth can-i create deployments.apps
kubectl auth can-i create cronjobs.batch
kubectl auth can-i create secrets
kubectl auth can-i create services
kubectl auth can-i create roles.rbac.authorization.k8s.io
kubectl auth can-i create serviceaccounts
kubectl auth can-i get pods/log
kubectl auth can-i deletecollection pods
kubectl auth can-i deletecollection deployments.apps
kubectl auth can-i deletecollection jobs.batch
kubectl auth can-i deletecollection cronjobs.batch
kubectl auth can-i create pods/portforward
kubectl auth can-i create ingresses.networking.k8s.io
kubectl auth can-i create poddisruptionbudgets.policy
kubectl auth can-i list namespaces
kubectl auth can-i list services --all-namespaces
kubectl auth can-i list nodes
kubectl auth can-i list nodepools.karpenter.sh

Every command must answer yes. If any command fails or answers no, check with your AWS EKS administrator before proceeding.

Tabsdata database

(RDS admin)

Tabsdata stores its own state and the metadata for user data in PostgreSQL.

Create an AWS RDS for PostgreSQL 18.4 instance with a database <TABSDATA_DATABASE>, using password authentication with <RDS_USERNAME> and <RDS_PASSWORD>.

<RDS_USERNAME> must have the following permissions:

RequirementKindStatement
CONNECT on <TABSDATA_DATABASE>privilegeGRANT CONNECT ON DATABASE <TABSDATA_DATABASE> TO <RDS_USERNAME>;
CREATEROLErole attributeALTER ROLE <RDS_USERNAME> CREATEROLE;
CREATE on <TABSDATA_DATABASE>privilegeGRANT CREATE ON DATABASE <TABSDATA_DATABASE> TO <RDS_USERNAME>;

The RDS master username already satisfies all three, and owns any database it creates.

The Tabsdata installation will create the necessary database schemas, roles and grants.

What the installation creates

(RDS admin)

One schema per Tabsdata component, inside <TABSDATA_DATABASE>:

SchemaComponent
<TABSDATA_DATABASE>_apiserverAPI server
<TABSDATA_DATABASE>_aiagentAI agent

Each schema holds that component's tables, indexes, views, triggers, row-level-security policies and baseline data.

Three PostgreSQL roles. Roles are cluster-global, so their names must be unique across the whole RDS instance, which is why they derive from <TABSDATA_DATABASE>:

RoleLoginPasswordOwns
<TABSDATA_DATABASE>_apiserverLOGINmust be providedthe API server schema
<TABSDATA_DATABASE>_aiagentLOGINmust be providedthe AI agent schema
<TABSDATA_DATABASE>_appNOLOGINnonenothing

The two login roles are the identities Tabsdata authenticates as, one per component. Their passwords are supplied during installation.

<TABSDATA_DATABASE>_app is the role every Tabsdata connection then switches to, and the one row-level security is enforced against. It is shared by both components, owns nothing, and cannot be reached directly: it has no login and no password, and is used only internally by Tabsdata.

Tabsdata cloud storage

(S3 admin)

Tabsdata uses AWS S3 bucket(s) for data storage.

You need an S3 bucket <S3_BUCKET> in region <S3_REGION>, and full-access credentials for it: <S3_ACCESS_KEY> and <S3_SECRET_KEY>.

Configure access from outside the cluster (over HTTPS)

(EKS admin)

note

None of this applies to local access via kubectl port-forward, as described in Install Tabsdata on AWS EKS.

Once installed, Tabsdata is running inside the cluster, but is not reachable from outside it.

Public access is delivered by two AWS components layered on the cluster. In EKS, the apiserver Service is fronted by an alb-class Ingress, which the AWS Load Balancer Controller turns into an internet-facing Application Load Balancer targeting pod IPs, so the controller must already be installed with an IAM role permitting ELBv2 management, and the VPC's public subnets must carry the kubernetes.io/role/elb tag in every availability zone in use. That ALB listens on HTTP only, and its security group is locked to the AWS-managed CloudFront origin-facing prefix list (read from EC2), so it is not reachable directly.

In front of it, a CloudFront distribution uses the ALB as a custom origin and serves viewers over HTTPS on its own *.cloudfront.net hostname, which is why no Route 53 record or ACM certificate is needed. Deployment of the distribution takes five to ten minutes; after that the instance answers only through CloudFront.

Use the distribution's *.cloudfront.net URL as <TABSDATA_PUBLIC_URL>, and point your browser at it.