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