Service Discovery
1. The Problem
You've got two .NET microservices running in Azure Container Apps:
OrderServicePaymentService
OrderService needs to call PaymentService.
So you configure the Payment service address:
PaymentServiceUrl = http://10.20.4.17
Your .NET application uses HttpClient to call it.
Everything works.
For now.
OrderService
│
│ HttpClient
│ http://10.20.4.17
▼
PaymentService
│
└── Container Replica #1
10.20.4.17
Now traffic increases.
Azure Container Apps scales PaymentService out:
PaymentService
│
├── Replica #1 10.20.4.17
├── Replica #2 10.20.5.21
└── Replica #3 10.20.5.22
Later, Azure removes Replica #1.
PaymentService
│
├── Replica #2 10.20.5.21
└── Replica #3 10.20.5.22
❌ 10.20.4.17 is gone
But your .NET configuration still contains:
http://10.20.4.17
Your calls now start failing.
2. What's Actually Going Wrong?
The problem isn't HttpClient.
The problem is that your .NET application is depending on the address of a particular container instance.
And container instances in Azure are ephemeral.
Azure can:
- create new replicas
- remove existing replicas
- replace containers
- scale the application up and down
So this:
10.20.4.17
is the location of an instance.
It is not the identity of PaymentService.
Your application should know:
“I need PaymentService.”
It shouldn't need to know:
“PaymentService happens to be running at 10.20.4.17.”
3. The Concept
This is what Service Discovery solves.
Instead of calling a specific instance address, your .NET service calls the target service using a stable service name.
Conceptually:
❌ Fixed instance address
OrderService
│
▼
10.20.4.17
│
▼
Specific container instance
becomes:
✅ Service name
OrderService
│
▼
PaymentService
│
▼
Azure service discovery / DNS
│
▼
Current PaymentService replica
The service name remains stable.
The underlying replica can change.
That's the key idea.
4. How Do You Fix It?
The fix is to stop putting an individual container instance address into your .NET application configuration.
Instead, use the stable internal name of the target service.
With Azure Container Apps, services within the same Container Apps environment can communicate using their internal DNS names.
So the flow becomes:
.NET OrderService
│
│ HttpClient
│
│ "PaymentService"
▼
Azure Container Apps
│
│ Internal DNS
▼
Current PaymentService
│
├── Replica #2 ✓
├── Replica #3 ✓
└── Replica #4 ✓
Your .NET application still uses HttpClient.
The important change is the address you give it.
Instead of:
http://10.20.4.17
you use the appropriate stable internal service name.
Now Azure can change the underlying replicas without forcing your application to know about those changes.
What is responsible for what?
.NET
│
└── HttpClient
│
│ "Call PaymentService"
▼
Azure Container Apps
│
└── Internal DNS / service discovery
│
▼
Current PaymentService instance
You don't need to build your own registry of container IP addresses.
The Azure platform handles the service-to-endpoint resolution.
5. Visualize It in Everyday Terms
Imagine you want to call a business.
You write down its phone number:
Green Store 9876543210
A year later, the store changes its number.
You keep calling the old number.
The store still exists.
Your information is stale.
Instead, you remember the business name:
Green Store
and look up its current phone number when you need to call.
That's essentially what service discovery does.
Everyday world .NET + Azure Business name → Service name Phone number → Service endpoint Current lookup → Service discovery / DNS Business moves → Container replica changes
You don't care where the business is today.
You care about which business you want to reach.
6. What Should You Remember?
When your .NET services run in a dynamic Azure environment:
Don't depend on a container instance's IP address.
Depend on the service's stable name.
Let Azure resolve that name to the service's current endpoint.
The mental model is:
Stable Service Name
↓
Azure Internal DNS
↓
Current Service Replica
The replica can disappear.
Your service identity shouldn't.