Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
GitHub Copilot for Azure plugin providing Azure service management and development assistance inside Claude Code and IDEs.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/services/container-apps/cloudrun-deployment-guide.md
1# Deployment: Cloud Run to Container Apps23## Prerequisites45Azure CLI 2.53+, gcloud CLI, Docker, ACR, Key Vault, Log Analytics67## Phase 1: Image Migration89### Bash1011```bash12set -euo pipefail13GCP_PROJECT="${GCP_PROJECT:-<project>}"14GCP_REGION="${GCP_REGION:-<region>}"15ACR_NAME="${ACR_NAME:-<acr>}"1617gcloud auth configure-docker "${GCP_REGION}-docker.pkg.dev"18az acr login --name "$ACR_NAME"19for img in "app:v1" "worker:v1"; do20docker pull "${GCP_REGION}-docker.pkg.dev/${GCP_PROJECT}/<repo>/$img"21docker tag "${GCP_REGION}-docker.pkg.dev/${GCP_PROJECT}/<repo>/$img" "${ACR_NAME}.azurecr.io/$img"22docker push "${ACR_NAME}.azurecr.io/$img"23done24```2526### PowerShell2728```powershell29$GCP_PROJECT = if ($env:GCP_PROJECT) { $env:GCP_PROJECT } else { "<project>" }30$GCP_REGION = if ($env:GCP_REGION) { $env:GCP_REGION } else { "<region>" }31$ACR_NAME = if ($env:ACR_NAME) { $env:ACR_NAME } else { "<acr>" }3233gcloud auth configure-docker "${GCP_REGION}-docker.pkg.dev"34az acr login --name $ACR_NAME35@("app:v1", "worker:v1") | ForEach-Object {36docker pull "${GCP_REGION}-docker.pkg.dev/${GCP_PROJECT}/<repo>/$_"37docker tag "${GCP_REGION}-docker.pkg.dev/${GCP_PROJECT}/<repo>/$_" "${ACR_NAME}.azurecr.io/$_"38docker push "${ACR_NAME}.azurecr.io/$_"39}40```4142## Phase 2: Infrastructure4344> Choose ONE path: basic (without VNet) OR VNet-integrated.4546### Basic (no VNet)4748#### Bash4950```bash51set -euo pipefail52az group create --name "$RG" --location "$LOCATION"53az monitor log-analytics workspace create -g "$RG" -n "${RG}-logs" -l "$LOCATION"54LOG_ID=$(az monitor log-analytics workspace show -g "$RG" -n "${RG}-logs" --query customerId -o tsv)55LOG_KEY=$(az monitor log-analytics workspace get-shared-keys -g "$RG" -n "${RG}-logs" --query primarySharedKey -o tsv)56az containerapp env create -n "${RG}-env" -g "$RG" -l "$LOCATION" \57--logs-workspace-id "$LOG_ID" --logs-workspace-key "$LOG_KEY"58```5960#### PowerShell6162```powershell63az group create --name $RG --location $LOCATION64az monitor log-analytics workspace create -g $RG -n "${RG}-logs" -l $LOCATION65$workspace = az monitor log-analytics workspace show -g $RG -n "${RG}-logs" | ConvertFrom-Json66$keys = az monitor log-analytics workspace get-shared-keys -g $RG -n "${RG}-logs" | ConvertFrom-Json67az containerapp env create -n "${RG}-env" -g $RG -l $LOCATION `68--logs-workspace-id $workspace.customerId --logs-workspace-key $keys.primarySharedKey69```7071### VNet-Integrated7273#### Bash7475```bash76set -euo pipefail77az network vnet create -g "$RG" -n "${RG}-vnet" \78--address-prefix 10.0.0.0/16 --subnet-name aca-subnet --subnet-prefix 10.0.0.0/2379SUBNET_ID=$(az network vnet subnet show -g "$RG" --vnet-name "${RG}-vnet" -n aca-subnet --query id -o tsv)80az containerapp env create -n "${RG}-env" -g "$RG" -l "$LOCATION" \81--logs-workspace-id "$LOG_ID" --logs-workspace-key "$LOG_KEY" \82--infrastructure-subnet-resource-id "$SUBNET_ID"83```8485#### PowerShell8687```powershell88az network vnet create -g $RG -n "${RG}-vnet" `89--address-prefix 10.0.0.0/16 --subnet-name aca-subnet --subnet-prefix 10.0.0.0/2390$subnet = az network vnet subnet show -g $RG --vnet-name "${RG}-vnet" -n aca-subnet | ConvertFrom-Json91az containerapp env create -n "${RG}-env" -g $RG -l $LOCATION `92--logs-workspace-id $workspace.customerId --logs-workspace-key $keys.primarySharedKey `93--infrastructure-subnet-resource-id $subnet.id94```9596## Phase 3: Secrets & Identity9798### Bash99100```bash101set -euo pipefail102az keyvault create --name "$KEY_VAULT" -g "$RG" -l "$LOCATION"103IDENTITY_ID=$(az identity create -n "${RG}-id" -g "$RG" -l "$LOCATION" --query id -o tsv)104PRINCIPAL_ID=$(az identity show --ids "$IDENTITY_ID" --query principalId -o tsv)105106# Grant Key Vault access — use RBAC (recommended) or access policies107# Option A: RBAC (default for new vaults)108KV_ID=$(az keyvault show --name "$KEY_VAULT" --query id -o tsv)109az role assignment create --assignee "$PRINCIPAL_ID" \110--role "Key Vault Secrets User" --scope "$KV_ID"111# Option B: Access policies (if vault uses access-policy mode)112# az keyvault set-policy --name "$KEY_VAULT" --object-id "$PRINCIPAL_ID" --secret-permissions get list113114# Migrate secrets without writing them to disk115az keyvault secret set --vault-name "$KEY_VAULT" --name <secret-name> \116--value "$(gcloud secrets versions access latest --secret=<secret-id> --project="$GCP_PROJECT")"117118# ACR pull access119ACR_ID=$(az acr show --name "$ACR_NAME" --query id -o tsv)120az role assignment create --assignee "$PRINCIPAL_ID" --role AcrPull --scope "$ACR_ID"121```122123### PowerShell124125```powershell126az keyvault create --name $KEY_VAULT -g $RG -l $LOCATION127$identity = az identity create -n "${RG}-id" -g $RG -l $LOCATION | ConvertFrom-Json128$principalId = (az identity show --ids $identity.id | ConvertFrom-Json).principalId129130# Grant Key Vault access — RBAC (recommended)131$kvId = (az keyvault show --name $KEY_VAULT | ConvertFrom-Json).id132az role assignment create --assignee $principalId `133--role "Key Vault Secrets User" --scope $kvId134135# Migrate secrets without writing them to disk136$secretValue = gcloud secrets versions access latest --secret=<secret-id> --project=$GCP_PROJECT137az keyvault secret set --vault-name $KEY_VAULT --name <secret-name> --value $secretValue138Remove-Variable secretValue139140# ACR pull access141$acrId = (az acr show --name $ACR_NAME | ConvertFrom-Json).id142az role assignment create --assignee $principalId --role AcrPull --scope $acrId143```144145## Phase 4: Deploy Container App146147### Bash148149```bash150set -euo pipefail151SECRET_URI=$(az keyvault secret show --vault-name "$KEY_VAULT" --name db-pw --query id -o tsv)152az containerapp create \153--name <app-name> -g "$RG" --environment "${RG}-env" \154--image "${ACR_NAME}.azurecr.io/app:v1" --target-port 8080 --ingress external \155--cpu 1.0 --memory 1Gi --min-replicas 0 --max-replicas 10 \156--user-assigned "$IDENTITY_ID" --registry-identity "$IDENTITY_ID" \157--registry-server "${ACR_NAME}.azurecr.io" \158--secrets db-pw=keyvaultref:"${SECRET_URI}",identityref:"${IDENTITY_ID}" \159--env-vars ENV=prod DB_PASSWORD=secretref:db-pw \160--scale-rule-name http --scale-rule-type http --scale-rule-http-concurrency 80161```162163### PowerShell164165```powershell166$secret = az keyvault secret show --vault-name $KEY_VAULT --name db-pw | ConvertFrom-Json167az containerapp create `168--name <app-name> -g $RG --environment "${RG}-env" `169--image "${ACR_NAME}.azurecr.io/app:v1" --target-port 8080 --ingress external `170--cpu 1.0 --memory 1Gi --min-replicas 0 --max-replicas 10 `171--user-assigned $identity.id --registry-identity $identity.id `172--registry-server "${ACR_NAME}.azurecr.io" `173--secrets "db-pw=keyvaultref:$($secret.id),identityref:$($identity.id)" `174--env-vars "ENV=prod" "DB_PASSWORD=secretref:db-pw" `175--scale-rule-name http --scale-rule-type http --scale-rule-http-concurrency 80176```177178### Configuration Mapping179180| Cloud Run | Container Apps |181|-----------|----------------|182| `--min-instances 0` | `--min-replicas 0` |183| `--max-instances 10` | `--max-replicas 10` |184| `--concurrency 80` | `--scale-rule-http-concurrency 80` |185| `--cpu 1` | `--cpu 1.0` |186| `--memory 512Mi` | `--memory 1Gi` |187188## Phase 5: Validation189190### Bash191192```bash193FQDN=$(az containerapp show --name <app-name> -g "$RG" --query properties.configuration.ingress.fqdn -o tsv)194curl -I "https://$FQDN/health"195az containerapp logs show --name <app-name> -g "$RG" --tail 100196```197198### PowerShell199200```powershell201$app = az containerapp show --name <app-name> -g $RG | ConvertFrom-Json202Invoke-WebRequest -Uri "https://$($app.properties.configuration.ingress.fqdn)/health"203az containerapp logs show --name <app-name> -g $RG --tail 100204```205206## Troubleshooting207208| Issue | Solution |209|-------|----------|210| Image pull fails | Verify ACR role: `az role assignment list --assignee $PRINCIPAL_ID --scope $ACR_ID -o table` |211| App won't start | Check logs: `az containerapp logs show --name <app> -g $RG --tail 100` |212| Secret not accessible | Verify RBAC: `az role assignment list --assignee $PRINCIPAL_ID --scope $KV_ID -o table` |213| Scaling not working | Check config: `az containerapp show --name <app> --query properties.template.scale` |214