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¶
- 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"
- Load the shared environment and confirm:
scripts/cloud-session.sh env
scripts/cloud-session.sh status
- Deploy exactly as on a workstation (
./deploy.sh --skip-provision, etc.). The usual rules inAGENTS.mdapply.
Troubleshooting¶
- Management API demands MFA claims: re-run
az login --use-device-codewith the--claims-challengevalue from the error. azd env selectcannot find the environment: checkAZD_STATE_*, thenscripts/cloud-session.sh configure; you needStorage Blob Data Contributoron 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.