Skip to main content
Job installations deploy job services to environments. Jobs can run on a cron schedule, be triggered manually via Run Now, or both. Configure environment variables, resource limits, and service-specific settings for your batch jobs, migrations, and scheduled tasks.
# yaml-language-server: $schema=https://api.ryvn.app/v1/schemas/resources.json
kind: ServiceInstallation
metadata:
  name: migrations-production
spec:
  service: migrations
  environment: production
  variableGroups:
    - name: shared-config
  env:
    - key: DATABASE_URL
      isSecret: true
  config: |
    schedule: "0 2 * * *"
    resources:
      requests:
        cpu: 0.25
        memory: 512Mi

Properties

service

string — required Name of the job service to install.
service: migrations

environment

string — required Target environment for this installation.
environment: production

name

string — optional Custom name for this installation. If not specified, uses the service name.
name: db-migrations

namespace

string — optional Kubernetes namespace to install into. If not provided, uses the environment’s default namespace.
namespace: jobs

releaseChannel

string — optional Release channel to follow for this installation. If not specified, uses the environment’s channel. Mutually exclusive with branch.
releaseChannel: stable

branch

string — optional Branch to track for this installation. The service must have the branch listed in build.branches. When set, the installation deploys whatever was last built on that branch. Mutually exclusive with releaseChannel.
branch: staging

variableGroups

array — optional List of variable group references to link to this installation. Each entry references a variable group by name that must already exist in the target environment. Variable groups provide shared sets of environment variables across installations.
variableGroups:
  - name: shared-config
  - name: database-credentials

variableGroups[].name

string — required Name of the variable group in the target environment.
variableGroups:
  - name: shared-config

env

array — optional Environment variables for the job service. Each variable specifies whether it’s a secret.
env:
  - key: DATABASE_URL
    isSecret: true
  - key: MIGRATION_MODE
    isSecret: false
    value: safe

env[].key

string — required Environment variable name.
key: DATABASE_URL

env[].isSecret

boolean — required Whether this environment variable is a secret. If true, value must be set on the platform when the blueprint is installed.
isSecret: true

env[].value

string — conditional Environment variable value. Cannot be set if isSecret is true.
value: safe

env[].orgSecret

string — optional Name of organization-level secret to get values from. All key-value pairs from the organization secret are exploded out as environment variables. Cannot be used with key, isSecret, or value.
Prefer using variableGroups instead of orgSecret for sharing secrets across installations. Variable groups provide better visibility, versioning, and audit logging.
env:
  - orgSecret: database-credentials

env[].valueFromInput

object — optional Reference to a blueprint input for the value. If the referenced input has a condition that evaluates to false, this environment variable is automatically omitted.
env:
  - key: API_KEY
    isSecret: true
    valueFromInput:
      name: apiKey

env[].valueFromOutput

object — optional Reference to an output from a service installation or blueprint installation. Exactly one of serviceInstallation or blueprintInstallation must be specified.
Prefer valueFromOutput over template functions like {{ (serviceInstallation "...").outputs.x }} or {{ (blueprintInstallation "...").outputs.x }} in env var values. Template functions render outputs as plaintext, which means secrets end up in manifests and logs. valueFromOutput routes secret outputs through the secrets system so they are never exposed in plaintext.
Properties:
PropertyTypeDescription
serviceInstallationstringName of the service installation to get the output from.
blueprintInstallationstringName of the blueprint installation to get the output from.
namestring(required) Name of the output. Supports dot notation for nested values (e.g., bucket.name).
env:
  # Reference a service installation output
  - key: DATABASE_HOST
    valueFromOutput:
      serviceInstallation: postgres-rds
      name: endpoint

  # Reference a blueprint installation output
  - key: CACHE_HOST
    valueFromOutput:
      blueprintInstallation: cache-stack
      name: host

  # Secret output — routed through the secrets system automatically
  - key: DATABASE_URL
    isSecret: true
    valueFromOutput:
      blueprintInstallation: database-stack
      name: connection_string
To concatenate an output with other values, use valueFromOutput to set a base env var and reference it with $(VAR) syntax in a subsequent variable. The referenced variable must appear earlier in the list:
env:
  - key: DATABASE_HOST
    valueFromOutput:
      serviceInstallation: postgres-rds
      name: endpoint
  - key: DATABASE_URL
    value: "postgresql://$(DATABASE_HOST):5432/mydb"

config

string or array — optional Service configuration. For jobs, this is the Helm chart values.yaml content. Configure scheduling, concurrency, resources, and more.
# As string
config: |
  schedule: "0 2 * * *"
  concurrencyPolicy: Forbid
  backoffLimit: 3
  resources:
    limits:
      cpu: 500m
      memory: 512Mi
    requests:
      cpu: 250m
      memory: 256Mi

# As array with file path
config:
  - path: config/production.yaml

config.image

object — optional Container image configuration.
config: |
  image:
    repository: myapp
    pullPolicy: IfNotPresent
    tag: v1.0.0

config.imagePullSecrets

array — optional Secrets for pulling images from private registries.
config: |
  imagePullSecrets:
    - name: regcred

config.serviceAccount

object — optional Service account configuration.
config: |
  serviceAccount:
    create: true
    automount: true
    annotations: {}
    name: ""

config.podAnnotations

object — optional Kubernetes annotations for pods.
config: |
  podAnnotations:
    karpenter.sh/do-not-disrupt: "true"

config.podLabels

object — optional Kubernetes labels for pods.
config: |
  podLabels:
    app: myapp
    tier: jobs

config.podSecurityContext

object — optional Security context for the pod.
config: |
  podSecurityContext:
    fsGroup: 2000
    runAsNonRoot: true
    runAsUser: 1000

config.securityContext

object — optional Security context for the container.
config: |
  securityContext:
    capabilities:
      drop:
        - ALL
    readOnlyRootFilesystem: true
    runAsNonRoot: true
    runAsUser: 1000

config.schedule

string — optional Cron schedule expression for the job. When omitted, the job is deployed as a manual-only job that never runs automatically and can only be triggered via the Run Now button in the UI or the trigger-job CLI command.
# Scheduled job
config: |
  schedule: "0 2 * * *"

# Manual-only job (omit schedule)
config: |
  concurrencyPolicy: Forbid

config.concurrencyPolicy

string — optional How to handle concurrent executions. Valid values: Forbid, Allow, Replace. Defaults to Forbid.
config: |
  concurrencyPolicy: Forbid

config.startingDeadlineSeconds

integer — optional Time in seconds for starting the job if it misses scheduled time.
config: |
  startingDeadlineSeconds: 300

config.successfulJobsHistoryLimit

integer — optional Number of successful job executions to keep. Defaults to 3.
config: |
  successfulJobsHistoryLimit: 5

config.failedJobsHistoryLimit

integer — optional Number of failed job executions to keep. Defaults to 1.
config: |
  failedJobsHistoryLimit: 3

config.suspend

boolean — optional Suspend job scheduling. Defaults to false.
config: |
  suspend: true

config.backoffLimit

integer — optional Number of retries before considering a job as failed. Defaults to 1.
config: |
  backoffLimit: 3

config.ttlSecondsAfterFinished

integer — optional Time to live in seconds after job finishes before automatic cleanup.
config: |
  ttlSecondsAfterFinished: 3600

config.labels

object — optional Additional labels for the CronJob metadata.
config: |
  labels:
    team: data

config.annotations

object — optional Additional annotations for the CronJob metadata.
config: |
  annotations:
    description: "Daily ETL job"

config.restartPolicy

string — optional Pod restart policy. Valid values: Never, OnFailure. Defaults to Never.
config: |
  restartPolicy: OnFailure

config.command

array — optional Override container’s default entrypoint.
config: |
  command:
    - /bin/sh
    - -c

config.args

array — optional Arguments to container’s entrypoint.
config: |
  args:
    - python
    - migrate.py

config.env

array — optional Environment variables passed to the container (in addition to the installation-level env field).
config: |
  env:
    - name: DEBUG
      value: "true"

config.envFrom

array — optional Environment variables from ConfigMaps or Secrets.
config: |
  envFrom:
    - configMapRef:
        name: job-config

config.resources

object — optional Container resource requests and limits.
config: |
  resources:
    limits:
      cpu: 500m
      memory: 512Mi
    requests:
      cpu: 250m
      memory: 256Mi

config.volumes

array — optional Additional volumes for the job.
config: |
  volumes:
    - name: data
      emptyDir: {}

config.volumeMounts

array — optional Additional volume mounts for the container.
config: |
  volumeMounts:
    - name: data
      mountPath: /data

config.nodeSelector

object — optional Node selector for pod scheduling.
config: |
  nodeSelector:
    disktype: ssd

config.tolerations

array — optional Tolerations for pod scheduling.
config: |
  tolerations:
    - key: node.kubernetes.io/not-ready
      operator: Exists
      effect: NoExecute

config.affinity

object — optional Affinity rules for pod scheduling.
config: |
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: node-type
                operator: In
                values:
                  - batch

resources

object — optional Resource requirements for the service.
resources:
  cpuCores: 1
  memoryMB: 2048

resources.cpuCores

number — required Number of CPU cores. Can be fractional (e.g., 0.5, 1, 2).
resources:
  cpuCores: 1

resources.memoryMB

integer — required Memory in megabytes. Must be a positive integer.
resources:
  memoryMB: 2048

Examples

ETL job with scheduling:
kind: ServiceInstallation
metadata:
  name: etl-pipeline-production
spec:
  service: etl-pipeline
  environment: production
  env:
    - key: SOURCE_DB
      isSecret: true
    - key: TARGET_DB
      isSecret: true
    - key: BATCH_SIZE
      value: "1000"
  config: |
    schedule: "0 2 * * *"
    concurrencyPolicy: Forbid
    successfulJobsHistoryLimit: 7
    failedJobsHistoryLimit: 3
    backoffLimit: 3
    ttlSecondsAfterFinished: 86400
With variable groups:
kind: ServiceInstallation
metadata:
  name: backup-job-production
spec:
  service: backup-job
  environment: production
  variableGroups:
    - name: aws-backup-credentials
  env:
    - key: BACKUP_SCHEDULE
      value: daily