Examples

Score examples

The following examples show how to use Score to deploy Applications and infrastructure configurations.

Each example highlights a particular use case and shows either a Score file (score.yaml), a Score extension file (humanitec.score.yaml), or both.

To use any particular example, use the humctl CLI and execute this command:

humctl score deploy \
              -f score.yaml \
              --extensions humanitec.score.yaml
              --app ${APP_ID} \
              --env ${ENV_ID} \
              --org ${HUMANITEC_ORG} \
              --token ${HUMANITEC_TOKEN} \

Usage notes:

  • If both files are shown, they must be used in conjunction.
  • If no Score file or no Score extension file is shown, no particular configuration is required through that file.
  • A Score extension file alone is never sufficient to perform a Workload Deployment. If no Score file is shown, you may choose one of your own, e.g. the Hello World example.
  • A Score file is picked up automatically if present in the same directory and named score.yaml.
  • A Score extension file is not picked up automatically, it must be spefified using the --extensions flag.
  • Make sure to use the proper types in your Score and Score extensions files to prevent deployment errors. They will be passed through as-is. E.g. when setting the boolean value for the setHostnameAsFQDN property in the PodSpec , configure it in the extension file like this:
apiVersion: humanitec.org/v1b1
spec:
  pod:
    setHostnameAsFQDN: true ## Not "true"

Affinity

Define affinity rules that are added to Pods generated for the Workload.


humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  pod:
    affinity:
      nodeAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1
          preference:
            matchExpressions:
            - key: disktype
              operator: In
              values:
              - ssd

Annotations

Define Annotations that are added to Kubernetes objects generated for the Workload.


humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  # Set annotations on the Kubernetes Deployment
  deployment:
    annotations:
      deploymentannotationkey: deploymentannotationvalue
  # Set annotations on the Kubernetes Pod
  pod:
    annotations:
      podannotationkey: podannotationvalue
  # Set annotations on the Kubernetes Service
  service:
    annotations:
      serviceannotationkey: serviceannotationvalue

score.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
service:
  ports:
    http:
      port: 80
      targetPort: 8080

Argument and command overrides

Provide overrides for container commands or arguments.


score.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
    command: ["/bin/sh"]
    args: ["-c", "while true; do printenv && sleep 60; done"]

Cronjobs

Define your workload to be deployed as a Kubernetes CronJob through a Score extension file.

The extension file needs to request a Workload Profile which creates a CronJob, such as the built-in default-cronjob Workload Profile.

The CronJob schedules are defined in the spec.schedules section of the extension file. Refer to the schedules feature for configuration details.

You may optionally also set additional properties for the Kubernetes CronJob, Job, and Pod objects which will be created. You can set almost any property of the Kubernetes API specifications for those objects. Refer to the CronJob feature , Job feature , and Pod feature descriptions for details on supported properties.


humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1
# Select the "default-cronjob" built-in Workload Profile
profile: humanitec/default-cronjob

spec:
  # Define the CronJob schedules
  schedules:
    6-hour-run:
      containers:
        main-container:
          args:
            - "--hours"
            - "6"
      schedule: "15 1,7,13,19 * * *"
  cronjob:
    # Set annotations and labels in the CronJob object metadata
    annotations:
      cronjobannotationkey: cronjobannotationvalue
    labels:
      cronjoblabelkey: cronjoblabelvalue
    # Set properties of the CronJobSpec, e.g.:
    timeZone: Africa/Lagos
    concurrencyPolicy: Forbid
  job:
    # Set annotations and labels in the Job object metadata for the Jobs created out of the CronJob
    annotations:
      jobannotationkey: jobannotationvalue
    labels:
      joblabelkey: joblabelvalue
    # Set properties of the JobSpec, e.g.:
    activeDeadlineSeconds: 30
    ttlSecondsAfterFinished: 3600
  pod:
    # Set Pod annotations and labels in Pod metadata
    annotations:
      podannotationkey: podannotationvalue
    labels:
      podlabelkey: podlabelvalue
    # Set properties of the PodSpec, e.g.:
    nodeSelector:
      topology.kubernetes.io/region: europe-west3
    os:
      name: linux

score.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1

metadata:
  name: my-cronjob

containers:
  main-container:
    image: registry/my-image:1.0.0

Deployments

For a Workload that is deployed as a Kubernetes Deployment, you can set properties of the Kubernetes DeploymentSpec on the Kubernetes Deployment object through a Score extension file for your workload.

You can set almost any property of the Kubernetes API specification for this objects. Refer to the Deployment feature for details on supported properties.


humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  deployment:
    # Set annotations and labels in the Deployment object metadata
    annotations:
      deploymentannotationkey: deploymentannotationvalue
    labels:
      deploymentlabelkey: deploymentlabelvalue
    # Set properties of the DeploymentSpec, e.g.:
    minReadySeconds: 10
    replicas: 2
    strategy:
      rollingUpdate:
        maxSurge: 30%
  # Set properties of the PodSpec, e.g.:
  pod:
    nodeSelector:
      topology.kubernetes.io/region: europe-west3
    os:
      name: linux

Environment variables

Define environment variables for a container. There are two ways to configure them.

  1. Via the Score file

    The Score specification supports placeholder references to the Workload metadata or Resources named in the Score file. The syntax and supported values are different in Score compared to the Platform Orchestrator, and the Platform Orchestrator will automatically convert Score references to native placeholders when deploying a Score file. Variables will be mapped into the container through a ConfigMap or Secret .

    The Platform Orchestrator supports an environment resource for accessing the shared values in the application environment:

    apiVersion: score.dev/v1b1
    metadata:
      name: example
    containers:
      main:
        image: example
        variables:
          KEY_ONE: hello-world
          KEY_TWO: ${resources.env.VALUE}
    resources:
      env:
        type: environment
    
  2. Via the Score extensions file

    Score extensions files contain Platform Orchestrator specific content allowing the workload profile or deployment options to be configured along with overrides to the resulting workloads. The Score extensions file supports the use of Score placeholder references and native placeholders when escaped with a $.

    apiVersion: humanitec.org/v1b1
    spec:
      containers:
        main:
          variables:
            KEY_THREE: $${values.VALUE}
            KEY_FOUR: goodbye
    

humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  containers:
    demo:
      variables:
        SOME: VARIABLE
        SHARED_VALUE: $${values.SOMETHING}

score.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
    variables:
      API_KEY: "${resources.env.API_KEY}"
resources:
  env:
    # The type "environment" is available per the Score specification.
    type: environment

Files

Add files to Containers.

Refer to the files feature for configuration details.

The examples show these variations to provide file content:

  • score.yaml: Base approach supplying the file contents as a multiline string. This approach creates the same file content across all environments.
  • score-shared-values.yaml: (Recommended) Supplying the file contents via a Shared Value via the environment resource which is available as part of the Score specification . Since Shared Values may optionally be overridden on an Environment level, this approach lets you inject environment-specific configuration managed through the Platform Orchestrator.
  • score-local-file-source.yaml: Supplying the file contents via a file available locally which is read at Score deployment time, i.e. when executing humctl score deploy.

appsettings.json ( view on GitHub ) :

{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}

score-local-file-source.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
    files:
      - target: /app/default.config
        mode: "0644"
        # The source references a locally available file
        # It is read by the humctl CLI when running "humctl score deploy"
        source: "./appsettings.json"

score-shared-values.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
    files:
      - target: /app/default.config
        mode: "0644"
        # The content references the Shared Value APP_SETTINGS, available through the "env" resource declared below
        content: "${resources.env.APP_SETTINGS}"
resources:
  env:
    # The type "environment" is available per the Score specification
    type: environment

score.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
    files:
      - target: /app/default.config
        mode: "0644"
        content: |
          [config]
          key=value

Jobs

Define your workload to be deployed as a Kubernetes Job through a Score extension file.

The extension file needs to request a Workload Profile which creates a Job, such as the built-in default-job Workload Profile.

You may optionally also set additional properties for the Kubernetes Job and Pod objects which will be created. You can set almost any property of the Kubernetes API specifications for those objects. Refer to the Job feature and Pod feature descriptions for details on supported properties.


humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1
# Select the "default-job" bulit-in Workload Profile
profile: humanitec/default-job

spec:
  job:
    # Set annotations and labels in the Job object metadata
    annotations:
      jobannotationkey: jobannotationvalue
    labels:
      joblabelkey: joblabelvalue
    # Set properties of the JobSpec, e.g.:
    activeDeadlineSeconds: 30
    ttlSecondsAfterFinished: 3600
  pod:
    # Set Pod annotations and labels in Pod metadata
    annotations:
      podannotationkey: podannotationvalue
    labels:
      podlabelkey: podlabelvalue
    # Set properties of the PodSpec, e.g.:
    nodeSelector:
      topology.kubernetes.io/region: europe-west3
    os:
      name: linux

Labels

Define Labels that will be added to Pods or Services generated for the Workload.


humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  # Set labels on the Kubernetes Deployment
  deployment:
    labels:
      deploymentlabelkey: deploymentlabelvalue
  # Set labels on the Kubernetes Pod
  pod:
    labels:
      podlabelkey: podlabelvalue
  # Set labels on the Kubernetes Service
  service:
    labels:
      servicelabelkey: servicelabelvalue

score.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

service:
  ports:
    http:
      port: 80
      targetPort: 8080

containers:
  demo:
    image: registry/my-image:1.0.0

Multiple workloads

This example shows how to deploy multiple workloads within one deployment.

Doing so requires a separate Score file per workload (score.example-service.yaml and score.another-service.yaml). The example also uses a Score extension file (score.humanitec.yaml) to apply some common settings to both workloads.

The file deploy-config.yaml wraps all those files into a deploy configuration which can be passed in to humctl using the --deploy-config flag. See the CLI documentation for details.


deploy-config.yaml ( view on GitHub ) :

apiVersion: config.humanitec.io/v1b1
kind: ScoreDeployConfig
workloads:
  - name: example-service
    specFile: ./score.example-service.yaml
    extensionsFile: ./score.humanitec.yaml
  - name: another-service
    specFile: ./score.another-service.yaml
    extensionsFile: ./score.humanitec.yaml


score.another-service.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: another-service

containers:
  demo:
    image: registry/my-image:1.0.0
    command: ["/bin/sh"]
    args: ["-c", "while true; do printenv && sleep 60; done"]


score.example-service.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: example-service

containers:
  demo:
    image: registry/my-image:1.0.0
    command: ["/bin/sh"]
    args: ["-c", "while true; do printenv && sleep 60; done"]


score.humanitec.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1
spec:
  containers:
    demo:
      resources:
        limits:
          cpu: "500m"
          memory: "256Mi"

Overrides

Provide overrides for container commands or arguments.


score.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
    command: ["/bin/sh"]
    args: ["-c", "while true; do printenv && sleep 60; done"]

Pods

You may set additional properties for the Kubernetes Pod objects which will be created for your workload. You can set almost any property of the Kubernetes API specification for this object. Refer to the Pod feature description for details on supported properties.


humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  pod:
    # Set Pod annotations and labels in the Pod metadata
    annotations:
      podannotationkey: podannotationvalue
    labels:
      podlabelkey: podlabelvalue
    # Set properties of the PodSpec, e.g.:
    nodeSelector:
      topology.kubernetes.io/region: europe-west3
    os:
      name: linux

Probes

Define liveness and readiness probes for your Workload.

Refer to the probe feature for configuration details.


humanitec.score.command.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  containers: 
    demo:
      liveness_probe:
        type: command
        command:
          - "bash"
          - "-c"
          - "/app/is_alive.sh"

humanitec.score.grpc.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  containers: 
    demo:
      liveness_probe:
        type: grpc
        port: 7001

humanitec.score.tcp.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  containers: 
    demo:
      liveness_probe:
        type: tcp
        port: 7001

score.http.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
    livenessProbe:
      httpGet:
        path: "/alive"
        port: 8080
    readinessProbe:
      httpGet:
        path: "/ready"
        port: 8080

Resources

Specify the resources required for a container.


score.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
    resources:
      limits:
        cpu: "0.250"
        memory: "256Mi"
      requests:
        cpu: "0.025"
        memory: "64Mi"

Route

A route resource defines how to route traffic to the Workload. See Routes and Ingress for details.


score.yaml ( view on GitHub ) :

# Example Score file for a Workload that has three routes from one DNS name
apiVersion: score.dev/v1b1
metadata:
  name: routes-example
service:
  ports:
    www:
      port: 80
      targetPort: 8080
containers:
  webserver:
    image: my-webservice:latest
resources:
  api-dns:
    type: dns
  users-route:
    type: route
    params:
      host: ${resources.api-dns.host}
      path: /users
      port: 80
  products-route:
    type: route
    params:
      host: ${resources.api-dns.host}
      path: /products
      port: 80
  checkout-route:
    type: route
    params:
      host: ${resources.api-dns.host}
      path: /checkout
      port: 80

Service

Define how a service for the Workload is configured.

Refer to the service feature for configuration details.

You may optionally set annotations and labels on the Kubernetes Service object through a Score extension file.


humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  service:
    # Set annotations on the Kubernetes Service
    annotations:
      serviceannotationkey: serviceannotationvalue
    # Set labels on the Kubernetes Service
    labels:
      servicelabelkey: servicelabelvalue

score.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
service:
  ports:
    www:
      port: 8080
      targetPort: 3001
    stream:
      port: 19245
      targetPort: 19245
      protocol: UDP

Serviceaccount

Define the Kubernetes Service Account that Pods in the Workload should run as. It does not manage the creation of that Service Account.

Refer to the Pod feature for configuration details.


humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  pod:
    serviceAccountName: data-access-service-account

Shared resource

When several Workloads need to use the same real-world Resource, this can be modelled as a Shared Resource .

Workloads using the Shared Resource will then reference the same node in the Resource Graph.

Example: Shared DNS

This example shows a frontend and a backend Workload. Both are exposed via DNS. The frontend is exposed via an external DNS, and it needs to access the backend via it associated DNS name as well. It therefore requires the backend DNS name to be injected as an environment variable.

To achieve this, the backend dns is made a Shared Resource by assigning it an id in Score. Both Score files need to use the same id to reference the same Resource.

Note that the Workloads refer to the Shared Resource using a different resource name (api-dns vs. my-dns). That name is local to the Score file and may be different.

The frontend has an additional dns for its own reachability. All dns resources are used in conjunction with a route.

The respective portions of the Resource Graph will then look like this:

---
title: Resource Graph
---
flowchart LR
    frontend(frontend) --> fe-route(route) --> fe-dns(dns)
    frontend --> fe-dns
    backend(backend) --> be-route(route) --> be-dns(dns)
    frontend ---> be-dns
    backend --> be-dns

Example files:

  • score-frontend.yaml: Score file for the frontend Workload
  • score-backend.yaml: Score file for the backend Workload

score-backend.yaml ( view on GitHub ) :

# Example Score file for a Workload using a Shared Resource to provide its DNS name to another Workload
apiVersion: score.dev/v1b1
metadata:
  name: shared-resource-example-backend

containers:
  backend:
    image: my-be-service:latest

resources:
  # This resource becomes a Shared Resource by assiging it an "id"
  # Other Workloads using the same id will reference the same resource
  my-dns:
    type: dns
    id: backend-dns
  my-route:
    type: route
    params:
      host: ${resources.my-dns.host}
      path: /
      port: 8765

score-frontend.yaml ( view on GitHub ) :

# Example Score file for a Workload using a Shared Resource to obtain the DNS name of another Workload
apiVersion: score.dev/v1b1
metadata:
  name: shared-resource-example-frontend

containers:
  frontend:
    image: my-fe-service:latest
    variables:
      # Inject the DNS name of the backend service as an environment variable
      API_URL: https://${resources.api-dns.host}

resources:
  # This resource becomes a Shared Resource by assiging it an "id"
  # Other Workloads using the same id will reference the same resource
  api-dns:
    type: dns
    id: backend-dns
  fe-dns:
    type: dns
  fe-route:
    type: route
    host: ${resources.fe-dns.host}
      path: /
      port: 80

Tolerations

Define tolerations rules that are added to Pods generated for the Workload.


humanitec.score.yaml ( view on GitHub ) :

apiVersion: humanitec.org/v1b1

spec:
  pod:
    tolerations:
    - key: "my-example-key"
      operator: "Exists"
      effect: "NoSchedule"

Volumes

Define volumes and volume mounts for a Workload.

Volume mounts are declared in the volumes section of the Score file. There should be a resource of type volume backing the volume.

One trick is that the content of source in the volume section should only reference the name of the resource, not an output. For example: ${resources.my-volume}.


score.yaml ( view on GitHub ) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload

containers:
  demo:
    image: registry/my-image:1.0.0
    volumes:
      - source: ${resources.my-volume}
        target: /mnt/my-volume
        readOnly: true

resources:
  my-volume:
    type: volume
Top