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/fargate-deployment-guide.md
1# Deployment: Fargate to Container Apps23## Prerequisites45Azure CLI 2.53+ with `containerapp` extension, AWS CLI v2, Docker, ACR, Key Vault, Log Analytics67## Phase 1: Container Registry Migration89```bash10set -euo pipefail11aws ecr get-login-password --region "$AWS_REGION" | \12docker login --username AWS --password-stdin "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"13az acr login --name "$ACR_NAME"14docker pull "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${IMAGE}"15docker tag "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${IMAGE}" "${ACR_NAME}.azurecr.io/${IMAGE}"16docker push "${ACR_NAME}.azurecr.io/${IMAGE}"17```1819```powershell20$ErrorActionPreference = 'Stop'21$ecrPassword = aws ecr get-login-password --region $env:AWS_REGION22$ecrPassword | docker login --username AWS --password-stdin "$($env:AWS_ACCOUNT_ID).dkr.ecr.$($env:AWS_REGION).amazonaws.com"23az acr login --name $env:ACR_NAME24docker pull "$($env:AWS_ACCOUNT_ID).dkr.ecr.$($env:AWS_REGION).amazonaws.com/$($env:IMAGE)"25docker tag "$($env:AWS_ACCOUNT_ID).dkr.ecr.$($env:AWS_REGION).amazonaws.com/$($env:IMAGE)" "$($env:ACR_NAME).azurecr.io/$($env:IMAGE)"26docker push "$($env:ACR_NAME).azurecr.io/$($env:IMAGE)"27```2829## Phase 2: Infrastructure3031> Choose ONE path: basic (without VNet) OR VNet-integrated.3233### Basic (no VNet)3435```bash36set -euo pipefail37az group create --name "$RG" --location "$LOCATION"38az monitor log-analytics workspace create -g "$RG" -n "${RG}-logs" -l "$LOCATION"39LOG_ID=$(az monitor log-analytics workspace show -g "$RG" -n "${RG}-logs" --query customerId -o tsv)40# Keyless (recommended): avoids handling the shared key entirely41az containerapp env create -n "${RG}-env" -g "$RG" -l "$LOCATION" \42--logs-destination azure-monitor --logs-workspace-id "$LOG_ID"43# Fallback: use shared key if azure-monitor destination is not available44# LOG_KEY=$(az monitor log-analytics workspace get-shared-keys -g "$RG" -n "${RG}-logs" --query primarySharedKey -o tsv)45# az containerapp env create -n "${RG}-env" -g "$RG" -l "$LOCATION" \46# --logs-workspace-id "$LOG_ID" --logs-workspace-key "$LOG_KEY"47```4849```powershell50$ErrorActionPreference = 'Stop'51az group create --name $env:RG --location $env:LOCATION52az monitor log-analytics workspace create -g $env:RG -n "$($env:RG)-logs" -l $env:LOCATION53$logId = az monitor log-analytics workspace show -g $env:RG -n "$($env:RG)-logs" --query customerId -o tsv54# Keyless (recommended): avoids handling the shared key entirely55az containerapp env create -n "$($env:RG)-env" -g $env:RG -l $env:LOCATION `56--logs-destination azure-monitor --logs-workspace-id $logId57# Fallback: use shared key if azure-monitor destination is not available58# $logKey = az monitor log-analytics workspace get-shared-keys -g $env:RG -n "$($env:RG)-logs" --query primarySharedKey -o tsv59# az containerapp env create -n "$($env:RG)-env" -g $env:RG -l $env:LOCATION `60# --logs-workspace-id $logId --logs-workspace-key $logKey61```6263### VNet-Integrated6465```bash66set -euo pipefail67az group create --name "$RG" --location "$LOCATION"68az monitor log-analytics workspace create -g "$RG" -n "${RG}-logs" -l "$LOCATION"69LOG_ID=$(az monitor log-analytics workspace show -g "$RG" -n "${RG}-logs" --query customerId -o tsv)70az network vnet create -g "$RG" -n "${RG}-vnet" \71--address-prefix 10.0.0.0/16 --subnet-name aca-subnet --subnet-prefix 10.0.0.0/2372SUBNET_ID=$(az network vnet subnet show -g "$RG" --vnet-name "${RG}-vnet" -n aca-subnet --query id -o tsv)73az containerapp env create -n "${RG}-env" -g "$RG" -l "$LOCATION" \74--logs-destination azure-monitor --logs-workspace-id "$LOG_ID" \75--infrastructure-subnet-resource-id "$SUBNET_ID"76```7778```powershell79$ErrorActionPreference = 'Stop'80az group create --name $env:RG --location $env:LOCATION81az monitor log-analytics workspace create -g $env:RG -n "$($env:RG)-logs" -l $env:LOCATION82$logId = az monitor log-analytics workspace show -g $env:RG -n "$($env:RG)-logs" --query customerId -o tsv83az network vnet create -g $env:RG -n "$($env:RG)-vnet" `84--address-prefix 10.0.0.0/16 --subnet-name aca-subnet --subnet-prefix 10.0.0.0/2385$subnet = az network vnet subnet show -g $env:RG --vnet-name "$($env:RG)-vnet" -n aca-subnet | ConvertFrom-Json86az containerapp env create -n "$($env:RG)-env" -g $env:RG -l $env:LOCATION `87--logs-destination azure-monitor --logs-workspace-id $logId `88--infrastructure-subnet-resource-id $subnet.id89```9091## Phase 3: Secrets & Identity9293```bash94set -euo pipefail95az keyvault create --name "$KEY_VAULT" -g "$RG" -l "$LOCATION" \96--enable-rbac-authorization true97IDENTITY_ID=$(az identity create -n "${RG}-id" -g "$RG" -l "$LOCATION" --query id -o tsv)98PRINCIPAL_ID=$(az identity show --ids "$IDENTITY_ID" --query principalId -o tsv)99100# Grant Key Vault access — use RBAC (recommended) or access policies101# Option A: RBAC (enabled on the vault created above)102KV_ID=$(az keyvault show --name "$KEY_VAULT" --query id -o tsv)103az role assignment create --assignee "$PRINCIPAL_ID" \104--role "Key Vault Secrets User" --scope "$KV_ID"105# Option B: Access policies (if vault uses access policy mode)106# az keyvault set-policy --name "$KEY_VAULT" --object-id "$PRINCIPAL_ID" --secret-permissions get list107108# Migrate secrets more safely: avoid passing the secret as a CLI argument.109# Use a locked-down temporary file, import with --file, and remove it immediately.110# Do not run this in shared, monitored, or recorded environments.111umask 077112secret_file="$(mktemp)"113trap 'rm -f "$secret_file"' EXIT114aws secretsmanager get-secret-value --secret-id <secret-id> --region <region> \115--query SecretString --output text > "$secret_file"116az keyvault secret set --vault-name "$KEY_VAULT" --name <secret-name> \117--file "$secret_file"118rm -f "$secret_file"119trap - EXIT120121# ACR pull access122ACR_ID=$(az acr show --name "$ACR_NAME" --query id -o tsv)123az role assignment create --assignee "$PRINCIPAL_ID" --role AcrPull --scope "$ACR_ID"124```125126```powershell127$ErrorActionPreference = 'Stop'128az keyvault create --name $env:KEY_VAULT -g $env:RG -l $env:LOCATION --enable-rbac-authorization true129$identityId = az identity create -n "$($env:RG)-id" -g $env:RG -l $env:LOCATION --query id -o tsv130$principalId = az identity show --ids $identityId --query principalId -o tsv131132# Grant Key Vault access — use RBAC (recommended) or access policies133# Option A: RBAC (enabled on the vault created above)134$kvId = az keyvault show --name $env:KEY_VAULT --query id -o tsv135az role assignment create --assignee $principalId `136--role "Key Vault Secrets User" --scope $kvId137# Option B: Access policies (if vault uses access policy mode)138# az keyvault set-policy --name $env:KEY_VAULT --object-id $principalId --secret-permissions get list139140# Migrate secrets more safely: use a temp file instead of passing as CLI argument.141# Do not run this in shared, monitored, or recorded environments.142$secretFile = [System.IO.Path]::GetTempFileName()143try {144aws secretsmanager get-secret-value --secret-id <secret-id> --region <region> `145--query SecretString --output text | Set-Content -Path $secretFile -NoNewline146az keyvault secret set --vault-name $env:KEY_VAULT --name <secret-name> `147--file $secretFile148} finally {149Remove-Item -Path $secretFile -Force -ErrorAction SilentlyContinue150}151152# ACR pull access153$acrId = az acr show --name $env:ACR_NAME --query id -o tsv154az role assignment create --assignee $principalId --role AcrPull --scope $acrId155```156157## Phase 4: Deploy158159```bash160set -euo pipefail161SECRET_URI=$(az keyvault secret show --vault-name "$KEY_VAULT" --name db-password --query id -o tsv)162az containerapp create --name <app-name> -g "$RG" --environment "${RG}-env" \163--image "${ACR_NAME}.azurecr.io/<image>:<tag>" --target-port 8080 --ingress external \164--cpu 0.5 --memory 1Gi --min-replicas 1 --max-replicas 10 \165--user-assigned "$IDENTITY_ID" --registry-identity "$IDENTITY_ID" \166--registry-server "${ACR_NAME}.azurecr.io" \167--secrets db-pass=keyvaultref:"${SECRET_URI}",identityref:"${IDENTITY_ID}" \168--env-vars ENV=production DB_PASSWORD=secretref:db-pass169```170171```powershell172$ErrorActionPreference = 'Stop'173$secretUri = az keyvault secret show --vault-name $env:KEY_VAULT --name db-password --query id -o tsv174az containerapp create --name <app-name> -g $env:RG --environment "$($env:RG)-env" `175--image "$($env:ACR_NAME).azurecr.io/<image>:<tag>" --target-port 8080 --ingress external `176--cpu 0.5 --memory 1Gi --min-replicas 1 --max-replicas 10 `177--user-assigned $identityId --registry-identity $identityId `178--registry-server "$($env:ACR_NAME).azurecr.io" `179--secrets "db-pass=keyvaultref:$($secretUri),identityref:$($identityId)" `180--env-vars ENV=production DB_PASSWORD=secretref:db-pass181```182183### Configuration Mapping184185| ECS Task Definition | Container Apps CLI |186|---------------------|--------------------|187| `cpu: "512"` (0.5 vCPU) | `--cpu 0.5` |188| `memory: "1024"` (1 GB) | `--memory 1Gi` |189| `containerPort: 8080` | `--target-port 8080` |190| `desiredCount: 2` | `--min-replicas 2` |191| `secrets` (Secrets Manager ARN) | `--secrets name=keyvaultref:URI,identityref:ID` |192| `environment` (env vars) | `--env-vars KEY=value` |193194## Phase 5: Validate195196```bash197set -euo pipefail198FQDN=$(az containerapp show --name <app-name> -g "$RG" --query properties.configuration.ingress.fqdn -o tsv)199curl -f -I "https://$FQDN/health" || { echo "Health check failed"; exit 1; }200az containerapp logs show --name <app-name> -g "$RG" --tail 100201```202203```powershell204$ErrorActionPreference = 'Stop'205$fqdn = az containerapp show --name <app-name> -g $env:RG --query properties.configuration.ingress.fqdn -o tsv206Invoke-WebRequest -Uri "https://$fqdn/health" -Method Head207az containerapp logs show --name <app-name> -g $env:RG --tail 100208```209210## Troubleshooting211212| Issue | Solution |213|-------|----------|214| Image pull fails | Verify ACR role: `az role assignment list --assignee $(az identity show --ids <identity-resource-id> --query principalId -o tsv) --scope $(az acr show -n <acr-name> --query id -o tsv)` |215| App won't start | Check logs: `az containerapp logs show --name <app-name> -g <resource-group> --tail 100` |216| Secret not accessible | Verify RBAC: `az role assignment list --assignee $(az identity show --ids <identity-resource-id> --query principalId -o tsv) --scope $(az keyvault show -n <vault-name> --query id -o tsv)` |217