apiops-deployment

SKILL.md

APIOps Deployment Skill

Provides Infrastructure as Code (Bicep/Terraform) templates and CI/CD pipeline patterns for deploying Azure API Management following APIOps principles and phased deployment strategies.

When to Use This Skill

Activate this skill when users need:

  • Infrastructure deployment: Generate Bicep/Terraform for APIM, Front Door, VNet, supporting services
  • CI/CD pipelines: Create GitHub Actions or Azure DevOps workflows for APIOps
  • Environment promotion: Implement dev → test → prod deployment workflows
  • Configuration management: Environment-specific parameters (dev/test/prod)
  • Disaster recovery: Backup/restore procedures, blue-green deployments
  • Phased rollout: Follow deployment planning guide with 7 phases over 17 weeks

Phased Deployment Strategy

See DEPLOYMENT_PLANNING_GUIDE.md for complete 17-week, 7-phase plan

Phase Summary

Phase Duration Focus Key Deliverables
1 Week 1-2 Core Infrastructure VNet, APIM(dev), Front Door, Key Vault, monitoring
2 Week 3-4 Authentication & IAM Entra ID, Entra External ID, OAuth policies
3 Week 5-8 API Onboarding (Dev) 5 pilot APIs, policies, developer portal
4 Week 9-10 Production Infrastructure APIM(prod) Premium 3u, zone-redundant
5 Week 11-12 Production APIs Migrate 5 pilot APIs, performance testing
6 Week 13-15 Governance & Scaling API Center, additional APIs, APIOps automation
7 Week 16-17 Operations Handoff Runbooks, training, monitoring dashboards

Important: MCP Tools (ALWAYS Use Before Code Generation)

1. Get Azure Verified Modules (AVM)

BEFORE writing any Bicep, check for Azure Verified Modules:

Tool: azure_bicep-get_azure_verified_module
ResourceType: "Microsoft.ApiManagement/service"

Why: AVM modules follow Microsoft best practices, reduce code duplication, tested at scale

2. Call Deployment Best Practices FIRST

Tool: mcp_azure_mcp_get_azure_bestpractices
Intent: "Azure API Management deployment best practices Bicep"

3. Search Deployment Documentation

Tool: mcp_azure_mcp_documentation search
Query: "APIM VNet Internal Bicep deployment"

Infrastructure as Code Templates

See references/IaC_TEMPLATES.md for complete Bicep/Terraform templates

Quick Bicep Example: Production APIM

param location string = 'uksouth'
param apimName string = 'apim-api-marketplace-prod-uks'
param publisherEmail string = 'admin@example.com'
param publisherName string = 'API Marketplace Team'
param vnetName string = 'vnet-apim-prod-uks'
param subnetName string = 'snet-apim'

resource vnet 'Microsoft.Network/virtualNetworks@2023-04-01' existing = {
  name: vnetName
}

resource apim 'Microsoft.ApiManagement/service@2023-05-01-preview' = {
  name: apimName
  location: location
  sku: {
    name: 'Premium'
    capacity: 3 // Zone-redundant: 3 units across 3 availability zones
  }
  properties: {
    publisherEmail: publisherEmail
    publisherName: publisherName
    virtualNetworkType: 'Internal' // VNet Internal mode
    virtualNetworkConfiguration: {
      subnetResourceId: '${vnet.id}/subnets/${subnetName}'
    }
    customProperties: {
      'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls10': 'False'
      'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls11': 'False'
      'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Ssl30': 'False'
      'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls10': 'False'
      'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls11': 'False'
      'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Ssl30': 'False'
      'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TripleDes168': 'False'
    }
    disableGateway: false
  }
  identity: {
    type: 'SystemAssigned' // Managed Identity for Key Vault access
  }
  zones: [
    '1'
    '2'
    '3'
  ] // Zone redundancy for 99.99% SLA
}

output apimId string = apim.id
output managedIdentityPrincipalId string = apim.identity.principalId

Key Configuration:

  • VNet Internal mode (virtualNetworkType: 'Internal')
  • Premium SKU with 3 units (zone-redundant)
  • TLS 1.2+ only (disable weak protocols)
  • Managed Identity (no service accounts)
  • Zones [1, 2, 3] for 99.99% SLA

APIOps CI/CD Pipeline Pattern

GitHub Actions Workflow (Recommended)

name: APIOps - Deploy APIM Infrastructure

on:
  workflow_dispatch:
  push:
    branches: [main]
    paths:
      - 'infra/**'
      - '.github/workflows/deploy-infra.yml'

env:
  AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
  AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
  
jobs:
  # ===== Dev Environment =====
  deploy-dev:
    runs-on: ubuntu-latest
    environment: development
    steps:
      - uses: actions/checkout@v4
      
      - name: Azure Login
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ env.AZURE_TENANT_ID }}
          subscription-id: ${{ env.AZURE_SUBSCRIPTION_ID }}
      
      - name: Deploy Bicep
        uses: azure/arm-deploy@v2
        with:
          scope: resourcegroup
          resourceGroupName: rg-apim-dev-uks
          template: ./infra/main.bicep
          parameters: ./infra/params/dev.bicepparam
          failOnStdErr: false
      
      - name: Smoke Test
        run: |
          # Verify APIM health endpoint
          curl -f https://management.azure.com/subscriptions/${{ env.AZURE_SUBSCRIPTION_ID }}/resourceGroups/rg-apim-dev-uks/providers/Microsoft.ApiManagement/service/apim-api-marketplace-dev-uks?api-version=2023-05-01-preview \
            -H "Authorization: Bearer $(az account get-access-token --query accessToken -o tsv)"
  
  # ===== Test Environment (After Dev) =====
  deploy-test:
    needs: deploy-dev
    runs-on: ubuntu-latest
    environment: test
    steps:
      # Same steps as dev, use test.bicepparam
      - uses: actions/checkout@v4
      - uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ env.AZURE_TENANT_ID }}
          subscription-id: ${{ env.AZURE_SUBSCRIPTION_ID }}
      - uses: azure/arm-deploy@v2
        with:
          scope: resourcegroup
          resourceGroupName: rg-apim-test-uks
          template: ./infra/main.bicep
          parameters: ./infra/params/test.bicepparam
          failOnStdErr: false
  
  # ===== Production (Manual Approval Required) =====
  deploy-prod:
    needs: deploy-test
    runs-on: ubuntu-latest
    environment:
      name: production
      # GitHub environment protection rule: Require manual approval
    steps:
      - uses: actions/checkout@v4
      - uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ env.AZURE_TENANT_ID }}
          subscription-id: ${{ env.AZURE_SUBSCRIPTION_ID }}
      
      - name: Deploy Production APIM
        uses: azure/arm-deploy@v2
        with:
          scope: resourcegroup
          resourceGroupName: rg-apim-prod-uks
          template: ./infra/main.bicep
          parameters: ./infra/params/prod.bicepparam
          failOnStdErr: false
      
      - name: Production Smoke Test
        run: |
          # Verify Front Door → APIM connectivity
          curl -f https://api.yourdomain.com/health
      
      - name: Tag Release
        run: |
          git tag -a "apim-prod-$(date +%Y%m%d-%H%M%S)" -m "Production deployment"
          git push origin --tags

Key Features:

  • Dev → Test → Prod progression (serial jobs with needs)
  • Manual approval for production (environment: production with protection rules)
  • Smoke tests after each deployment
  • Git tags for production releases (audit trail)
  • Federated credential authentication (no secrets in code)

Environment-Specific Parameters

dev.bicepparam

using './main.bicep'

param location = 'uksouth'
param environment = 'dev'
param apimSku = 'Developer' // £45/month
param apimCapacity = 1
param virtualNetworkType = 'Internal'
param enableFrontDoor = false // Dev: Direct APIM access
param tags = {
  Environment: 'Development'
  ManagedBy: 'IaC'
  CostCenter: 'Engineering'
}

prod.bicepparam

using './main.bicep'

param location = 'uksouth'
param environment = 'prod'
param apimSku = 'Premium' // £1,944/month (3 units)
param apimCapacity = 3 // Zone-redundant
param virtualNetworkType = 'Internal'
param enableFrontDoor = true // Prod: Front Door + Private Link
param enableApiCenter = true // £135/month
param tags = {
  Environment: 'Production'
  ManagedBy: 'IaC'
  CostCenter: 'Operations'
  Criticality: 'High'
}

Pattern: Single main.bicep template, environment-specific .bicepparam files for configuration


Backup & Restore Procedures

APIM Backup (Automated)

#!/bin/bash
# backup-apim.sh - Schedule daily via Azure Automation or GitHub Actions

APIM_NAME="apim-api-marketplace-prod-uks"
RESOURCE_GROUP="rg-apim-prod-uks"
STORAGE_ACCOUNT="stapimproduksbkp"
CONTAINER="apim-backups"
BACKUP_NAME="apim-backup-$(date +%Y%m%d-%H%M%S)"

# Trigger APIM backup to Storage Account
az apim backup create \
  --name "$APIM_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --storage-account-name "$STORAGE_ACCOUNT" \
  --storage-account-container "$CONTAINER" \
  --backup-name "$BACKUP_NAME"

echo "Backup created: $BACKUP_NAME"

APIM Restore (Disaster Recovery)

#!/bin/bash
# restore-apim.sh - Run during DR scenario

APIM_NAME="apim-api-marketplace-prod-uks"
RESOURCE_GROUP="rg-apim-prod-uks"
STORAGE_ACCOUNT="stapimproduksbkp"
CONTAINER="apim-backups"
BACKUP_NAME="apim-backup-20260128-120000" # Latest successful backup

# Restore APIM from backup
az apim backup restore \
  --name "$APIM_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --storage-account-name "$STORAGE_ACCOUNT" \
  --storage-account-container "$CONTAINER" \
  --backup-name "$BACKUP_NAME"

echo "APIM restored from backup: $BACKUP_NAME"

Backup Retention:

  • Daily backups for 30 days (Azure Storage lifecycle policy)
  • Weekly backups for 12 weeks
  • Monthly backups for 12 months
  • Geo-redundant storage (GRS) to UK West

Deployment Validation Checklist

Before production deployment, verify:

  • Infrastructure Code: Bicep/Terraform linted and validated (az bicep build, terraform validate)
  • Network Configuration: VNet Internal mode, Private Link configured
  • Security: TLS 1.2+, weak protocols disabled, Key Vault integration
  • Authentication: OAuth policies deployed, Entra ID/External ID configured
  • Rate Limiting: All APIs have rate-limit-by-key policies
  • Monitoring: Application Insights, diagnostic logs, alerts configured
  • Backups: Automated daily backups to GRS storage
  • Smoke Tests: Health endpoints responding, Front Door → APIM connectivity verified
  • Manual Approval: Production deployment requires human approval (GitHub environment protection)
  • Rollback Plan: Previous Bicep/Terraform state in Git, APIM backup available

Common Deployment Issues & Solutions

Issue: APIM VNet Integration Fails

Error: The subnet is not valid for API Management instance

Solution:

  1. Ensure subnet size ≥ /27 (32 IPs minimum)
  2. Subnet must not have any other resources
  3. Delegate subnet to Microsoft.ApiManagement/service:
    delegations: [
      {
        name: 'delegation'
        properties: {
          serviceName: 'Microsoft.ApiManagement/service'
        }
      }
    ]
    

Issue: Private Link Connection Pending

Error: Front Door → APIM Private Link status Pending Approval

Solution:

  1. Approve Private Endpoint connection in APIM:
    az network private-endpoint-connection approve \
      --resource-name apim-api-marketplace-prod-uks \
      --resource-group rg-apim-prod-uks \
      --name <connection-name> \
      --type Microsoft.ApiManagement/service
    
  2. Verify status:
    az network private-endpoint-connection list \
      --name apim-api-marketplace-prod-uks \
      --resource-group rg-apim-prod-uks \
      --type Microsoft.ApiManagement/service
    

Issue: Deployment Takes 45+ Minutes

Cause: APIM Premium with zone redundancy takes 30-60 minutes to deploy

Solution: Expected behavior. Use incremental deployments:

  • Day 1: Deploy APIM infrastructure (wait 45 min)
  • Day 2+: Deploy API configurations (fast, minutes)

Optimization: Use --what-if flag to preview changes without deploying


Related Skills

  • azure-apim-architecture - Understand architecture before deploying
  • apim-policy-authoring - Deploy policies as part of APIOps workflow
  • api-security-review - Validate security before production deployment

Microsoft Documentation


Skill Version: 1.0
Last Updated: 29 January 2026
Primary Knowledge: DEPLOYMENT_PLANNING_GUIDE.md, references/IaC_TEMPLATES.md

Weekly Installs
6
GitHub Stars
88
First Seen
14 days ago
Installed on
opencode6
gemini-cli6
github-copilot6
codex6
kimi-cli6
cursor6