The Atlas MikeOSS.Azure's docs, bound to the code — and to the migration that built it
108 documents
marketplace/README.md

Describes the Partner Center managed-application bundle and how it is built. Three files ship: the generated mainTemplate.json (never hand-edited; built from infra/main.bicep), the hand-written createUiDefinition.json (Portal wizard) and viewDefinition.json (managed-RG blade). It documents the image-distribution model — the customer deployment can't reach the publisher's private ACR, so images are pulled anonymously from a public publisher registry acrmikeoss.azurecr.io, flipping two bicep params (imagePullAuth:'anonymous' so registries[] stays empty and the AcrPull grant is skipped, createAcr:false) while self-host/dev keep managed-identity + a private ACR over the same modules. Includes the one-time publisher-ACR setup (Standard SKU + az acr update --anonymous-pull-enabled) and per-release image push. Note: this README is flagged stale in ARCHITECTURE-ANALYSIS §11 — it describes AI-key wizard fields the current createUiDefinition.json does not contain. Read to understand the marketplace bundle contents and the anonymous public-ACR image-pull design before touching the package.

Mike AI — Azure Marketplace package

This directory contains the artefacts uploaded to Partner Center to publish Mike as an Azure Marketplace Managed Application. The customer launches the offer from the Azure Portal, fills out the wizard, and the full stack is provisioned in their own subscription with no manual steps after the wizard.

Files in the bundle

File Source Purpose
mainTemplate.json generated from infra/main.bicep ARM template the Portal deploys
createUiDefinition.json hand-written Portal wizard (Basics → Database → AI providers → Networking → Review)
viewDefinition.json hand-written Custom managed-resource-group blade with backend FQDN, KV name, etc.

mainTemplate.json is generated — do not edit it by hand. Run scripts/package-marketplace.sh to rebuild it from infra/main.bicep and produce a mike-marketplace-<version>.zip ready to upload to Partner Center.

Building the package

# bash (Linux / macOS / Git-Bash) — needs python on PATH
./scripts/package-marketplace.sh                # uses git short SHA as version
./scripts/package-marketplace.sh --version v1.2.0
./scripts/package-marketplace.sh --out dist/    # change output directory
# PowerShell 7+ (Windows / cross-platform) — no python required
./scripts/package-marketplace.ps1
./scripts/package-marketplace.ps1 -Version v1.2.0
./scripts/package-marketplace.ps1 -OutDir dist

Outputs:

marketplace/mainTemplate.json           # generated, gitignored
dist/mike-marketplace-<version>.zip     # upload this to Partner Center

The script:

  1. Verifies az CLI is on PATH.
  2. Runs az bicep build --file infra/main.bicep --outfile marketplace/mainTemplate.json.
  3. Validates createUiDefinition.json and viewDefinition.json parse as JSON.
  4. Zips the three required files into a flat archive (no nested folders — Partner Center rejects them).

Wizard → bicep parameter mapping

The wizard outputs in createUiDefinition.json map 1:1 to parameters in infra/main.bicep. The three AI-key fields (anthropicApiKey, openaiApiKey, openaiBaseUrl) are not consumed by the bicep yet — they are surfaced in the UI so the future wrapper template (issue 016, deliverable 4) can write them to Key Vault via a Microsoft.Resources/deploymentScripts resource.

Image distribution

The marketplace deployment runs in the customer's subscription, so it cannot pull from the publisher's private ACR. The chosen approach is direct anonymous pull from a public publisher ACR: a registry called acrmikeoss.azurecr.io is created in the publisher subscription with anonymous pull enabled, and customer Container Apps reference its images (acrmikeoss.azurecr.io/backend:<version>, acrmikeoss.azurecr.io/postgrest:v12.2.3) directly at startup. No customer ACR is provisioned, no az acr import step runs at deploy time, and no credentials are embedded in customer subscriptions.

The marketplace flow flips two bicep parameters away from their self-hosted defaults via createUiDefinition.json:

  • imagePullAuth: 'anonymous' — Container Apps' registries[] is left empty (so the platform pulls anonymously); the managed-identity module skips the AcrPull role assignment.
  • createAcr: false — no customer-side ACR.

Self-hosted/dev deployments (deploy.ps1) keep the defaults (imagePullAuth='managed-identity', private ACR with MI auth). Both code paths share the same bicep modules.

See docs/issues/azure-migration/016-marketplace-listing.md for the full reasoning, alternatives that were rejected (mirror via deploymentScript, scope-map tokens, public Docker Hub), and the open verification item against certification policy 300.4.7.

Publisher ACR — one-time setup

# Run once, in the publisher's own subscription. NOT the dev subscription.
# Anonymous pull requires Standard or Premium SKU and is enabled via a
# separate `az acr update` call (the flag does not exist on `az acr create`).
az group create --name rg-mike-publisher --location westeurope
az acr create \
  --resource-group rg-mike-publisher \
  --name acrmikeoss \
  --sku Standard
az acr update \
  --name acrmikeoss \
  --anonymous-pull-enabled true

Per-release: push images to the publisher ACR

Both images live in acrmikeoss under tags that match the marketplace package version. Run before package-marketplace.{ps1,sh}:

VERSION=v1.2.0   # match the --version you'll pass to package-marketplace

# Backend — built fresh each release from this repo
az acr build --registry acrmikeoss --image backend:${VERSION} ./backend

# PostgREST — mirror once per upstream version bump (idempotent with --force)
az acr import \
  --name acrmikeoss \
  --source docker.io/postgrest/postgrest:v12.2.3 \
  --image postgrest:v12.2.3 \
  --force

scripts/release-images.ps1 (and .sh) wraps both calls into a single command — see scripts/release-images.ps1 -h.

Local validation

Before uploading, paste createUiDefinition.json into the Portal sandbox to preview the wizard:

https://portal.azure.com/?feature.customportal=false#blade/Microsoft_Azure_CreateUIDef/SandboxBlade

Out of scope here

  • Partner Center upload (manual today; automation tracked in issue 016 §5)
  • Pricing / billing model — Mike v1 ships free / BYOL only