A comprehensive Azure Function App boilerplate with Shopify integration, FastAPI, and complete infrastructure as code. This template provides a production-ready foundation for building serverless applications with Azure Functions.
- Azure CLI
- Azure Developer CLI (azd)
- Python 3.12+
- Poetry (for local development)
- Get the template:
azd init --template https://github.com/SatelCreative/azure-function-app-boilerplate.git ? Enter a unique environment name: <APP-NAME>
- Rename the app:
./rename-integration.sh <APP-NAME> <REPO-NAME>
- Configure environment:
cd <APP-NAME> # Edit configuration files (config.sh and local.settings.json are auto-created)
- Set ENV variables
export AZURE_ENV_NAME=<RESOURCE_GROUP_NAME-ENV> export AZURE_SERVICE_NAME=<APP-NAME> export AZURE_LOCATION=<REGION>
Note: You can also add these variables in config.sh and do source config.sh
rather than exporting as shown above
- Deploy apps using the deploy.sh script:
# Deploy your first app ./deploy.sh my-first-app # Deploy additional apps to the same resource group ./deploy.sh my-second-app ./deploy.sh my-third-app
The deploy.sh
script will:
- β Automatically create app folders
- β Set up Azure environments
- β Handle all configuration
- β Deploy to Azure
- β Support multiple apps in the same resource group
- Azure Functions: Python 3.12 runtime on consumption plan
- Storage Account: Required for Azure Functions runtime
- Application Insights: Comprehensive monitoring and logging
- Log Analytics Workspace: Centralized logging and analytics
- App Service Plan: Consumption (Y1) tier for cost-effective scaling
- FastAPI Integration: Modern, fast web framework for building APIs
- Shopify Integration: Pre-built webhooks and API client
- Health Check Endpoints: Built-in monitoring and status endpoints
- Comprehensive Testing: Unit tests with pytest
- Local Development: Full local development setup with Azure Functions Core Tools
- Bicep Templates: Complete infrastructure definitions
- Parameterized Deployment: Environment-specific configurations
- GitHub Actions: CI/CD pipeline ready to use
azure-function-app-boilerplate/
βββ azure.yaml # azd configuration
βββ azd-template.json # Template metadata
βββ backend-integration/ # Main application code
β βββ azure.yaml # Service-level azd config
β βββ function_app.py # Azure Functions entry point
β βββ pyproject.toml # Python dependencies
β βββ infra/ # Infrastructure as Code
β β βββ main.bicep # Main Bicep template
β β βββ main.parameters.json # Deployment parameters
β β βββ core/ # Modular Bicep templates
β βββ shopify/ # Shopify integration
β βββ webapp/ # FastAPI application
β βββ utils/ # Shared utilities
β βββ tests/ # Test suite
βββ .github/workflows/ # CI/CD pipelines
The template uses the following environment variables that will be prompted during azd up
:
AZURE_ENV_NAME
: Environment name (becomes resource group name)AZURE_LOCATION
: Azure region (e.g.,eastus
)AZURE_SUBSCRIPTION_ID
: Your Azure subscription ID
Configure your application in backend-integration/infra/main.parameters.json
:
{
"environmentName": {"value": "${AZURE_ENV_NAME}"},
"location": {"value": "${AZURE_LOCATION}"},
"appSettings": {
"value": {
"APP_DOMAIN": "your-domain.com",
"API_KEY": "your-api-key",
"SHOPIFY_APP_URL": "your-shopify-app-url",
"SHOPIFY_API_KEY": "your-shopify-api-key",
"SHOPIFY_API_SECRET": "your-shopify-api-secret"
}
}
}
-
Rename the integration (optional but recommended):
./rename-integration.sh <APP-NAME> <REPO-NAME> # This renames backend-integration/ to <APP-NAME>/ and updates all references # Both APP-NAME and REPO-NAME are required parameters
-
Install dependencies:
cd <APP-NAME> # or whatever name you chose poetry install
-
Configure local settings:
cp local.settings.json.example local.settings.json # Edit local.settings.json with your development values
-
Run locally:
poetry run func start
-
Run tests:
poetry run pytest
The deploy.sh
script provides zero-config deployment:
# Deploy your first app
./deploy.sh my-first-app
# Deploy additional apps to the same resource group
./deploy.sh my-second-app
Environment Variables (Optional):
AZURE_ENV_NAME
: Environment name (becomes resource group name)AZURE_LOCATION
: Azure region (e.g.,eastus
)AZURE_SUBSCRIPTION_ID
: Your Azure subscription IDTEMPLATE_URL
: Template repository URL (auto-detected if not set)
# Deploy everything (infrastructure + code)
azd up
# Deploy only code changes
azd deploy
# Deploy only infrastructure changes
azd provision
When you deploy, the following Azure resources are created:
- Resource Group: Named after your environment (e.g.,
my-env
) - Function App: Python 3.12 runtime on consumption plan
- Storage Account: Required for Azure Functions
- Application Insights: Monitoring and logging
- Log Analytics Workspace: Centralized logging
- App Service Plan: Consumption (Y1) tier
This template supports deploying multiple applications to the same resource group. Each application will have unique resource names based on the AZURE_SERVICE_NAME
parameter.
Example: Deploy Two Apps to Same Resource Group
# Deploy first app
./deploy.sh app1
# Deploy second app to same resource group
./deploy.sh app2
Resource Naming Convention:
- Resource Group:
{AZURE_ENV_NAME}
(shared) - Function App:
{AZURE_SERVICE_NAME}-{hash}-function-app
- Storage Account:
{AZURE_SERVICE_NAME}{hash}storage
- App Service Plan:
{AZURE_SERVICE_NAME}-{hash}-plan
- Application Insights:
{AZURE_SERVICE_NAME}-{hash}-appinsights
Benefits:
- Cost Efficiency: Share monitoring and logging resources
- Centralized Management: All related apps in one resource group
- Unique Resources: Each app has its own compute and storage
- Easy Cleanup: Delete entire resource group to remove all apps
Before setting up Azure DevOps integration, you'll need to gather the following information:
- Azure Subscription ID: Found in the Azure Portal Subscriptions page
- Azure Tenant ID: Available after app registration
- Azure Client ID: Generated during app registration
Navigate to the Azure Portal Subscriptions page and copy your subscription ID.
- Go to the Azure App Registrations page
- Click "New registration"
- Provide a name for your application
- Select the appropriate account types
- Click "Register"
This will provide you with:
- AZURE_CLIENT_ID (Application ID)
- AZURE_TENANT_ID (Directory ID)
- In your app registration, navigate to "Certificates & secrets"
- Click on "Federated credentials" tab
- Click "Add credential"
- Configure the federated credential with:
- Entity type: GitHub Actions
- Repository:
your-org/your-repo
- Environment:
backend-integration-dev
(must match your workflow environment) - Branch:
main
(or your default branch)
Important: The environment name must match exactly with the environment specified in your GitHub workflows. See the workflow configuration for reference.
The registered app needs contributor permissions for your Azure subscription. Run the following command locally:
az role assignment create \
--assignee "AZURE_CLIENT_ID" \
--role "Contributor" \
--scope "/subscriptions/AZURE_SUBSCRIPTION_ID"
Verification: To verify the role assignment, run:
az role assignment list \
--assignee "AZURE_CLIENT_ID" \
--scope "/subscriptions/AZURE_SUBSCRIPTION_ID" \
--output table
Note: Make sure you're logged into the correct Azure organization before running these commands.
Once the app has been created on Azure, you'll need to add the following environment variables to your GitHub repository variables/secrets:
<APP_NAME>_CLIENT_ID
<APP_NAME>_TENANT_ID
<APP_NAME>_SUBSCRIPTION_ID
<APP_NAME>_ENV_NAME
<APP_NAME>_LOCATION
This boilerplate provides a production-ready foundation for building Azure Function-based integrations with proper monitoring, deployment pipelines, and infrastructure management.
-
Rename the integration directory:
./rename-integration.sh your-integration-name your-repo-name # This script will rename backend-integration/ and update all configuration files # Both integration-name and repo-name are required parameters
-
Update configuration files:
- Update
azure.yaml
service project path - Update
pyproject.toml
project name - Update GitHub workflow file paths
- Update
-
Customize the integration code:
- Replace Shopify-specific code in
shopify/
directory - Update configuration in
utils/config.py
- Modify API endpoints in
webapp/main.py
- Replace Shopify-specific code in
-
Update infrastructure parameters:
- Modify
infra/main.parameters.json
for your specific needs - Add any additional Azure resources in
infra/main.bicep
- Modify
- Create Bicep modules in
backend-integration/infra/core/
- Reference them in
main.bicep
- Add parameters to
main.parameters.json
- Update app settings as needed
The template includes comprehensive monitoring setup:
- Application Insights: Automatic telemetry collection
- Custom Dashboards: Pre-configured monitoring dashboards
- Health Checks: Built-in health check endpoints
- Log Analytics: Centralized logging and querying
Access your monitoring data:
- Application Insights: Azure Portal β Your Function App β Application Insights
- Logs: Azure Portal β Your Function App β Logs
- Metrics: Azure Portal β Your Function App β Metrics
-
"resource not found: unable to find a resource tagged with 'azd-service-name: ...'":
- Use
./deploy.sh <app-name>
for automatic configuration - The script handles all service naming automatically
- Use
-
Deployment fails with permissions error:
- Ensure your Azure account has Contributor role on the subscription
- Check that azd is authenticated:
azd auth login
-
Function app not starting:
- Check Application Insights logs for detailed error messages
- Verify all required app settings are configured
-
Multi-app deployment issues:
- Use
./deploy.sh <app-name>
for each app - it handles everything automatically - Each app gets its own folder and unique service name
- All apps share the same resource group for cost efficiency
- Use
-
Local development issues:
- Ensure Azure Functions Core Tools are installed
- Check that
local.settings.json
is properly configured
-
Template URL issues:
- Set
TEMPLATE_URL
environment variable if auto-detection fails - Or run:
TEMPLATE_URL='your-url' ./deploy.sh <app-name>
- Set
./deploy.sh <app-name>
- Primary deployment method - Zero-config deployment script./rename-integration.sh <new-name> <repo-name>
- Rename integration folder (for manual setup)