azuredockervirtual-machineazure-managed-identityazure-vm

Using Azure Managed Identity in a Docker container running on an Azure VM


I have a problem in which I cannot reach my company's Container registry via Azure Container Instances and Azure Container Apps, which has to do with VNET's and a private link to the company's registry, and the fact that dynamically launched containers can't be linked. Eventually I want to go to Kubernetes as a platform for my batch job workloads, but right now I have to find a quick solution that makes it able to have at least one container running, and maybe manually scale these when necessary (one is probably enough most of the times).

Right now, the way I am aiming to achieve this is by simply launching a VM (and maybe a couple more when necessary) and running a docker container on this VM with the (Python) application code.

Now I'm wondering if, and if yes how, the Docker container can use a (either system/user assigned) managed identity assigned to the VM. When assigned to an ACI container with a user managed identity assigned to it on startup, I could easily just have code like:

default_credential = DefaultAzureCredential()
q_client = QueueClient(
  credential=default_credential,
  queue_name='Queuename',
  accounrt_url='someurl'
)

and be able to access - for instance - this queue. No need to request any kind of token, no need to specify any kind of environment variable.

Now I doubt this will work in a docker container running in a VM with a user identity assigned to it, since the user identity is not really assigned directly to the docker container. Is there any way to still achieve this or is this a fools errand and should I just work with environment variables for now? I don't really like the idea of the latter, but I haven't found a way to use managed identities this particular way.


Solution

  • • Yes, there is a way through which you can use the managed identity assigned to the VM on the docker container deployed on it. Kindly follow the steps given below and you can surely use the managed identity assigned to the VM in the docker container: -

    a) Thus, to get an access token to authenticate a request to an Azure resource using a managed identity, you have to call a special URL: - https://169.254.169.254/metadata/identity/oauth2/token . Also, to ensure that the authentication token and regarding networking works in a container, you will have to use a tool which is intended to be run as Windows service on the container host and uses file-based communication to wait for requests by monitoring a folder. The container puts a request file in that folder, the service requests a token and responds to the container with a response file. The container can then use that token to authenticate against whatever Azure resource you need.

    b) To do the above, you will have to deploy a VM in Azure and connect to it through RDP, then execute the command below to start a container: -

    docker run -ti -v c:\miat-helper:c:\miat-helper mcr.microsoft.com/powershell:6.2.3-nanoserver-1809
    

    With the below command, you will get a PowerShell session inside of the container where you can use the ‘helper’ tool to get an access token.

    $access_token = Invoke-Expression "c:\miat-helper\bin\client.exe --folder c:\miat-helper --resource https://management.azure.com/"
    

    c) You can call an Azure API using that access token. Thus, to get more information about the VM generated, ensure to replace the resource group name and the virtual machine name with your values as below: -

     $vmInfo = (Invoke-WebRequest -Uri 'https://management.azure.com/subscriptions/ 94670b10-08d0-4d17-bcfe-e01f701be9ff/resourceGroups/<resource group name>/providers/Microsoft.Compute/ virtualMachines/<virtual machine name>?api-version=2017-12-01' -Method GET -ContentType "application/json" -Headers @{ Authorization ="Bearer $access_token"}).content
      Write-Host $vmInfo
    

    The above execution of commands should give you the necessary tools to cleanly handle authentication against Azure resources from a container. Also, then assign a managed identity to the VM during ARM template deployment and assign a role to that managed identity to allow read access to the VM. Once these things are done, you make a ‘GET’ request to the token endpoint from the VM and you get an access token. Then, the helper tool will run as a Windows service and is configured to listen on a particular folder post which the client creates a ‘.request’ file in that folder with the targeted resource as content.

    d) Then ‘helper’ service is notified through an event which reads the file and requests the token upon which the response file is created in the same class and writes the token to the file. The client then picks the response file, reads the token, and writes it to the standard output. In this way, we can think of anything better with the same very low amount of setup and high stability.

    For more detailed information on this, kindly refer to the link below: -

    https://tobiasfenster.io/using-azure-managed-identities-in-containers