Specification

Resources

Provisioner

Azure Blob


score.yaml (view on GitHub) :

apiVersion: score.dev/v1b1
metadata:
  name: my-workload
containers:
  my-container:
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $AZURE_STORAGE_CONNECTION_STRING; sleep 5; done"]
    variables:
      AZURE_STORAGE_CONNECTION_STRING: "${resources.blob.connection_string}"
      AZURE_STORAGE_ACCOUNT: "${resources.blob.account_name}"
      AZURE_STORAGE_KEY: "${resources.blob.account_key}"
      AZURE_BLOB_ENDPOINT: "${resources.blob.blob_endpoint}"
      AZURE_BLOB_CONTAINER: "${resources.blob.container}"
resources:
  blob:
    type: azure-blob
    params:
      container: my-workload-data

Initialize your local workspace, by importing a specific community provisioner:

score-compose init --provisioners REPLACE-ME-WITH-ACTUAL-PROVISIONER-FILE-URL.yaml

Note: you need to replace REPLACE-ME-WITH-ACTUAL-PROVISIONER-FILE-URL.yaml by the actual provisioner file you want to use and import. More information here.

Get the provisioners definition:

score-compose provisioners list

Generate the platform specific manifests:

score-compose generate score.yaml

See the resource outputs:

score-compose resources list

You can run the following command on each resource listed with the previous command to get their outputs:

score-compose resources get-outputs

Deploy the generated manifests:

docker compose up -d

See the running containers:

docker ps


10-azurite-azure-blob.provisioners.yaml (view on GitHub) :

# Azurite (Azure Storage emulator) provisioner for the azure-blob resource type.
# Runs Azurite in the cluster and gives the workload a connection string plus the
# well-known dev-storage credentials, so apps using the Azure Blob SDK can work
# against it locally without a real Azure Storage account.
# See https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite
- uri: template://community-provisioners/azurite-azure-blob
  type: azure-blob
  description: Generates an Azurite (Azure Storage emulator) StatefulSet and Service exposing the blob endpoint.
  supported_params:
    - container
  init: |
    blobPort: 10000
    accountName: devstoreaccount1
    accountKey: "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
    defaultContainer: blob-{{ randAlphaNum 6 | lower }}    
  state: |
    service: azurite-{{ .SourceWorkload }}-{{ substr 0 8 .Guid | lower }}
    container: {{ dig "container" (.Params.container | default .Init.defaultContainer) .State | quote }}    
  outputs: |
    connection_string: "DefaultEndpointsProtocol=http;AccountName={{ .Init.accountName }};AccountKey={{ .Init.accountKey }};BlobEndpoint=http://{{ .State.service }}:{{ .Init.blobPort }}/{{ .Init.accountName }};"
    account_name: {{ .Init.accountName | quote }}
    account_key: {{ .Init.accountKey | quote }}
    blob_endpoint: "http://{{ .State.service }}:{{ .Init.blobPort }}/{{ .Init.accountName }}"
    container: {{ .State.container | quote }}    
  expected_outputs:
    - connection_string
    - account_name
    - account_key
    - blob_endpoint
    - container
  manifests: |
    - apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: {{ .State.service }}
        {{ if ne .Namespace "" }}
        namespace: {{ .Namespace }}
        {{ end }}
        annotations:
          k8s.score.dev/source-workload: {{ .SourceWorkload }}
          k8s.score.dev/resource-uid: {{ .Uid }}
          k8s.score.dev/resource-guid: {{ .Guid }}
        labels:
          app.kubernetes.io/managed-by: score-k8s
          app.kubernetes.io/name: {{ .State.service }}
          app.kubernetes.io/instance: {{ .State.service }}
      spec:
        serviceName: {{ .State.service }}
        replicas: 1
        selector:
          matchLabels:
            app.kubernetes.io/instance: {{ .State.service }}
        template:
          metadata:
            labels:
              app.kubernetes.io/managed-by: score-k8s
              app.kubernetes.io/name: {{ .State.service }}
              app.kubernetes.io/instance: {{ .State.service }}
          spec:
            containers:
              - name: azurite
                image: mcr.microsoft.com/azure-storage/azurite:latest
                command: ["azurite-blob"]
                args:
                  - --blobHost
                  - 0.0.0.0
                  - --blobPort
                  - "{{ .Init.blobPort }}"
                  - --location
                  - /data
                ports:
                  - name: blob
                    containerPort: {{ .Init.blobPort }}
                volumeMounts:
                  - name: data
                    mountPath: /data
                readinessProbe:
                  tcpSocket:
                    port: {{ .Init.blobPort }}
                  initialDelaySeconds: 5
                  periodSeconds: 5
                securityContext:
                  allowPrivilegeEscalation: false
                  capabilities:
                    drop:
                      - ALL
            securityContext:
              fsGroup: 1000
        volumeClaimTemplates:
          - metadata:
              name: data
            spec:
              accessModes: ["ReadWriteOnce"]
              resources:
                requests:
                  storage: 1Gi
    - apiVersion: v1
      kind: Service
      metadata:
        name: {{ .State.service }}
        {{ if ne .Namespace "" }}
        namespace: {{ .Namespace }}
        {{ end }}
        annotations:
          k8s.score.dev/source-workload: {{ .SourceWorkload }}
          k8s.score.dev/resource-uid: {{ .Uid }}
          k8s.score.dev/resource-guid: {{ .Guid }}
        labels:
          app.kubernetes.io/managed-by: score-k8s
          app.kubernetes.io/name: {{ .State.service }}
          app.kubernetes.io/instance: {{ .State.service }}
      spec:
        selector:
          app.kubernetes.io/instance: {{ .State.service }}
        type: ClusterIP
        ports:
          - port: {{ .Init.blobPort }}
            targetPort: {{ .Init.blobPort }}
            name: blob    

README.md (view on GitHub) :

## For `10-azurite-azure-blob.provisioners.yaml`

Runs [Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite), the Azure Storage emulator, as a `StatefulSet` with a 1Gi volume, and exposes its blob endpoint through a `ClusterIP` Service on port `10000`. It's meant for local development against the Azure Blob SDK without provisioning a real Storage account.

The workload gets these outputs:

- `connection_string` - ready to drop into `AZURE_STORAGE_CONNECTION_STRING` or pass to `BlobServiceClient`.
- `account_name`, `account_key` - Azurite's well-known dev account (`devstoreaccount1`).
- `blob_endpoint` - `http://<service>:10000/devstoreaccount1`.
- `container` - a container name for the workload to use. Override it with the `container` param.

A couple of things worth knowing:

- The account name and key are Azurite's [well-known credentials](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite#well-known-storage-account-and-key). They're the same for every Azurite instance and are published in the docs, so treat them as a local-dev convenience, not as secrets.
- Azurite starts empty. The `container` output is just a name - have your app create it on startup (`create_if_not_exists` / `createIfNotExists` exists in every Azure SDK), or run `az storage container create` against the endpoint once it's up.

Prerequisites:
- None beyond `score-k8s`. This is a template provisioner, so there's no `helm` or `yq` dependency.
- To actually run it, apply the generated manifests to any cluster. If you don't have one, `.scripts/setup-kind-cluster.sh` spins up a local Kind cluster.

Initialize your local workspace, by importing a specific community provisioner:

score-k8s init --provisioners REPLACE-ME-WITH-ACTUAL-PROVISIONER-FILE-URL.yaml

Note: you need to replace REPLACE-ME-WITH-ACTUAL-PROVISIONER-FILE-URL.yaml by the actual provisioner file you want to use and import. More information here.

Get the provisioners definition:

score-k8s provisioners list

Generate the platform specific manifests:

score-k8s generate score.yaml

See the resource outputs:

score-k8s resources list

You can run the following command on each resource listed with the previous command to get their outputs:

score-k8s resources get-outputs

Deploy the generated manifests:

kubectl apply -f manifests.yaml

See the running containers:

kubectl get all