TAMS on Kubernetes is a containerized deployment solution that simplifies the deployment and management of the Time Addressable Media Store (TAMS) on Kubernetes infrastructure.
Learn more about TAMS in this blog post
- Overview
- Getting started
- Store Resource Specification
- API Usage
- Development
- Contributing
- License
- Contact
TAMS on Kubernetes is designed for teams who need a scalable, declarative, and Kubernetes-native way to deploy and operate TAMS instances. It abstracts infrastructure complexity by exposing a simple Custom Resource, while remaining flexible enough for production workloads.
TAMS on Kubernetes consists of two main components:
- Kubernetes Controller: A custom Kubernetes controller written in Go that manages
Storecustom resources and automatically deploys TAMS service instances - TAMS Service: A TypeScript/Node.js service that provides REST APIs
┌─────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌──────────────────┐ ┌──────────────────────┐ │
│ │ TAMS Controller │──────│ Store CRD │ │
│ │ (Go) │ │ (Custom Resource) │ │
│ └──────────────────┘ └──────────────────────┘ │
│ │ │
│ │ Creates/Manages │
│ ▼ │
│ ┌──────────────────┐ │
│ │ TAMS Service │ │
│ │ (TypeScript) │ │
│ │ - REST API │ │
│ │ - Flow Management│ │
│ │ - Source Mgmt │ │
│ └──────────────────┘ │
│ │ │
│ │ Connects to │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ DynamoDB │ │ S3 Backend │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
tams-k8s/
├── k8s-controller/ # Kubernetes controller (Go)
│ ├── pkg/
│ │ ├── apis/ # CRD API definitions
│ │ └── controller/ # Controller logic
│ ├── artifacts/ # Deployment manifests
│ └── hack/ # Code generation scripts
├── service/ # TAMS service (TypeScript)
│ ├── src/
│ │ ├── api/ # REST API routes
│ │ ├── backend/ # Storage backend implementations
│ │ └── repository/ # Data access layer
│ └── config/ # Configuration files
└── example/ # Example configurations
- Kubernetes cluster (v1.20+)
kubectlconfigured to access your cluster- AWS credentials (if using DynamoDB and S3 backends)
Deploy the controller, create a Store, and access the API in a few minutes.
kubectl apply -f https://raw.githubusercontent.com/trackit/tams-k8s/refs/heads/master/k8s-controller/artifacts/tams/quick-deploy.yaml
kubectl apply -f example/store.yaml
kubectl port-forward svc/my-store 3000:3000Deploy the TAMS controller and CRD using the quick-deploy manifest:
kubectl apply -f https://raw.githubusercontent.com/trackit/tams-k8s/refs/heads/master/k8s-controller/artifacts/tams/quick-deploy.yamlVerify the controller is running:
kubectl get pods -n tams-systemCreate a Kubernetes secret with your AWS credentials:
kubectl create secret generic tams-aws-secret \
--from-literal=AWS_ACCESS_KEY_ID=your-access-key \
--from-literal=AWS_SECRET_ACCESS_KEY=your-secret-keyCreate a Store resource:
apiVersion: tams.trackit.io/v1alpha1
kind: Store
metadata:
name: my-store
spec:
database:
type: dynamodb
region: us-west-2
flowTableName: "tams-flows"
serviceTableName: "tams-services"
mediaObjectTableName: "tams-media-objects"
backends:
- id: 4a6c17c4-977a-4e69-b5e1-c12cde6f9253
type: s3
default: true
bucketName: my-tams-bucket
region: us-west-2
replicas: 1
secretName: tams-aws-secret
logs:
level: infoApply the Store:
kubectl apply -f store.yamlCheck the Store status:
kubectl get stores
kubectl describe store my-storeThe Store custom resource describes the desired configuration of a TAMS instance.
| Field | Required | Type | Description |
|---|---|---|---|
| type | yes | string | dynamodb or memory |
| region | yes (dynamodb) | string | AWS region |
| flowTableName | yes | string | DynamoDB table for flows |
| flowDeleteRequestTableName | yes | string | DynamoDB table for flows delete request |
| sourceTableName | yes | string | DynamoDB table for sources |
| serviceTableName | yes | string | DynamoDB table for services |
| mediaObjectTableName | yes | string | DynamoDB table for media objects |
| endpoint | no | string | Custom database endpoint |
| Field | Required | Type | Description |
|---|---|---|---|
| id | yes | string (UUID) | Backend unique identifier |
| type | yes | string | s3 |
| default | no | boolean | Marks the default backend |
| bucketName | yes | string | S3 bucket name |
| region | yes | string | AWS region |
| Field | Required | Type | Description |
|---|---|---|---|
| replicas | no | number | Number of replicas (default: 1) |
| secretName | yes | string | Kubernetes secret with credentials |
| serviceAccountName | no | string | Service account name |
| logs.level | no | string | debug, info, warn, error |
| server.port | no | number | API port (default: 3000) |
Once a Store is deployed, the TAMS service exposes a REST API. Access the service:
# Port-forward to access the service locally
kubectl port-forward svc/my-store 3000:3000# Create a flow
curl -X POST http://localhost:3000/flows \
-H "Content-Type: application/json" \
-d '{
"label": "my-flow",
"description": "Example flow"
}'
# List flows
curl http://localhost:3000/flows
# Get a specific flow
curl http://localhost:3000/flows/{flowId}This section is intended for contributors working on the controller or the service.
- Go 1.25.1+
- Node.js and npm
- Docker
- kubectl
cd k8s-controller
go mod download
go test ./...cd service
npm install
npm run testContributions of any kind are welcome to help improve this project.
- Bug reports and fixes
- Documentation improvements
- Feature proposals
Please read our contributing guidelines before submitting a pull request or issue.
Copyright 2025 TrackIt
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at LICENSE
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
For questions, suggestions, or support, please open an issue on GitHub or contact us via the blog.