Skip to content

Claude Code Cloud Sessions

Run development and deployments from a Claude Code cloud session the same way as from a workstation. Local development is unchanged: without the optional azd remote-state setting below, azd keeps .azure/ on your machine.

 GitHub repo ──clone──► Workstation (.azure local or remote)  ──► ./deploy.sh ─┐
      │                                                                         ▼
      └──clone──► Cloud session (fresh VM each session)       ──► ./deploy.sh ─► Azure env + Entra
                    │  setup script (cached): az, azd, python
                    │  SessionStart hook: tools match repo pins, azd remote state
                    │  you: approve two device-code sign-ins
                    ▼
            azd remote state (Azure Blob, Entra-only) ◄── workstation syncs the same env

Cloud VMs keep nothing between sessions except the setup script's cached image, so the azd environment (including the provisioner client secret and management API key) lives in an Azure Storage container that azd syncs after sign-in. Nothing secret goes into the cloud environment's settings.

One-time: azd remote state

Use a storage account outside the deployment's resource group so scripts/teardown.sh can never delete it. Disable shared keys and grant yourself Storage Blob Data Contributor; enable blob versioning and soft delete, since the state includes secrets and is hard to rebuild.

az group create -n <state-rg> -l <region>
az storage account create -n <stateaccount> -g <state-rg> --sku Standard_LRS \
  --allow-shared-key-access false --allow-blob-public-access false --min-tls-version TLS1_2
az storage account blob-service-properties update -n <stateaccount> -g <state-rg> \
  --enable-versioning true --enable-delete-retention true --delete-retention-days 30
az role assignment create --assignee "$(az ad signed-in-user show --query id -o tsv)" \
  --role "Storage Blob Data Contributor" \
  --scope "$(az storage account show -n <stateaccount> -g <state-rg> --query id -o tsv)"
az storage container create --account-name <stateaccount> -n identity-spiffe --auth-mode login

Point your workstation's azd at it (user-level config, never azure.yaml, which would break azd for everyone else), then re-save any value to upload:

AZD_STATE_ACCOUNT=<stateaccount> AZD_STATE_CONTAINER=identity-spiffe scripts/cloud-session.sh configure
azd env set AZURE_LOCATION "$(azd env get-value AZURE_LOCATION)"

One-time: cloud environment settings

Field Value
Network access Custom, with Also include default list of common package managers checked, plus the domains below
Network secrets None (they inject HTTP headers only and cannot carry Azure credentials)
Setup script The full contents of scripts/cloud-setup.sh
Environment variables See below

Allowed domains (in addition to the defaults):

management.azure.com
graph.microsoft.com
login.microsoftonline.com
*.blob.core.windows.net
*.azurecr.io
*.azurecontainerapps.io
downloads.bicep.azure.com
aka.ms

Environment variables (.env format; none are secrets):

AZURE_TENANT_ID=<tenant-id>
AZURE_SUBSCRIPTION_ID=<subscription-id>
AZURE_ENV_NAME=<azd-env-name>
AZD_STATE_ACCOUNT=<stateaccount>
AZD_STATE_CONTAINER=identity-spiffe
DEPLOY_PYTHON=/usr/bin/python3
BASH_DEFAULT_TIMEOUT_MS=2700000
AZURE_CORE_COLLECT_TELEMETRY=false
AZURE_DEV_COLLECT_TELEMETRY=no

BASH_DEFAULT_TIMEOUT_MS (45 minutes) lets a full deploy.sh run without the default command timeout moving it to the background early.

Keeping the setup script in sync

scripts/cloud-setup.sh is the source of truth. CI runs it on Ubuntu 24.04 (Cloud session setup job). The repo-tracked SessionStart hook in .claude/settings.json runs scripts/cloud-session.sh hook at the start of every cloud session (it is a no-op elsewhere): if the installed az/azd do not match the repo pins it reinstalls them from the repo copy and asks you to re-paste the setup script, which also refreshes the cached image. A stale pasted copy is slower, never wrong.

Every session

  1. Sign in with device codes. Claude runs each command and shows you the code; approve it at https://microsoft.com/devicelogin:
az login --use-device-code --tenant "$AZURE_TENANT_ID"
azd auth login --use-device-code --tenant-id "$AZURE_TENANT_ID"
  1. Load the shared environment and confirm:
scripts/cloud-session.sh env
scripts/cloud-session.sh status
  1. Deploy exactly as on a workstation (./deploy.sh --skip-provision, etc.). The usual rules in AGENTS.md apply.

Troubleshooting

  • Management API demands MFA claims: re-run az login --use-device-code with the --claims-challenge value from the error.
  • azd env select cannot find the environment: check AZD_STATE_*, then scripts/cloud-session.sh configure; you need Storage Blob Data Contributor on the state account.
  • A long deploy stopped when the session went idle: cloud VMs can pause when idle. Keep the session active during deploys, or run long deploys from a workstation.