.github/skills/apiops-deployment/SKILL.md
Guides deployment of Azure API Management infrastructure using Infrastructure as Code (Bicep/Terraform), CI/CD pipelines (GitHub Actions/Azure DevOps), and APIOps workflows. Use when deploying APIM, creating pipelines, or implementing dev→test→prod promotion strategies.
npx skillsauth add thomast1906/github-copilot-agent-skills apiops-deploymentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Provides Infrastructure as Code (Bicep/Terraform) templates and CI/CD pipeline patterns for deploying Azure API Management following APIOps principles and phased deployment strategies.
Activate this skill when users need:
See DEPLOYMENT_PLANNING_GUIDE.md for complete 17-week, 7-phase plan
| 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 |
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
Tool: mcp_azure_mcp_get_azure_bestpractices
Intent: "Azure API Management deployment best practices Bicep"
Tool: mcp_azure_mcp_documentation search
Query: "APIM VNet Internal Bicep deployment"
See references/IaC_TEMPLATES.md for complete Bicep/Terraform templates
param location string = 'uksouth'
param apimName string = 'apim-api-marketplace-prod-uks'
param publisherEmail string = '[email protected]'
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:
virtualNetworkType: 'Internal')[1, 2, 3] for 99.99% SLAname: 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:
needs)environment: production with protection rules)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'
}
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
#!/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"
#!/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:
Before production deployment, verify:
az bicep build, terraform validate)Error: The subnet is not valid for API Management instance
Solution:
Microsoft.ApiManagement/service:
delegations: [
{
name: 'delegation'
properties: {
serviceName: 'Microsoft.ApiManagement/service'
}
}
]
Error: Front Door → APIM Private Link status Pending Approval
Solution:
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
az network private-endpoint-connection list \
--name apim-api-marketplace-prod-uks \
--resource-group rg-apim-prod-uks \
--type Microsoft.ApiManagement/service
Cause: APIM Premium with zone redundancy takes 30-60 minutes to deploy
Solution: Expected behavior. Use incremental deployments:
Optimization: Use --what-if flag to preview changes without deploying
Skill Version: 1.0
Last Updated: 29 January 2026
Primary Knowledge: DEPLOYMENT_PLANNING_GUIDE.md, references/IaC_TEMPLATES.md
development
Assess Azure architectures against Well-Architected Framework (WAF) five pillars - Reliability, Security, Cost Optimization, Operational Excellence, and Performance Efficiency. Provide scores and recommendations.
devops
Safe Terraform provider upgrades with automatic resource migration, breaking change detection, and state management using moved blocks. Use when upgrading provider versions, handling removed resources, migrating deprecated syntax, or performing major version upgrades.
development
Comprehensive skills for creating, compiling, debugging, and managing GitHub Agentic Workflows (gh-aw) with best practices and common patterns
tools
Create and edit diagrams on a live Excalidraw canvas using the Excalidraw MCP server. Use when asked to draw, diagram, sketch, or visualise architectures, workflows, data flows, system designs, flowcharts, mind maps, or sequence diagrams. Trigger phrases include "create an excalidraw", "draw me a diagram", "make a flowchart", "visualise the system", "diagram this architecture", "export to PNG/SVG". Can export to PNG, SVG, .excalidraw file, or a shareable URL. Do NOT use for Draw.io or diagrams.net output (use drawio-mcp-diagramming instead).