This repository demonstrates how to deploy a Python-based Azure Function App to Azure Container Apps using Infrastructure as Code (Bicep) and GitHub Actions for CI/CD.
The solution deploys the following Azure resources:
- Azure Container Registry (ACR) for storing function container images
- Azure Storage Account for function app requirements
- Azure Container Apps Environment
- Azure Function App running on Container Apps
- Managed Identity and RBAC roles for secure access
- Azure Subscription
- GitHub Account
- Azure CLI
- Docker
- Visual Studio Code with Azure Functions extension
- Python 3.12+
├── .github/workflows/
│ └── deploy.yml # GitHub Actions workflow for deployment
├── infra/
│ ├── main.bicep # Infrastructure as Code (Bicep) template
│ └── setup-gh.ps1 # PowerShell script to set up GitHub authentication
├── src/
│ ├── Dockerfile # Container image definition
│ ├── function_app.py # Sample HTTP-triggered function
│ ├── host.json # Function host configuration
│ └── requirements.txt # Python dependencies
-
Clone this repository
-
Run the setup script to configure GitHub authentication:
./infra/setup-gh.ps1
This will:
- Create a service principal with necessary permissions
- Set up GitHub Actions environment and secrets
- Configure federated credentials for passwordless authentication
-
The deployment will create resources in the following environment:
- Resource Group:
rg-pyt001
- Region: South Africa North
- Python Version: 3.12
- Resource Group:
The solution uses GitHub Actions for automated deployment. The workflow:
- Authenticates with Azure using OIDC
- Creates resource group if not exists
- Deploys infrastructure using Bicep
- Builds and pushes the container image to ACR
- Updates the Function App with the latest container image
To deploy:
- Navigate to the Actions tab in your repository
- Select the "Deploy Function App to Container App" workflow
- Click "Run workflow"
-
Install dependencies:
pip install -r src/requirements.txt
-
Run the function locally:
cd src func start
The repository includes a sample HTTP-triggered function that accepts a name
parameter either through query string or request body and returns a personalized greeting.
Test the function:
curl "http://localhost:7071/api/HttpExample?name=YourName"
- HTTPS-only access to storage
- TLS 1.2 enforcement
- OAuth authentication for storage
- System-assigned managed identity
- RBAC for ACR access
- Application Insights monitoring
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.