This simple containerized application acts as a proxy, allowing other containerized applications to access Azure developer credentials without installing Azure CLI on each individual container. It is designed for use in local development environments only.
Add workleap/azure-cli-credentials-proxy:latest
to your docker-compose.yml
and mount your Linux or WSL ~/.azure/
directory:
version: "3"
services:
azclicredsproxy:
image: workleap/azure-cli-credentials-proxy:latest
volumes:
- "\\\\wsl$\\<DISTRONAME>\\home\\<USERNAME>\\.azure\\:/app/.azure/" # On Windows with WSL
- "/home/<USERNAME>/.azure:/app/.azure/" # On Linux
Finally, add two environment variables to your containerized applications that use DefaultAzureCredential
or ManagedIdentityCredential
:
version: "3"
services:
# azclicredsproxy: [...]
myservice:
build: .
depends_on:
- azclicredsproxy
environment:
- "IDENTITY_ENDPOINT=http://azclicredsproxy:8080/token"
- "IMDS_ENDPOINT=dummy_required_value"
When developers run services on their operating system, they use their personal Azure identity (username@company.com
) to access protected Azure resources, thanks to Azure CLI. The az login
command caches Azure personal credentials in a local ~/.azure/
directory, which is then used by DefaultAzureCredential
- specifically AzureCliCredential
, a part of the former.
When these services run in Azure cloud (App Service, AKS, etc.), protected Azure resources are typically accessed using ManagedIdentityCredential
, which uses a service principal-based Azure identity authentication mechanism also included in DefaultAzureCredential
.
However, when developers attempt to run these same services in Docker locally, the Docker images do not include Azure CLI. These images also lack access to a service principal. While Dockerfiles can be modified to install Azure CLI, and containers can mount the local ~/.azure/
directory, there are several disadvantages:
- Azure CLI is not suitable for production as an authentication mechanism
- Azure CLI adds a significant 1GB to the Docker image
Despite these issues, developers often use their personal Azure identity in local Docker containers. A GitHub issue created in March 2021 remains open.
Instead of installing Azure CLI in each service, we can run another container - a proxy, which is the only one that contains Azure CLI and a mount on ~/.azure/
. This container exposes a single endpoint that returns the Azure developer credentials retrieved with Azure CLI.
Then, we must add two environment variables to each service:
IDENTITY_ENDPOINT
: the URL of the proxy endpoint (e.g.,http://azclicredsproxy:8080/token
)IMDS_ENDPOINT
: an arbitrary but mandatory value (e.g.,random-placeholder
)
With these two environment variables, any service that uses DefaultAzureCredential
or ManagedIdentityCredential
will now call the proxy when Azure credentials are needed. This is because one of ManagedIdentityCredential
's source implementations explicitly looks for both of these environment variables if they are specified.
With this proxy, Dockerfiles can remain untouched and production-ready. The proxy can easily be added to an existing docker-compose.yml
, and the environment variables are also easy to add. Now, the containerized environment looks like this:
Keep in mind that you cannot mount a Windows-based ~/.azure/
credentials directory to a Linux container. On Windows, the credentials file cache is a binary file encrypted with DPAPI. On Linux, DPAPI is not supported and the file is not encrypted.
The solution is to use az login
on your WSL distribution and mount \\wsl$\Ubuntu\home\<WSLUSERNAME>\.azure\
instead of %USERPROFILE%\.azure\
.
Copyright © 2023, Workleap Inc.. This code is licensed under the Apache License, Version 2.0. You may obtain a copy of this license at https://github.com/gsoft-inc/gsoft-license/blob/master/LICENSE.