Free — no signup required

Anatomy of a score.yaml

2 min read

Reading a Score File From First Principles

A score.yaml has four top-level sections. Here is a complete, annotated example:

# The Score API version. Versioned so the spec can evolve without breaking files.
apiVersion: score.dev/v1b1

metadata:
  name: my-backend-service   # Unique name for this workload

containers:
  main:                       # A logical name for this container within the workload
    image: my-repo/backend:latest
    variables:
      # Static value — known at write time
      DEBUG_MODE: "false"
      # Dynamic value — resolved at translation time by the implementation
      # Syntax: ${resources.<resource-name>.<output-key>}
      CONNECTION_STRING: postgres://${resources.db.host}:${resources.db.port}/app

service:
  ports:
    http:
      port: 8080        # The port exposed externally by the service
      targetPort: 8080  # The port the container actually listens on

resources:
  db:
    type: postgres      # Abstract type — the implementation decides what "postgres" means

Breaking Down Each Section

containers
Defines the container(s) in the workload. Each container has an image and optional environment variables. Multiple containers in one workload are supported (for sidecar patterns).

variables
Environment variables injected into the container. The key insight is the placeholder syntax: ${resources.db.host}. This is a resource output reference. The developer is saying: "I need the host of my db resource injected here, but I don't know what it will be — the platform does." The implementation resolves this at translation time.

service
Declares what ports this workload exposes. The port is what the outside world connects to; targetPort is what the container listens on. This maps directly to a Kubernetes Service spec, but Score keeps it abstract.

resources
The most powerful section. Each entry declares an abstract dependency by type. The developer does not specify a hostname, a connection string, or a cloud provider. They just say "I need a postgres." The implementation is responsible for:
- Locally: spinning up a Postgres container in the generated Compose file.
- In production: binding this to an existing RDS instance, a managed Cloud SQL database, or a Helm-deployed Postgres cluster — whatever the platform provides.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free