Moving Azure credentials to Docker - azure

I have a Docker volume from ${USERPROFILE}/.azure to /root/.azure:rw. In my Dockerfile, I'm installing az-cli and then using DefaultAzureCredentials class in .NET (https://learn.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet) to load the credentials.
It worked fine until a month ago, I had to az login on my machine and then it worked fine in Docker. However, about a month ago, when az-cli switched from ADAL to MSAL, it throws an exception saying I'm not logged in.
My guess is that az-cli stores the tokens somewhere else now, other than the .azure directory, or something else, I'm not sure. Anyone has any idea?

Earlier, Azure CLI save ADAL tokens and service principal entries to ~/.azure/accessToken.json
Later when Azure CLI use MSAL, it no longer generate accessTokens.json file.
Any existing workflow depending on accessTokens.json no longer works
So instead of DefaultAzureCredentials class, you can use AzureCliCredential class
AzureCliCredential class uses subprocess to call az account get-access-token to get an access token for the current logged-in account
Reference: MSAL-based Azure CLI | Microsoft Docs

For now you can use a pre-2.30 az-cli version both on your host system and inside your container. Instructions are here to install a specific version: https://learn.microsoft.com/en-us/cli/azure/install-azure-cli

Related

Use DefaultAzureCredentials to authenticate Service bus in Docker Container

I'm trying to use DefaultAzureCredentials to authenticate my Azure function against Azure Service Bus. In my azure function azure-func-service-bus, I call to Azure Service Bus
servicebus_client = ServiceBusClient(
fully_qualified_namespace=MY_SERVICE_BUS_NAMESPACE_NAME+".servicebus.windows.net",
credential=DefaultAzureCredential(additionally_allowed_tenants=['*'])
)
I created and pushed Docker container to ACR. When I run the container locally for testing outside of Azure, it does not know what permissions to use.
az acr login --name acr01
docker push acr01.azurecr.io/azure-func-service-bus:v1
docker pull acr01.azurecr.io/azure-func-service-bus:v1
docker run -it --rm -p 8080:80 acr01.azurecr.io/azure-func-service-bus:v1
but got the following error.
DefaultAzureCredential failed to retrieve a token from the included credentials.
Attempted credentials:
EnvironmentCredential: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
Visit https://aka.ms/azsdk/python/identity/environmentcredential/troubleshoot to troubleshoot.this issue.
ManagedIdentityCredential: ManagedIdentityCredential authentication unavailable, no response from the IMDS endpoint.
SharedTokenCacheCredential: SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.
VisualStudioCodeCredential: Failed to get Azure user details from Visual Studio Code.
AzureCliCredential: Azure CLI not found on path
AzurePowerShellCredential: PowerShell is not installed
To mitigate this issue, please refer to the troubleshooting guidelines here at https://aka.ms/azsdk/python/identity/defaultazurecredential/troubleshoot.
Unexpected error occurred (ClientAuthenticationError('DefaultAzureCredential failed to retrieve a token from the included credentials.\nAttempted credentials:\n\tEnvironmentCredential: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.\nVisit https://aka.ms/azsdk/python/identity/environmentcredential/troubleshoot to troubleshoot.this issue.\n\tManagedIdentityCredential: ManagedIdentityCredential authentication unavailable, no response from the IMDS endpoint.\n\tSharedTokenCacheCredential: SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.\n\tVisualStudioCodeCredential: Failed to get Azure user details from Visual Studio Code.\n\tAzureCliCredential: Azure CLI not found on path\n\tAzurePowerShellCredential: PowerShell is not installed\nTo mitigate this issue, please refer to the troubleshooting guidelines here at https://aka.ms/azsdk/python/identity/defaultazurecredential/troubleshoot.')). Handler shutting down.
I'm missing a key piece of the puzzle. How can I handle this?
When the Azure Function runs in Azure, it's configured to support ManagedIdentityCredential. For your case I'd recommend trying to configure EnvironmentCredential to test locally.
You can find the details in the link, but the short version is:
Create a service principle (Docs) and give it the needed access
Run the container with extra Environment Variables:
AZURE_TENANT_ID: service principal's Tenant ID
AZURE_CLIENT_ID: service principal's AppId
AZURE_CLIENT_SECRET: service principle's password
I'd recommend using a .env file to make this easier, but be sure it doesn't get checked in anywhere.
FYI If your account doesn't use MFA, you can instead use the variables AZURE_USERNAME and AZURE_PASSWORD. But then you've put your username and password in a file or your terminal history which is concerning. Admittedly the service principal has the same problem, but you can more easily mitigate that with minimizing it's access and regularly rolling the secret.
P.S. If you're using Visual Studio for making your Azure Function you should be able to use something like: EnvironmentCredentialExample to automate setting up and using the needed .env file.

How to work with multiple Azure accounts with Azure CLI? [duplicate]

We actually have multiple azure accounts (for some valid reason) and I want to be able to run azure-cli commands for different accounts at the same time from the same machine.
The problem with that is, once I login to one azure account with azure login, token will be stored in ~/.azure directory so I am not sure if I can login into another account exactly at the same time on that machine.
Is there any way to tell azure-cli not to store token in local profile so that I can use azure-cli to connect to multiple accounts at the same time from same machine?
If you are using a windows or mac machine then the tokens are stored in Windows token manager or OSx key chain respectively. Only on Linux systems the tokens are stored in ~/.azure/azureProfile.json
However, you should still be able to login with multiple accounts on Win/Mac or Linux machines.
azure account set "subscription-name" will set the subscription as your default subscription and all the commands that you execute will run against that subscription.
Every command has a -s or --subscription switch where you can explicitly specify the subscription id. Even if the subscription belongs to a different account, it should still work if you have authenticated with that account.
For Linux system, I would suggest to create multiple user accounts and then run the CLI from those accounts. I think there could be a race condition when two commands from different accounts try to access ~/.azure/azureProfile.json.
The latest update is that the environment variable AZURE_CONFIG_DIR has been introduced and that can be set differently for each environment before az login is called.
export AZURE_CONFIG_DIR=/tmp1
az login
and on other window
export AZURE_CONFIG_DIR=/tmp2
az login
Reference: configure the AZURE_CONFIG_DIR for fixing concurrency issue
For Windows, here are steps
Go to env variables and add AZURE_CONFIG_DIR with the value of new config folder (e.x. C:\Users\YourUser\.azure-personal)
restart your cli, then run this az login --use-device-code
use the code given on step 2 and use it with whatever browser to login to new azure account
Now, one of your accounts config is in default azure folder config (C:\Users\YourUser\.azure) and new one lives in the place you specified on step 1.
if you wanna switch between them, you need to flip that env variable to point to whatever config you want

AZ CLI login using Service Principal fails from specific computer

I have posted previously about az login using a Service Principal failing with the error No subscriptions found and I have run across others that have had similar issues. Capability seems shaky for some reason. What I am seeing now that has me scratching my head is when I run a script I have that does an az login with a service principal from my desktop computer it works fine...no issues. When I run the same script from my laptop, the login fails with the No subscriptions found error. What I have tried on the laptop:
Checked AZ CLI version...same as desktop
Ran az account clear to make sure everything was cleared out
Deleted Service Principal from AAD and recreated from laptop
I even ran az account clear on my desktop to make sure it was not working simply because it was cached and even after the clear, the az login worked fine.
Any thoughts on what might be causing this?
You need to assign a Role to the Service Principle, or add the flag --allow-no-subscriptions.
I have posted resolution for this under following thread.
https://stackoverflow.com/a/66108965/1712969
you might want to try command with this flag "--allow-no-subscriptions"

Interactive login is required. Use 'azure login' to interactively login

Trying to run Kubernetes on Azure, I'm stuck on ./azure-login.js -u <your_username>.
I'm getting the following:
[aii#localhost azure]$ ./azure-login.js -u aii#aii_domain.com
info: Executing command login
Password: ********
+ Authenticating...
error: Interactive login is required. Use 'azure login' to interactively login.
info: Error information has been recorded to /home/aii/.azure/azure.err
error: login command failed
More info:
[aii#localhost azure]$ azure --version
0.10.0 (node: 4.3.1)
BTW, my account is BizSpark Plus if it matter..
Add the following commands first:
azure account download
it will guide you to download .publishsettings file from browser which you should use for:
azure account import <downloaded file>
azure account set <"name of your subscription">
Azure login only works from a work or school id, which really means an AAD object (identity). If you have a Microsoft account, you can only "connect" with the azure account import command that takes a .publishsettings file that you have to download. (it's a cert file)
This is actually a feature of Azure, although I think we don't communicate well here. Turns out that everyone has a default Azure Active Directory domain that they get for free.
At a larger level, Azure has two management APIs:
1. Service management, which can be used with either work ids or Microsoft account ids, and
2. Resource management, which is the new stuff and can be used only with work or school ids, and that works only with the azure login functionality.

Can I access multiple azure accounts with azure-cli from the same machine at same time?

We actually have multiple azure accounts (for some valid reason) and I want to be able to run azure-cli commands for different accounts at the same time from the same machine.
The problem with that is, once I login to one azure account with azure login, token will be stored in ~/.azure directory so I am not sure if I can login into another account exactly at the same time on that machine.
Is there any way to tell azure-cli not to store token in local profile so that I can use azure-cli to connect to multiple accounts at the same time from same machine?
If you are using a windows or mac machine then the tokens are stored in Windows token manager or OSx key chain respectively. Only on Linux systems the tokens are stored in ~/.azure/azureProfile.json
However, you should still be able to login with multiple accounts on Win/Mac or Linux machines.
azure account set "subscription-name" will set the subscription as your default subscription and all the commands that you execute will run against that subscription.
Every command has a -s or --subscription switch where you can explicitly specify the subscription id. Even if the subscription belongs to a different account, it should still work if you have authenticated with that account.
For Linux system, I would suggest to create multiple user accounts and then run the CLI from those accounts. I think there could be a race condition when two commands from different accounts try to access ~/.azure/azureProfile.json.
The latest update is that the environment variable AZURE_CONFIG_DIR has been introduced and that can be set differently for each environment before az login is called.
export AZURE_CONFIG_DIR=/tmp1
az login
and on other window
export AZURE_CONFIG_DIR=/tmp2
az login
Reference: configure the AZURE_CONFIG_DIR for fixing concurrency issue
For Windows, here are steps
Go to env variables and add AZURE_CONFIG_DIR with the value of new config folder (e.x. C:\Users\YourUser\.azure-personal)
restart your cli, then run this az login --use-device-code
use the code given on step 2 and use it with whatever browser to login to new azure account
Now, one of your accounts config is in default azure folder config (C:\Users\YourUser\.azure) and new one lives in the place you specified on step 1.
if you wanna switch between them, you need to flip that env variable to point to whatever config you want

Resources