Overview
Control Plane Task Runner is a self-hosted HTTP task queue and scheduler, similar to Google Cloud Tasks. You enqueue a task over HTTP and the workers deliver it to its target URL, with automatic retries, delayed and scheduled execution, per-client rate limiting and a circuit breaker. This template deploys the API, the workers, and the Redis Sentinel cluster they persist to.What Gets Created
reveal permission on secrets. The template’s identities have no cloud access and no permission on any other Control Plane resource.
Prerequisites
One secret must exist before you install: the admin API key. The/admin/* endpoints create, edit and delete clients and rate-limit tiers, and they are guarded by the X-Admin-Key header. Secrets are org-level, so no GVC flag is involved.
Create the admin key secret
plain whose payload is the key itself:printf, not echo. A trailing newline from echo becomes part of the key and then has to be sent in every admin request. Set api.admin.apiKeySecretName to this name.Read the key back later
-o yaml. A bare cpln secret reveal prints only a summary table, not the payload:change-me- defaults at install time.
Installation
Create the admin key secret first, then install with its name and your own Redis and Sentinel passwords:UI
CLI
Terraform
Pulumi
Configuration
Image
The same image runs both the API and the worker:API Workload
api.admin.apiKeySecretName to "" turns admin authentication off entirely. The chart permits that only while api.public.enabled is false.
Worker Workload
allowPrivateUrls: false is what keeps an enqueued task off internal addresses.
Secrets and Redis
createSecret is set to.
secretNameis an org-level name and is not prefixed with the release name. A second install in the same org needs a differentsecretName, with bothfromSecret.namevalues changed to match.- To bring your own secret, set
createSecret: false, create a dictionary secret holding the two keys named by thepasswordKeyfields, and point bothfromSecret.namevalues at it:
Connecting
/health/ready path as the workload readiness probe:
Enqueuing Tasks
Post a task to/v1/enqueue. With the default private API, send it from a workload in the same GVC to http://RELEASE_NAME-task-runner-api.GVC_NAME.cpln.local:8080, or through the tunnel above to http://127.0.0.1:8080:
Admin Endpoints
Every/admin/* request needs the X-Admin-Key header, whose value is the payload of your api.admin.apiKeySecretName secret:
Rate Limiting
Rate limits apply per client, and a client tier is assigned through the admin API:OpenTelemetry
SetotelEndpoint under api.env and worker.env to export traces. In the GVC settings, set the Tracing Provider to Control Plane, then use the built-in HTTP collector endpoint:
Operations
Backing Up
The Redis volume setRELEASE_NAME-redis-vs takes a snapshot every day and keeps each one for 7 days. List the snapshots:
Restoring a Backup
A restore procedure for this template has not been verified. Do not rely on the snapshots as a tested recovery path for queued tasks.Rotating the Admin Key
Apply the whole secret with a new payload, confirm it, then force a redeployment of the API. A running replica keeps the old key until it is redeployed:Upgrading From 1.2.x
Two defaults change, and both break an existing workflow that relied on the old behaviour.api.env.adminApiKey or redis.admin.fromSecret, or an empty apiKeySecretName while public access is on, is rejected at render before anything is applied.
Create the admin key secret
Drop the removed keys from your values
api.env.adminApiKey and redis.admin.fromSecret, and set api.admin.apiKeySecretName instead.Decide about public access
api.public.enabled now defaults to false. Read Public Access and the Open Queue before setting it back to true.Upgrade
Public Access and the Open Queue
api.public.enabled is false by default. Turning it on exposes the following:
/v1/enqueuerequires no credential. There is no header, token or signature to supply.- An unknown
client_idis auto-registered, not rejected. A client ID is therefore not a secret and not a control. - The API becomes a request relay. Anyone reaching it can make a worker send outbound HTTP with the method, headers and body they choose.
worker.env.allowPrivateUrls: falsekeeps those requests off internal addresses. /metricsis unauthenticated and its labels list everyclient_id.
api.public.enabled at false. Access changes can take several minutes to take effect, so re-test over that window.
Scaling and Availability
The API and worker are serverless workloads that autoscale on concurrent requests withinapi.replicas and worker.replicas. Raise worker.replicas.max or worker.env.concurrency for more delivery throughput. Redis runs as three replicas with three Sentinels, which elect a new primary if the current one fails.
Troubleshooting
The API workload never starts and cpln logs returns nothing
The API workload never starts and cpln logs returns nothing
api.admin.apiKeySecretName does not exist. get-deployments shows The secret SECRET_NAME no longer exists. Workload updates are paused until the secret is added or the reference to the secret removed.Fix: create the secret as in Prerequisites. The workload recovers on its own, or run cpln workload force-redeployment RELEASE_NAME-task-runner-api --gvc GVC_NAME.Install fails with apiKeySecretName is empty while api.public.enabled is true
Install fails with apiKeySecretName is empty while api.public.enabled is true
api.admin.apiKeySecretName is "" and public access is on. The chart refuses to publish unauthenticated admin endpoints.Fix: set api.admin.apiKeySecretName to your admin key secret, or set api.public.enabled: false.Install or upgrade fails with api.env.adminApiKey was REMOVED
Install or upgrade fails with api.env.adminApiKey was REMOVED
api.env.adminApiKey or redis.admin.fromSecret).Fix: follow Upgrading From 1.2.x.Admin requests are rejected
Admin requests are rejected
X-Admin-Key header is missing or does not match the secret payload, for example because the key was created with echo and carries a trailing newline, or the secret was rotated without a redeployment.Fix: read the key with cpln secret reveal SECRET_NAME -o yaml, and redeploy the API after any rotation.Tasks to internal addresses are never delivered
Tasks to internal addresses are never delivered
worker.env.allowPrivateUrls is false, so workers refuse private and internal targets.Fix: set it to true only if you accept that any enqueued task can then reach anything the worker can route to.Important Notes
- Create the admin key secret before installing. A missing secret wedges the API with no log output; the reason is in
status.versions[].message. - Leave
api.public.enabledatfalseunless an authenticating proxy fronts the API./v1/enqueueis unauthenticated and auto-registers unknown client IDs. - Change the
change-me-Redis and Sentinel passwords at install time. Once the volumes are initialised, changing them requires uninstalling (which deletes the volume sets) and reinstalling. secretNameis org-wide. Give each install in the same org its ownsecretNameand matchingfromSecret.namevalues.- Force a redeployment after rotating the admin key. A running replica keeps the old key.