Skip to main content
Version: 0.12

Kubernetes operator

The Marmot operator runs pipelines as Kubernetes resources instead of from the CLI or the UI. Each pipeline discovers assets from a data source and syncs them into Marmot, while the cluster handles scheduling, retries and lifecycle for you. Pipeline config lives alongside your other manifests, so changes go through the same review and GitOps workflow as everything else.

The operator watches Run resources and reconciles them into Kubernetes Jobs or CronJobs. Each ingestion job runs as its own pod, so you can scope credentials per data source rather than giving a single Marmot instance access to all your assets. Separate pods also keep large or frequent ingestion runs from competing with each other.

The operator is deployed with Marmot by the Helm chart, so install Marmot with Helm first.

Enabling the operator​

Enable the operator in your Helm values:

operator:
enabled: true
helm upgrade marmot marmotdata/marmot -f values.yaml

Creating a Run​

A Run resource defines an ingestion pipeline. The spec.runs array uses the same format as the CLI configuration file.

apiVersion: runs.marmotdata.io/v1alpha1
kind: Run
metadata:
name: my-pipeline
spec:
schedule: "0 */6 * * *"
runs:
- postgresql:
host: "db.example.com"
port: 5432
database: "production"
user: "readonly"

The resource's metadata.name is used as the pipeline name for tracking ingestion state. If a pipeline with that name already exists in Marmot and was not created by the operator, the operator leaves it untouched and logs a warning; rename the Run, or delete the existing pipeline if the operator should own it.

kubectl apply -f my-pipeline.yaml

Credentials​

Keep credentials in a Kubernetes Secret rather than in the Run. Map each key into the ingestion container with env, then refer to it in runs as ${NAME}. The Job pod reads the Secret directly, so the value never appears in the Run, the rendered pipeline config or Marmot's database, and the operator itself needs no access to Secrets.

spec:
env:
- name: PG_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-readonly
key: password
runs:
- postgresql:
host: "db.example.com"
user: "readonly"
password: "${PG_PASSWORD}"

Variables starting with MARMOT_ are reserved for the operator and are rejected. Marmot stores operator-managed pipelines with their sensitive fields masked, because the server never runs them.

Ingestion pods authenticate to Marmot with their ServiceAccount token. That identity can only start and complete runs and write assets, lineage and documentation, so a token taken from an ingestion pod cannot administer Marmot.

Pod labels and annotations​

Use podLabels and podAnnotations to integrate ingestion pods with service meshes, observability tools or policy engines.

On AWS, this is particularly useful for providing credentials to plugins via IAM Roles for Service Accounts (IRSA). Instead of storing AWS credentials in your pipeline config, annotate the pod so it automatically receives IAM permissions:

spec:
podAnnotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/marmot-s3-reader"
podLabels:
team: data-engineering
runs:
- s3:
bucket: "my-data-lake"
region: "eu-west-1"

Manual triggers​

Trigger a scheduled pipeline outside its cron window by annotating the Run:

kubectl annotate run my-pipeline runs.marmotdata.io/trigger=true

This creates a temporary Job that runs immediately and cleans up after 60 seconds.

Teardown on delete​

By default, deleting a Run resource runs marmot ingest --destroy to remove all assets that pipeline previously discovered from Marmot. Set teardownOnDelete: false if you want to keep existing assets after removing the Run.

Reference​

Run spec​

FieldTypeDefaultDescription
runsarrayrequiredSource configurations, same format as CLI YAML
servebooleanfalseRun as a Deployment that ingests on start, then serves queries for the run marked queryable: true. See Serving Queries from Your Network. Cannot be combined with schedule
schedulestringCron expression. When set, creates a CronJob instead of a Job
suspendbooleanfalsePause scheduled executions. Only applies when schedule is set
concurrencyPolicyAllow / Forbid / ReplaceForbidHow to handle concurrent Job executions
backoffLimitint3Retries before marking a Job as failed
activeDeadlineSecondsintMaximum duration (seconds) a Job may run
successfulJobsHistoryLimitint3Successful CronJob runs to retain
failedJobsHistoryLimitint1Failed CronJob runs to retain
resourcesResourceRequirementsCPU/memory requests and limits for the ingestion container
envEnvVar arrayEnvironment variables for the ingestion container, referenced in runs as ${NAME}. MARMOT_ names are reserved
podLabelsmapAdditional labels applied to the pod template
podAnnotationsmapAdditional annotations applied to the pod template
teardownOnDeletebooleantrueRun marmot ingest --destroy when the Run is deleted

Operator Helm values​

KeyDefaultDescription
operator.enabledfalseEnable the operator Deployment and CRD
operator.replicas1Number of operator replicas
operator.leaderElecttrueEnable leader election for HA
operator.watchNamespace"" (all)Restrict to a single namespace
operator.marmot.urlauto-detectedMarmot API URL passed to Job pods
operator.resources100m/128Mi, 500m/256MiOperator pod resource requests and limits

Next steps​