I am building a multi container app, deployed on Azure App services with 'docker compose',assigned an identity (user assigned managed identity) and gave RBAC to principal Id to access the cosmos container with the following command
az cosmosdb sql role assignment create -a cosmos-nosql-db -g rish90-rg-westus -s "/" -p actual_principal_id -d 00000000-0000-0000-0000-000000000002
Multi container app consists of three containers nginx proxy, nginx http web server and .NET based backend server. It's the backend server which talks to CosmosDB with DefaultAzureCredential.
But with multi container app, the cosmos db is not accessible. I get error Azure.Identity.CredentialUnavailableException: DefaultAzureCredential failed to retrieve a token from the included credentials.
BUT if I deploy a backend as single container azure app service; and enable Managed identity and respective RBAC, the backend is able to access cosmos;
Here is the link to Github repo of same.
I am not able to understand what is the problem here and how can it be fixed?
here is a design of what the system looks like
I don't think multi-container app using docker compose
file supports Managed identity to connect currently, as it is currently in preview. I would suggest to use connection string
for connection for work around.
Using connection string worked for me.
I used connection string for client.
docker-compose.yml
:
version: '3.3'
services:
proxy:
image: vivek.azurecr.io/proxy
ports:
- "80:80"
container_name: proxy
frontend:
image: vivek.azurecr.io/frontend
ports:
- "80"
depends_on:
- backend
container_name: frontend
backend:
image: vivek.azurecr.io/backend
ports:
- "3000"
container_name: backend
TodoListDbClient.cs
:
using System.Net.Http.Headers;
using Azure.Identity;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Linq;
using TodoApi;
public class TodoListDbClient : IDbClient
{
private readonly Container _todoListContainer;
public TodoListDbClient()
{
var cosmosClientOptions = new CosmosClientOptions {
};
var cosmosClient = new CosmosClient("AccountEndpoint=https://multicontainer-web-app-db.documents.azure.com:443/;AccountKey=xxxxxxxxxxxxxxxxxxxxx;");
_todoListContainer = cosmosClient.GetDatabase("ToDoList").GetContainer("Items");
}
public async Task<ItemResponse<Todo>> AddAsync(Todo todoItem)
{
return await _todoListContainer.CreateItemAsync<Todo>(todoItem);
}
public async Task<List<Todo>> GetAllAsync()
{
var queryable = _todoListContainer.GetItemLinqQueryable<Todo>();
var feed = queryable.Where(p => p.id != null).ToFeedIterator();
List<Todo> todos = [];
while (feed.HasMoreResults)
{ //pagination response
var response = await feed.ReadNextAsync();
foreach (var item in response)
{
todos.Add(item);
}
}
return todos;
}
}
OUTPUT