Skip to content
MCP

Chapter 9 Β· Integrate & Ship

Azure Deployment

Ship the server to Azure with one script. Bicep provisions everything, the image is built in ACR, and APIM fronts the app. You choose App Service or Container Apps.

🎯 What you'll be able to do

  • Run the deployment script for App Service or Container Apps
  • Identify the Azure resources each Bicep file creates
  • Understand the APIM policy and replace its placeholder IP ranges
  • Choose between App Service and Container Apps

Primary deployment command

From the project root:

PowerShell
az login
.\scripts\deploy.ps1 `
    -ResourceGroup rg-jira-mcp `
    -Location eastus `
    -Acr myacr `
    -PublisherEmail you@example.com

The script:

  1. Creates the resource group.
  2. Builds the image in Azure Container Registry.
  3. Deploys Azure resources with Bicep.
  4. Prints the MCP endpoint.
  5. Prints the connector host.

Use Container Apps instead of App Service with the -Hosting switch:

PowerShell
.\scripts\deploy.ps1 `
    -ResourceGroup rg-jira-mcp `
    -Location eastus `
    -Acr myacr `
    -PublisherEmail you@example.com `
    -Hosting ContainerApps

Deployment topology

Both hosting options share this shape: ACR β†’ host β†’ APIM β†’ connector, with Key Vault and App Insights alongside.

App Service deployment resources

infra\\main.bicep creates:

ResourcePurpose
Log Analytics workspaceStores logs.
Application InsightsApp telemetry.
Key VaultGateway secret.
Linux App Service planHosts the container.
Linux Web AppRuns the MCP container.
Autoscale settingScales the App Service plan.
API ManagementPublic gateway.
APIM named valueSecret reference to Key Vault.
APIM API and operationExposes /jira-mcp/mcp.
APIM policySecurity and routing policy.

Container Apps deployment resources

infra\\containerapp.bicep creates:

ResourcePurpose
User-assigned managed identityPulls the ACR image and reads the Key Vault secret.
Log Analytics workspaceContainer logs.
Application InsightsApp telemetry.
Key VaultGateway secret.
Container Apps environmentHosting environment.
Container AppRuns the MCP container.
API ManagementPublic gateway.
APIM policySecurity and routing.

APIM policy & IP ranges

The policy in infra\\apim-policy.xml restricts origins via CORS, includes placeholder IP allow-list ranges, rate limits and applies a daily quota by IP, requires an Authorization header, injects X-Gateway-Token, adds hardening headers, and deletes sensitive headers on error paths.

Find the service tag ranges for your region:

PowerShell
az network list-service-tags --location eastus `
  --query "values[?name=='AzureConnectors.EastUS'].properties.addressPrefixes" -o json

App Service vs Container Apps

βœ“ App Service β€” choose when

  • You want a familiar web-app hosting model
  • You value built-in health checks and simple ops

βœ— Container Apps β€” choose when

  • You want container-native scaling and revisions
  • You want HTTP-concurrency-based scaling
Production note
Both can be production-ready. Keep APIM in front either way β€” the gateway is part of the security model, not an optional extra.

❓ Concept check

Deployment succeeds, the app's own /healthz works, but calls through APIM fail. The APIM policy still has REPLACE_START_IP. What's happening?

πŸ“Œ Chapter summary

  • deploy.ps1 creates the resource group, builds the image in ACR, deploys Bicep, and prints the MCP endpoint and connector host.
  • Both hosting options put APIM in front and use a Key Vault-backed gateway secret.
  • Replace placeholder IP ranges in the APIM policy with connector egress / service tags before production.

βœ… End-of-chapter review

0/4 done