feat: Implement comprehensive Azure Functions code generation and deployment workflow

- Added detailed planning, code generation, testing, and deployment steps for Azure Functions.
- Introduced status tracking and error handling mechanisms.
- Established best practices for code generation and deployment, including security and structure guidelines.
- Created GitHub Actions workflow for production deployment with build, test, and deployment stages.
- Developed PowerShell script for full production deployment with custom domain support.
- Designed Bicep templates for infrastructure setup, including Azure Static Web Apps and Function Apps.
- Configured parameters for production deployment, including Stripe public key and custom domain settings.
- Added SWA CLI configuration for local development and deployment.
- Documented production deployment success criteria and post-deployment tasks.
This commit is contained in:
defiQUG
2025-10-05 20:55:32 -07:00
parent 12764ceb86
commit 68e53f41bf
8 changed files with 1225 additions and 9 deletions

View File

@@ -0,0 +1,146 @@
---
description: Generate and deploy Azure Functions with comprehensive planning, code generation, and deployment automation.
tools: ["changes","edit","extensions","fetch","findTestFiles","githubRepo","new","openSimpleBrowser","problems","runCommands","runNotebooks","runTasks","search","testFailure","todos","usages","vscodeAPI","Microsoft Docs","azureterraformbestpractices","bicepschema","deploy","quota","get_bestpractices","azure_query_azure_resource_graph","azure_generate_azure_cli_command","azure_get_auth_state","azure_get_current_tenant","azure_get_available_tenants","azure_set_current_tenant","azure_get_selected_subscriptions","azure_open_subscription_picker","azure_sign_out_azure_user","azure_diagnose_resource","azure_list_activity_logs"]
model: Claude Sonnet 4
---
# Azure Functions Code Generation and Deployment
Enterprise-grade Azure Functions development workflow with automated planning, code generation, testing, and deployment using Azure best practices and Infrastructure as Code (IaC).
## Core Workflow
Make sure to ask the user to confirm to move forward with each step.
### 1. Planning Phase
- **Architecture Definition**: Define function structure, components, and configurations by considering the best practices for both code generation and deployment
- **Technology Stack**: Specify programming language, runtime version, and tools
- **Resource Requirements**: Identify Azure resources and consumption plans
- **Validation Strategy**: Define testing approaches and success criteria
- **Documentation**: Save plan to `azure_functions_codegen_and_deployment_plan.md`
### 2. Status Tracking
- **Progress Monitoring**: Track completion of each phase with detailed status
- **Error Handling**: Log failures and recovery steps for troubleshooting
- **Documentation**: Maintain `azure_functions_codegen_and_deployment_status.md`
### 3. Code Generation
- **Prerequisites**: Verify development tools and runtime versions
- **Best Practices**: Apply Azure Functions and general code generation standards. Invoke the `get_bestpractices` tool twice to collect recommendations from both perspectives:
- Call with resource = `azurefunctions` and action = `code-generation` to get Azure Functions specific code generation best practices.
- Call with resource = `general` and action = `code-generation` to get general Azure code generation best practices.
Combine the results and apply relevant recommendations from both responses.
- **Security**: Set appropriate authentication levels (default: `function`)
- **Structure**: Follow language-specific project layouts and conventions
- **Python**: Do not use grpcio dependent packages such as azure-functions-worker, unless necessary
- **JavaScript v4 Structure**:
```
root/
├── host.json # Function host configuration
├── local.settings.json # Development settings
├── package.json # Dependencies
├── src/
│ ├── app.js # Main application entry
│ └── [modules].js # Business logic
└── tests/ # Test suite
```
### 4. Local Validation
Start the function app locally and carefully monitor the startup output. Look for any errors, warnings, or unusual messages.
Don't proceed to testing until you've confirmed a clean startup. If you see any issues, investigate and fix them before continuing.
- **Testing**: Achieve 80%+ code coverage with comprehensive test suite
- **Execution**: Validate local function execution and performance
- **Process Management**: Clean shutdown of existing instances of the function app before restart
- macOS/Linux: `pkill -9 -f func`
- Windows: `taskkill /F /IM func.exe /T`
#### Post-Testing Cleanup Protocol
Upon finishing testing, ensure all processes are properly shut down to prevent resource conflicts and port binding issues:
### 5. Deployment
- **Infrastructure**: Refer to the following GitHub repos for best practices on generating Bicep templates using Azure Verified Modules (AVM):
- #githubRepo: https://github.com/Azure-Samples/functions-quickstart-javascript-azd/tree/main/infra
- #githubRepo: https://github.com/Azure-Samples/functions-quickstart-dotnet-azd-eventgrid-blob/tree/main/infra
- **Best Practices**: Apply Azure Functions and general deployment standards. Invoke the `get_bestpractices` tool twice to collect recommendations from both perspectives:
- Call with resource = `azurefunctions` and action = `deployment` to get Azure Functions specific deployment best practices.
- Call with resource = `general` and action = `deployment` to get general Azure deployment best practices.
Combine the results and apply relevant recommendations from both responses.
- **Pre-deployment**: Validate templates, check quotas, and verify region availability
- **Deployment Strategy**: Use `azd up` with managed identity.
- ALWAYS Use Flex Consumption plan (FC1) for deployment, never Y1 dynamic.
- ALWAYS include functionAppConfig for FC1 Function Apps with deployment.storage configuration. Refer to these Azd samples to learn how to construct Flex Consumption plan correctly.
- #githubRepo: https://github.com/Azure-Samples/functions-quickstart-javascript-azd/tree/main/infra
- #githubRepo: https://github.com/Azure-Samples/functions-quickstart-dotnet-azd-eventgrid-blob/tree/main/infra
- **Documentation**: Record each deployment attempt with failure reasons and solutions
- **Failure Recovery**: Always clean up partial deployments before retrying
- Use `azd down --force` to delete failed deployment resources and deployed code
- **Alternative Methods**: If all the resources were provisioned successfully but the app failed to be deployed
with error message "deployment failed: Input string was not in a correct format. Failure to parse near offset 40.
Format item ends prematurely.", use Azure CLI deployment to upload the function app code.
### 6. Post-Deployment
- **Authentication**: Retrieve function names being deployed, then retrieve and configure function keys
- **Endpoint Testing**: Validate all function endpoints with proper authentication
- **Monitoring**: Verify Application Insights telemetry and establish performance baselines
- **Documentation**: Create a README with deployment and usage instructions
## Enterprise Environment Considerations
### Corporate Policy Compliance
- **Alternative Strategies**: Prepare Azure CLI fallback for blocked `azd` commands
- **Compliance Standards**: Use Azure Verified Modules (AVM) for enterprise requirements
- **Network Restrictions**: Consider VNet integration and private endpoints
### Security & Authentication
- **Managed Identity**: Preferred authentication method for Azure-hosted resources
- **Function Keys**: Use function-level keys following principle of least privilege
- **Key Management**: Retrieve keys post-deployment for endpoint testing
- **RBAC Configuration**: Implement proper role assignments for dependencies
## Quality Assurance
### Testing Requirements
- **Unit Tests**: 100% passing rate
- **Integration Tests**: 80%+ coverage of main scenarios
- **Code Quality**: ESLint/linting checks passing
- **Performance**: Baseline performance validation
### Deployment Validation
- **Infrastructure**: Bicep templates pass validation
- **Pre-deployment**: Use deploy tool and set parameter `command` to be `deploy_iac_rules_get` to get the best practices rules for iac generation.
- **Authentication**: Proper managed identity and RBAC configuration
- **Monitoring**: Application Insights receiving telemetry
## Failure Recovery & Troubleshooting
### Common Issues & Solutions
1. **Policy Violations**: Switch to Azure CLI deployment methods
2. **Missing Dependencies**: Systematic tool installation and validation
3. **Authentication Issues**: Comprehensive RBAC and managed identity setup
4. **Runtime Compatibility**: Use supported versions (Node.js 20+, Python 3.11+)
5. **Partial Deployments**: Clean resource group deletion before retry
### Deployment Failure Recovery Protocol
```bash
# Delete failed deployment resources and deployed code
azd down --force
# Or
# Clean failed deployment
az group delete --name rg-<AZURE_ENV_NAME> --yes --no-wait
az group wait --name rg-<AZURE_ENV_NAME> --deleted --timeout 300
# Retry deployment
azd up
```
## Reference Resources
### Azure Functions Best Practices
- **Programming Models**: Use latest versions (v4 JavaScript, v2 Python)
- **Extension Bundles**: Prefer over SDKs for simplified dependency management
- **Event Sources**: Use EventGrid for blob triggers
- **Configuration**: Generate `local.settings.json` for local development
### Infrastructure Templates
- [JavaScript Azure Functions AZD Sample](https://github.com/Azure-Samples/functions-quickstart-javascript-azd/tree/main/infra)
- [.NET Azure Functions with EventGrid Sample](https://github.com/Azure-Samples/functions-quickstart-dotnet-azd-eventgrid-blob/tree/main/infra)

View File

@@ -0,0 +1,249 @@
name: Production Deployment
on:
push:
branches: [ main ]
workflow_dispatch:
inputs:
custom_domain:
description: 'Custom domain name'
required: false
default: 'miraclesinmotion.org'
force_deploy:
description: 'Force deployment even if tests fail'
required: false
default: 'false'
env:
NODE_VERSION: '22'
AZURE_STATIC_WEB_APPS_API_TOKEN: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}
jobs:
build-and-test:
runs-on: ubuntu-latest
name: Build and Test
steps:
- uses: actions/checkout@v4
with:
submodules: true
lfs: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install main dependencies
run: npm install --legacy-peer-deps
- name: Install API dependencies
run: |
cd api
npm install
cd ..
- name: Run linting
run: npm run lint
continue-on-error: true
- name: Run tests
run: npx vitest run --reporter=verbose
continue-on-error: ${{ github.event.inputs.force_deploy == 'true' }}
- name: Build application
run: npm run build
- name: Build API
run: |
cd api
npm run build || npm run tsc
cd ..
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-files
path: |
dist/
api/
staticwebapp.config.json
deploy-infrastructure:
runs-on: ubuntu-latest
needs: build-and-test
name: Deploy Infrastructure
outputs:
static-web-app-name: ${{ steps.deploy.outputs.staticWebAppName }}
function-app-name: ${{ steps.deploy.outputs.functionAppName }}
static-web-app-url: ${{ steps.deploy.outputs.staticWebAppUrl }}
steps:
- uses: actions/checkout@v4
- name: Azure Login
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Create Resource Group
run: |
az group create \
--name rg-miraclesinmotion-prod \
--location "East US"
- name: Deploy Infrastructure
id: deploy
run: |
DEPLOYMENT_NAME="mim-prod-$(date +%Y%m%d-%H%M%S)"
# Deploy infrastructure
DEPLOYMENT_OUTPUT=$(az deployment group create \
--resource-group rg-miraclesinmotion-prod \
--template-file infrastructure/main-production.bicep \
--parameters infrastructure/main-production.parameters.json \
--parameters stripePublicKey="${{ secrets.STRIPE_PUBLIC_KEY }}" \
--parameters customDomainName="${{ github.event.inputs.custom_domain || 'miraclesinmotion.org' }}" \
--parameters enableCustomDomain=true \
--name $DEPLOYMENT_NAME \
--output json)
# Extract outputs
STATIC_WEB_APP_NAME=$(echo $DEPLOYMENT_OUTPUT | jq -r '.properties.outputs.staticWebAppName.value')
FUNCTION_APP_NAME=$(echo $DEPLOYMENT_OUTPUT | jq -r '.properties.outputs.functionAppName.value')
STATIC_WEB_APP_URL=$(echo $DEPLOYMENT_OUTPUT | jq -r '.properties.outputs.staticWebAppUrl.value')
# Set outputs
echo "staticWebAppName=$STATIC_WEB_APP_NAME" >> $GITHUB_OUTPUT
echo "functionAppName=$FUNCTION_APP_NAME" >> $GITHUB_OUTPUT
echo "staticWebAppUrl=$STATIC_WEB_APP_URL" >> $GITHUB_OUTPUT
echo "✅ Infrastructure deployed successfully"
echo "📱 Static Web App: $STATIC_WEB_APP_NAME"
echo "⚡ Function App: $FUNCTION_APP_NAME"
echo "🌐 URL: $STATIC_WEB_APP_URL"
deploy-application:
runs-on: ubuntu-latest
needs: deploy-infrastructure
name: Deploy Application
environment:
name: production
url: ${{ needs.deploy-infrastructure.outputs.static-web-app-url }}
steps:
- uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build-files
- name: Azure Login
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Get Static Web App Deployment Token
id: swa-token
run: |
DEPLOYMENT_TOKEN=$(az staticwebapp secrets list \
--name ${{ needs.deploy-infrastructure.outputs.static-web-app-name }} \
--resource-group rg-miraclesinmotion-prod \
--query "properties.apiKey" \
--output tsv)
echo "::add-mask::$DEPLOYMENT_TOKEN"
echo "token=$DEPLOYMENT_TOKEN" >> $GITHUB_OUTPUT
- name: Setup Node.js for SWA CLI
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install SWA CLI
run: npm install -g @azure/static-web-apps-cli
- name: Deploy to Static Web App
run: |
swa deploy ./dist \
--api-location ./api \
--env production \
--deployment-token ${{ steps.swa-token.outputs.token }}
- name: Deploy Azure Functions
run: |
# Create deployment package
cd api
zip -r ../api-deployment.zip . -x "node_modules/*" "*.test.*" "*.md"
cd ..
# Deploy functions
az functionapp deployment source config-zip \
--resource-group rg-miraclesinmotion-prod \
--name ${{ needs.deploy-infrastructure.outputs.function-app-name }} \
--src api-deployment.zip
- name: Warm up application
run: |
echo "🔥 Warming up the deployed application..."
curl -s ${{ needs.deploy-infrastructure.outputs.static-web-app-url }} > /dev/null
curl -s ${{ needs.deploy-infrastructure.outputs.static-web-app-url }}/#/portals > /dev/null
echo "✅ Application warmed up successfully"
post-deployment:
runs-on: ubuntu-latest
needs: [deploy-infrastructure, deploy-application]
name: Post-Deployment Tasks
steps:
- name: Run smoke tests
run: |
echo "🧪 Running smoke tests..."
# Test main page
STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${{ needs.deploy-infrastructure.outputs.static-web-app-url }})
if [ $STATUS -eq 200 ]; then
echo "✅ Main page is accessible"
else
echo "❌ Main page returned status: $STATUS"
exit 1
fi
# Test portals page
STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${{ needs.deploy-infrastructure.outputs.static-web-app-url }}/#/portals)
if [ $STATUS -eq 200 ]; then
echo "✅ Portals page is accessible"
else
echo "❌ Portals page returned status: $STATUS"
exit 1
fi
echo "🎉 All smoke tests passed!"
- name: Create deployment summary
run: |
echo "## 🚀 Production Deployment Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📊 Deployment Details" >> $GITHUB_STEP_SUMMARY
echo "- **Static Web App**: ${{ needs.deploy-infrastructure.outputs.static-web-app-name }}" >> $GITHUB_STEP_SUMMARY
echo "- **Primary URL**: ${{ needs.deploy-infrastructure.outputs.static-web-app-url }}" >> $GITHUB_STEP_SUMMARY
echo "- **Portal Access**: ${{ needs.deploy-infrastructure.outputs.static-web-app-url }}/#/portals" >> $GITHUB_STEP_SUMMARY
echo "- **Custom Domain**: https://${{ github.event.inputs.custom_domain || 'miraclesinmotion.org' }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🔗 Quick Links" >> $GITHUB_STEP_SUMMARY
echo "- [🏠 Main Site](${{ needs.deploy-infrastructure.outputs.static-web-app-url }})" >> $GITHUB_STEP_SUMMARY
echo "- [🚪 Portals](${{ needs.deploy-infrastructure.outputs.static-web-app-url }}/#/portals)" >> $GITHUB_STEP_SUMMARY
echo "- [💰 Donate](${{ needs.deploy-infrastructure.outputs.static-web-app-url }}/#/donate)" >> $GITHUB_STEP_SUMMARY
echo "- [🤝 Volunteer](${{ needs.deploy-infrastructure.outputs.static-web-app-url }}/#/volunteers)" >> $GITHUB_STEP_SUMMARY
echo "- [📊 Analytics](${{ needs.deploy-infrastructure.outputs.static-web-app-url }}/#/analytics)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📋 Next Steps" >> $GITHUB_STEP_SUMMARY
echo "1. Configure DNS records for custom domain" >> $GITHUB_STEP_SUMMARY
echo "2. Update Stripe webhook endpoints" >> $GITHUB_STEP_SUMMARY
echo "3. Test all portal functionality" >> $GITHUB_STEP_SUMMARY
echo "4. Monitor application performance" >> $GITHUB_STEP_SUMMARY
- name: Notify team
if: success()
run: |
echo "🎉 Production deployment completed successfully!"
echo "🌐 Application is live at: ${{ needs.deploy-infrastructure.outputs.static-web-app-url }}"
echo "🚪 Portals are accessible at: ${{ needs.deploy-infrastructure.outputs.static-web-app-url }}/#/portals"