armandoblanco/tutorial-copilot-azure-containerapp-auth
Tutorial: Deploy containerized web apps to Azure Container Apps with Microsoft Entra ID authentication using GitHub Copilot Agent Mode
Deploy Web Apps to Azure Container Apps with Entra ID Authentication
A step-by-step tutorial for deploying containerized web applications to Azure using GitHub Copilot in Agent Mode.
๐ Overview
This tutorial demonstrates how to leverage GitHub Copilot in Agent Mode to dramatically accelerate your Azure deployment workflow. Instead of manually researching Azure CLI commands, writing scripts, and troubleshooting configurations, you'll use natural language prompts to let Copilot handle the heavy lifting.
What is Agent Mode?
Agent Mode is GitHub Copilot's conversational AI assistant that can execute multi-step tasks, run terminal commands, create files, and interact with Azure directly through the CLI. You simply describe your goal in plain English, and Copilot orchestrates the entire deployment process.
What you'll accomplish:
- Deploy containerized applications to Azure without writing deployment scripts
- Configure enterprise-grade authentication using Microsoft Entra ID
- Test and validate your infrastructure using Azure CLI
- Learn repeatable patterns for future deployments
Technologies used:
- Azure Container Registry (ACR) - Store your Docker images
- Azure Container Apps - Serverless container hosting
- Microsoft Entra ID - Enterprise authentication
- Azure CLI - Direct cloud resource management
Why this approach?
Traditional deployment methods require deep knowledge of Azure CLI syntax, infrastructure-as-code tools, and authentication protocols. With GitHub Copilot Agent Mode, you can focus on what you want to achieve while Copilot handles how to implement it, dramatically reducing deployment time from hours to minutes.
๐๏ธ Architecture
graph TB
User[User Browser] -->|HTTPS| ContainerApp[Azure Container App]
ContainerApp -->|Authentication| EntraID[Microsoft Entra ID]
EntraID -->|Token Validation| ContainerApp
ContainerApp -->|Pull Image| ACR[Azure Container Registry]
Dev[Developer] -->|Build & Push| ACR
Dev -->|Deploy| ContainerApp
style ContainerApp fill:#0078d4,color:#fff
style ACR fill:#0078d4,color:#fff
style EntraID fill:#0078d4,color:#fff
๐ Deployment Flow
sequenceDiagram
participant Dev as Developer
participant Copilot as GitHub Copilot
participant ACR as Container Registry
participant ACA as Container App
participant EntraID as Entra ID
Dev->>Copilot: "Create Dockerfile for my app"
Copilot->>Dev: Generates Dockerfile
Dev->>Copilot: "Deploy to Azure Container Apps"
Copilot->>ACR: Build & Push image
Copilot->>ACA: Create/Update Container App
Dev->>Copilot: "Enable Entra ID authentication"
Copilot->>EntraID: Register application
Copilot->>ACA: Configure authentication
ACA->>Dev: Returns application URL
โ Prerequisites
Before starting, ensure you have:
- An existing web application (any language/framework)
- Azure subscription with active access
- Azure CLI installed
- GitHub Copilot enabled in VS Code
- Docker knowledge (basic understanding)
๐ Step-by-Step Guide
Note: All prompts should be used in GitHub Copilot Agent Mode (accessed via the Chat panel in VS Code). Agent Mode allows Copilot to execute multi-step operations, run CLI commands, and manage files automatically.
Step 1: Prepare Your Application
Copilot Prompt:
Create a Dockerfile for my [Python/Node.js/Java/.NET] application that runs on port [PORT_NUMBER].
The app requires [list specific dependencies like Flask, Express, Spring Boot, etc.].
Also create a .dockerignore file to exclude unnecessary files from the build.
What Copilot will create:
Dockerfile- Container build instructions.dockerignore- Files to exclude from the image
Example result:
FROM python:3.11-slim
WORKDIR /app
COPY src/app.py .
EXPOSE 8000
CMD ["python", "app.py"]Step 2: Deploy Azure Infrastructure
Copilot Prompt:
Use Azure CLI without generating additional files. Create an Azure Resource Group in [region]
called [myapp-rg]. Then create a Container Registry called [myappregistry]. Build my Docker
image using ACR build and push it to the registry. Create a Container App Environment and
deploy a Container App called [myapp-container] with external ingress on port [PORT_NUMBER].
Provide me with the final application URL.
What Copilot will do:
- Execute Azure CLI commands directly in the terminal
- Create Resource Group
- Create Azure Container Registry
- Build Docker image using ACR
- Create Container App Environment
- Deploy Container App
- Return the application URL
Expected outcome:
โ
Resource Group: myapp-rg
โ
Container Registry: myappregistry
โ
Container App: myapp-container
โ
URL: https://myapp-container.[random-id].[region].azurecontainerapps.io
Step 3: Enable Entra ID Authentication
Copilot Prompt:
Use Azure CLI to enable Entra ID authentication for my Container App. Register an Entra ID
application with the appropriate redirect URIs, create a service principal, generate client
secret, and configure the Container App authentication using Microsoft identity provider.
Store all configuration values (subscription ID, tenant ID, client ID, client secret, resource
group, registry name, container app name) in a .env file and update .gitignore to exclude it.
What Copilot will do:
- Execute Azure CLI commands to register Entra ID app
- Create service principal
- Generate client credentials
- Configure authentication on Container App using CLI
- Create
.envfile with configuration - Update
.gitignoreto protect secrets
Configuration stored in .env:
AZURE_SUBSCRIPTION_ID=xxxxx
AZURE_TENANT_ID=xxxxx
ENTRA_CLIENT_ID=xxxxx
ENTRA_CLIENT_SECRET=xxxxx
RESOURCE_GROUP=myapp-rg
REGISTRY_NAME=myappregistry
CONTAINER_APP_NAME=myapp-containerStep 4: Update Your Application Code
Copilot Prompt:
Update my [Python/Node.js/Java/.NET] application to read the X-MS-CLIENT-PRINCIPAL header
that Azure Container Apps injects after Entra ID authentication. Parse the base64-encoded
JSON data to extract user claims and display the user's name, email, and authentication
status on the web page.
What Copilot will add:
For Python applications:
def get_user_info(self):
auth_header = self.headers.get('X-MS-CLIENT-PRINCIPAL')
if auth_header:
user_data = json.loads(base64.b64decode(auth_header))
return user_data.get('claims', [])
return NoneFor Node.js applications:
const authHeader = req.headers['x-ms-client-principal'];
const userData = authHeader ?
JSON.parse(Buffer.from(authHeader, 'base64').toString()) : null;๐ง Manual Alternative: Entra ID Registration
If you prefer to register the Entra ID application manually using Azure CLI commands instead of the prompt-based approach in Step 3, follow these steps:
Note: This is optional. If you already used the Copilot prompt in Step 3, you can skip this section.
1. Register the Application
# Get your Container App URL
APP_URL=$(az containerapp show \
--name myapp-container \
--resource-group myapp-rg \
--query properties.configuration.ingress.fqdn -o tsv)
# Create app registration
APP_ID=$(az ad app create \
--display-name "MyApp Authentication" \
--web-redirect-uris "https://$APP_URL/.auth/login/aad/callback" \
--query appId -o tsv)
echo "Client ID: $APP_ID"2. Create Service Principal
az ad sp create --id $APP_ID3. Generate Client Secret
CLIENT_SECRET=$(az ad app credential reset \
--id $APP_ID \
--query password -o tsv)
echo "Client Secret: $CLIENT_SECRET"4. Get Tenant ID
TENANT_ID=$(az account show --query tenantId -o tsv)
echo "Tenant ID: $TENANT_ID"5. Configure Container App Authentication
# Store client secret
az containerapp secret set \
--name myapp-container \
--resource-group myapp-rg \
--secrets entra-secret=$CLIENT_SECRET
# Configure authentication
az containerapp auth microsoft update \
--name myapp-container \
--resource-group myapp-rg \
--client-id $APP_ID \
--client-secret-name entra-secret \
--issuer https://login.microsoftonline.com/$TENANT_ID/v2.0 \
--allowed-audiences api://$APP_ID \
--yes
# Require authentication
az containerapp auth update \
--name myapp-container \
--resource-group myapp-rg \
--unauthenticated-client-action RedirectToLoginPage๐งช Testing Your Deployment
1. Verify Container App is Running
Copilot Prompt:
Use Azure CLI to check the status of my Container App and show me the current revisions
with their traffic distribution.
Manual command:
az containerapp revision list \
--name myapp-container \
--resource-group myapp-rg \
--query "[].{Name:name, Active:active, Traffic:trafficWeight}" \
-o table2. Test Authentication
Visit your application URL in a browser:
https://myapp-container.[random].[region].azurecontainerapps.io
Expected behavior:
- Redirects to Microsoft login page
- User authenticates with organizational account
- Redirects back to your application
- Application displays user information
3. Test API Authentication
# Should return 401 Unauthorized
curl -I https://myapp-container.[url].azurecontainerapps.io
# With valid token, should return 200 OK
curl -H "Authorization: Bearer $TOKEN" \
https://myapp-container.[url].azurecontainerapps.io๐ Continuous Deployment (Optional)
This section is optional but recommended for production deployments.
Option 1: Using GitHub Copilot
Copilot Prompt:
Create a GitHub Actions workflow file that automatically builds and deploys my container app
to Azure whenever I push to the main branch. Use Azure CLI commands and store Azure credentials
as GitHub secrets.
Option 2: Manual Deployment Commands
When you need to redeploy after making changes, run these commands directly:
# Load environment variables
source .env
# Set a new version tag
VERSION=$(date +%Y%m%d-%H%M%S)
# Build and push new image version
az acr build \
--registry $REGISTRY_NAME \
--image myapp:$VERSION .
# Update Container App with new image
az containerapp update \
--name $CONTAINER_APP_NAME \
--resource-group $RESOURCE_GROUP \
--image $REGISTRY_NAME.azurecr.io/myapp:$VERSION
echo "Deployed version: $VERSION"๐ Monitoring and Logs
Copilot Prompt:
Use Azure CLI to show me the real-time logs from my Container App with the --follow flag.
Manual commands:
# View recent logs
az containerapp logs show \
--name myapp-container \
--resource-group myapp-rg \
--follow
# View specific revision logs
az containerapp revision list \
--name myapp-container \
--resource-group myapp-rg๐ Troubleshooting
Authentication Not Working
Issue: Users not being redirected to login
Solution:
# Verify auth configuration
az containerapp auth show \
--name myapp-container \
--resource-group myapp-rgContainer Not Starting
Issue: Container app shows unhealthy status
Check logs:
az containerapp logs show \
--name myapp-container \
--resource-group myapp-rg \
--tail 50Common causes:
- Wrong port configuration (check ingress port matches app port)
- Missing environment variables
- Image build errors
Image Pull Errors
Issue: Cannot pull image from registry
Solution:
# Verify registry access
az acr login --name myappregistry
# Check if image exists
az acr repository list --name myappregistry๐งน Cleanup Resources
When you're done testing:
Copilot Prompt:
Use Azure CLI to delete the entire Resource Group [myapp-rg] to clean up all resources
and avoid charges.
Manual command:
az group delete --name myapp-rg --yes --no-wait๐ Key Concepts Summary
| Component | Purpose | Cost Model |
|---|---|---|
| Container Registry | Store Docker images | Pay per GB stored + data transfer |
| Container Apps | Run containers serverless | Pay per vCPU/memory second |
| Entra ID | Enterprise authentication | Free for basic features |
๐ฏ Best Practices
-
Security
- Always use
.gitignorefor.envfiles - Store secrets in Azure Key Vault for production
- Use managed identities when possible
- Always use
-
Performance
- Use minimal base images (alpine, slim variants)
- Implement health checks
- Configure appropriate scaling rules
-
Cost Optimization
- Scale to zero when not in use
- Use spot instances for dev/test
- Monitor actual usage vs. provisioned resources
-
DevOps
- Version your container images
- Implement blue-green deployments
- Use revision traffic splitting for gradual rollouts
๐ Additional Resources
- Azure Container Apps Documentation
- Azure Container Registry Documentation
- Microsoft Entra ID Documentation
- GitHub Copilot in VS Code
๐ก Example: Complete Session with Copilot
Here's what a typical deployment conversation looks like:
You: "Create a Dockerfile for my Python web app that runs on port 8000. It uses Flask.
Also create a .dockerignore file."
Copilot: [Creates Dockerfile and .dockerignore]
You: "Use Azure CLI to create a Resource Group in East US 2, create a Container Registry,
build my image, create a Container App, and give me the URL."
Copilot: [Executes all Azure CLI commands, provides URL]
You: "Use Azure CLI to enable Entra ID authentication and save config to .env file."
Copilot: [Registers Entra ID app, configures authentication, creates .env]
You: "Update my Python app to read authentication headers and display user information."
Copilot: [Modifies app code to parse X-MS-CLIENT-PRINCIPAL header]
You: "Use Azure CLI to rebuild and redeploy my container with the latest changes."
Copilot: [Builds new image version, updates Container App]
That's it! You now have a fully deployed, authenticated web application on Azure.
Last Updated: February 2026
Difficulty Level: Intermediate
Estimated Time: 30-45 minutes
Use Azure CLI to rebuild and redeploy my container with the latest changes"
Copilot: [Builds new image version, updates Container App