//Azure Marketplace

Tutorial 10 — List and Deploy via Azure Marketplace

> Status note.* The Helm chart at deploy/helm/buttrbase-backend-rust/ is real and committed — you can run it against an AKS cluster right now using tutorial 07. The Azure Marketplace *listing* (the Partner Center offer, the Azure Container/Kubernetes application package, the certification pipeline) is forward-looking: this tutorial is a packaging guide for when you take that chart to market, not a guide to a listing that exists today. Steps that require a Microsoft Partner Center account are marked *[Marketplace listing — forward-looking] so the distinction is never ambiguous.

This tutorial is one layer thin: it explains what Azure Marketplace adds on top of the chart, how to push the image to Azure Container Registry so Azure can reference it, how the Kubernetes application offer wraps the chart, and what a customer sees when they install from the Marketplace. For everything about how Helm install actually works — topology values, secrets, the /health probe — see 07-deploy-with-helm.md. That document is the substrate; this one references it, it does not repeat it.

1. Why Azure Marketplace

Azure Marketplace lets an AKS customer deploy ButtrBase directly into their own Azure subscription* — they find the listing, click *Get It Now, pick a cluster, and the Marketplace UI drives the same Helm values the operator would set by hand. The purchase settles through their existing Azure billing account and can draw down Microsoft Azure Consumption Commitments (MACC) — meaning enterprises with committed Azure spend can apply that commitment to ButtrBase without a separate procurement motion.

This maps exactly to the single-tenant-byoc topology: the customer owns the AKS cluster, the Azure Database for PostgreSQL instance, and the Azure Blob Storage bucket. ButtrBase's Mothership provisions the tenant record and issues the encryption keys; the customer's infrastructure runs the workload. See the deployment matrix in docs/specs/federation-and-deployment-architecture.md for where single-tenant-byoc sits relative to the other topologies and why the marketplace path lands there.

| What Azure Marketplace provides | What you still own | |---------------------------------|--------------------| | Kubernetes application offer UI into customer's AKS | The Helm chart logic and values files | | Azure billing integration and MACC drawdown | Mothership provisioning and entitlement sync | | ACR hosting for the packaged offer image | The container image (ghcr.io/buttrbase/buttrbase-backend-rust) | | Marketplace listing search and discoverability | The support, SLA, and upgrade path |

2. Prerequisites

  • An Azure subscription with billing enabled and the following services accessible: Azure Container Registry (ACR)*, **Azure Kubernetes Service**, *Azure Database for PostgreSQL (for the customer's Postgres instance).
  • az CLI authenticated: az login.
  • An AKS cluster (1.25+) and kubectl configured against it.
  • Helm 3.12+.
  • Marketplace listing — forward-looking]* A Microsoft Partner Center account enrolled in the *Commercial Marketplace program. Partner onboarding is the gating step — Microsoft reviews the publisher application before you can create or submit a listing. See [Microsoft's commercial marketplace documentation for the current enrollment process.
  • 3. Create an Azure Container Registry

    The application image must live in ACR so Azure's validation pipeline and AKS pull policy can reach it. If you already have an ACR instance, skip the creation step.

    az acr create \
      --resource-group YOUR_RESOURCE_GROUP \
      --name YOUR_ACR_NAME \
      --sku Basic
    

    Authenticate Docker to the registry:

    az acr login --name YOUR_ACR_NAME
    

    Replace YOUR_RESOURCE_GROUP and YOUR_ACR_NAME throughout. The login step sets up the Docker credential helper for YOUR_ACR_NAME.azurecr.io.

    4. Push the application image to ACR

    The chart's default image is ghcr.io/buttrbase/buttrbase-backend-rust. The Marketplace offer must reference an ACR URI. Tag and push a pinned release — never list latest on a marketplace:

    Pull the image you want to list (pin a real tag)

    docker pull ghcr.io/buttrbase/buttrbase-backend-rust:0.1.0

    Tag for ACR

    docker tag \ ghcr.io/buttrbase/buttrbase-backend-rust:0.1.0 \ YOUR_ACR_NAME.azurecr.io/buttrbase/buttrbase-backend-rust:0.1.0

    Push

    docker push YOUR_ACR_NAME.azurecr.io/buttrbase/buttrbase-backend-rust:0.1.0

    After this step the image is accessible to AKS clusters that grant pull access to your ACR, and to Azure's offer validation scanner.

    5. Package the chart as an Azure Kubernetes application offer

    [Marketplace listing — forward-looking]

    Azure Marketplace Kubernetes application offers (also called Container offers with an AKS deployment plan) require a packaging bundle on top of the raw Helm chart. The bundle is a .zip archive you upload via Partner Center:

    | Bundle artifact | Purpose | |-----------------|---------| | Chart.yaml | Standard Helm chart descriptor — already present in deploy/helm/buttrbase-backend-rust/. | | values.yaml + overlay files | The topology values files from the chart (values-single-tenant-byoc.yaml drives the customer install plan). | | createUiDefinition.json | Defines the Azure Portal configuration form the customer fills in: cluster selector, Postgres connection string, storage account, tenant slug, region. Maps form fields to Helm values. | | mainTemplate.json | An ARM template (or Bicep transpiled to ARM) that wraps the Kubernetes application object. Azure's deployment engine processes this to track the install lifecycle in the customer's subscription. |

    The chart at deploy/helm/buttrbase-backend-rust/ slots in as-is. The customer-facing configuration form (createUiDefinition.json) will inject their inputs — Postgres URL, storage account name, tenant slug, region — as values matching the shape of values-single-tenant-byoc.yaml. The secrets (database-url, secret-key, encryption-key) are passed through secure fields in the form and materialized as a Kubernetes Secret in the customer's cluster — the same three keys the chart reads.

    Canonical authoring references for createUiDefinition.json and the ARM wrapper are in Microsoft's documentation for creating a Kubernetes application offer.

    6. Submit the listing

    [Marketplace listing — forward-looking]

    Submission happens entirely in the Partner Center web UI at partner.microsoft.com. The steps are:

    1. In Partner Center, go to Marketplace offers* and create a new **Azure Container** offer (choose the *Kubernetes application plan type for AKS). 2. Fill in the offer metadata: name, description, categories, support contacts, and legal terms. 3. Configure pricing: Azure Marketplace supports free, flat-rate, per-core, and usage-based billing models. Choose the model that matches how ButtrBase sells the BYOC tier. 4. Under the plan's Technical configuration, upload the chart bundle (the .zip from step 5) and provide the ACR image URI for the application container. 5. Supply the createUiDefinition.json so the Marketplace portal can render the customer configuration form. 6. Trigger Partner Center's automated validation. The validator checks that the bundle is well-formed, the images are pullable from ACR, and the Kubernetes application installs successfully against a test cluster. 7. Submit for Microsoft's review. First-submission review timelines vary; plan for several business days.

    Do not attempt to drive these steps from the az CLI — the Partner Center commercial-marketplace workflow is portal-native. There is no stable az marketplace offer ... subcommand surface for publisher-side operations.

    7. Customer install experience

    Once the listing is live, a customer's path is:

    1. Find ButtrBase* in the Azure Marketplace and click *Get It Now. 2. Select the Azure subscription and resource group to deploy into (their own subscription). 3. Fill in the configuration form from createUiDefinition.json: AKS cluster, Postgres connection string (typically Azure Database for PostgreSQL private endpoint), storage account, tenant slug, region. 4. Click Create. Azure's deployment engine applies the ARM wrapper and invokes helm upgrade --install with the customer-supplied values against their AKS cluster. 5. The Portal shows the deployment as Succeeded once the Kubernetes application reports healthy.

    The customer never sees a Helm command. Underneath, Azure is running the same chart as 07, with topology values matching values-single-tenant-byoc.yaml.

    8. Direct AKS install (without the Marketplace UI)

    For operators who need to deploy into a customer's AKS cluster directly — without going through the Marketplace listing — the flow is the same as tutorial 07, but targeted at the customer's cluster. Fetch AKS credentials:

    az aks get-credentials \
      --resource-group CUSTOMER_RESOURCE_GROUP \
      --name CUSTOMER_AKS_CLUSTER \
      --overwrite-existing
    

    Then create the namespace, the Secret, and run the Helm install exactly as in tutorial 07:

    kubectl create namespace buttrbase

    kubectl -n buttrbase create secret generic buttrbase-backend-rust \ --from-literal=database-url='postgres://buttrbase:…@customer-pg.postgres.database.azure.com:5432/buttrbase' \ --from-literal=secret-key="$(openssl rand -hex 32)" \ --from-literal=encryption-key="$(openssl rand -hex 32)"

    helm upgrade --install buttrbase ./deploy/helm/buttrbase-backend-rust \ -n buttrbase \ -f ./deploy/helm/buttrbase-backend-rust/values-single-tenant-byoc.yaml \ --set app.image.tag=0.1.0

    This is the direct operator path — useful for BYOC deployments while the Marketplace listing is still in review, or for customers who prefer to drive the install themselves.

    9. Verify the install

    Verification is identical to tutorial 07 — the chart is the same chart. Once the deployment is running (whether installed via the Marketplace UI or directly), check readiness and probe the health endpoint:

    kubectl -n buttrbase rollout status deploy/buttrbase --timeout=120s
    kubectl -n buttrbase port-forward svc/buttrbase 4300:4300 &
    curl -fsS http://localhost:4300/health && echo "  ✓ healthy"
    

    Confirm the topology round-tripped:

    kubectl -n buttrbase exec deploy/buttrbase -- printenv BUTTRBASE_RUST_DEPLOYMENT_MODE
    

    → single-tenant-byoc

    If the pod is not ready, read the logs — the two dominant first-install failures are a database-url the pod's network cannot reach (the AKS node can't hit the Postgres private endpoint) and an encryption-key that is not 32 bytes hex. Both appear in the first ten log lines.

    kubectl -n buttrbase logs deploy/buttrbase --tail=50
    

    Done

    You have the full Azure Marketplace packaging path: the image is in ACR, the chart is ready for the Kubernetes application bundle, and the customer-facing install flow maps cleanly to single-tenant-byoc. From here:

  • Back to the substrate — if anything in the install behaves unexpectedly, 07-deploy-with-helm.md is the ground truth for chart behavior, values semantics, and secret layout.
  • GCP Marketplace — 08-deploy-gcp-marketplace.md covers the same chart packaged as a GKE Marketplace Kubernetes app.
  • AWS Marketplace — tutorial 09 covers the same chart packaged as an EKS Marketplace listing.