Azure Container Apps (ACA) needs an external service to do URL routing. In kubernetes this is usually handled by an Ingress. ACA uses Envoy under the hood to handle web traffic, which is great, but it's URL routing functionality is not exposed.
This repo demonstrates how to implement URL routing with YARP, so you get all the flexibility you normally have with ingresses in K8S.
This demo is loosly based on this Azure sample.
This is not a full-fledged production ready sample, it's focussed on demonstrating what could be done with Yarp in Azure Container Apps. For a high traffic site you'll probably want to host your front-end on a service that supports edge caching.
For less demanding applications though, the setup presented here could save quite a bit of money and reduce complexity of the required infrastructure.
The application has 3 deployments, with 1 container each. The public deployment has the Yarp container in it, which delegates traffic by url to the API or the front-end.
The goal of this project is to have a play with Azure Container Apps and get some hands-on experience with:
- Configuring traffic into the Container App Environment
- Connecting apps within an environment
- Auto-scaling with network traffic
- Routing traffic from external to internal apps
ACA already does a bunch of things that most apps need:
- CORS
- IP filtering
- HTTPS termination
Just like K8S and AKS, you can reach other containers directly using their deployment name. So, within the Conainer Environment, http://frontend
resolves to the frontend
deployment.
The main missing feature for me is path based routing and URL rewriting. This is where YARP comes in. It's dotnet based reverse proxy. For dotnet devs it's really easy to use and configure, and it's pretty fast too.
To make it even more interesting, I've implemented HMAC request signing in YARP. Here, it's implemented as an authentication method. The idea is that if you can implement this kind of functionality within the cluster, there's less need for pricy external resources like API Management. This type of authorization is best suited for machine-to-machine connections, for example to validate incoming webhooks.
You'll need:
A dev environment is handy too:
Start each of the projects, either from the development environment or by running dotnet run
.
Navigate to the YARP endpoint at https://localhost:7193.
There's a LoadTester tool that will hit the API and the frontend.
In the node folder there's a small test script showing how to invoke the API from another tech stack.
You'll need:
Before rolling out the apps, we need to have some infrastructure in place. We'll roll this out using Azure CLI.
First, make sure you're logged in and have the correct subscription selected:
# Login to the CLI
az login
az extension add -n containerapp
# Ensure you have the right subscription selected
az account show
Now deploy the Container Apps environment and supporting services.
# Setup preferences
$location="westeurope"
# Ensure the required provider is registered in the subscription
az provider register --namespace Microsoft.Web
# Create a resource group
az group create `
--name 'sample-rg' `
--location $location
az monitor log-analytics workspace create `
--resource-group 'sample-rg' `
--workspace-name 'logs-for-sample'
az monitor app-insights component create `
--app insights-for-sample `
--location $location `
--resource-group 'sample-rg'
$LOG_ANALYTICS_WORKSPACE_CLIENT_ID=$(az monitor log-analytics workspace show --query customerId -g 'sample-rg' -n 'logs-for-sample' --out tsv)
$LOG_ANALYTICS_WORKSPACE_CLIENT_SECRET=$(az monitor log-analytics workspace get-shared-keys --query primarySharedKey -g 'sample-rg' -n 'logs-for-sample' --out tsv)
# Create a container app environment
az containerapp env create `
--name 'sample-env' `
--resource-group 'sample-rg' `
--logs-workspace-id $LOG_ANALYTICS_WORKSPACE_CLIENT_ID `
--logs-workspace-key $LOG_ANALYTICS_WORKSPACE_CLIENT_SECRET `
--location $location
Each individual project can be deployed using the deploy.ps1
script in the respective apps's folder.
On the first deployment, the container app tooling will create a container registry. This will happen only once.