Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Assess and migrate workloads from AWS, GCP, or other clouds to Azure services.
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