Always use --output tsv when storing an az CLI value in a variable
To explain why to use the --output tsv, assume the example of assigning a role to a web app’s managed identity which fails with an error Cannot find user or service principal in graph database which looks like a permissions problem. The identity exists and the role name is right.
So what is the problem here?
The error
In the following az commands, I first capture the principal ID into a variable, then use it in a role assignment for a Cosmos DB:
principalId=$(az webapp identity assign \
--resource-group <resource-group> \
--name <web-app-name> \
--query principalId)
az role assignment create \
--assignee $principalId \
--scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>" \
--role "Cosmos DB Account Reader Role"
The error thrown is:
Cannot find user or service principal in graph database for '"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"'.
The quoting is what matters in the ID-value '"aaaaaaaa-..."'. The single quotes belong to the error message, the double quotes inside them are part of the value. The CLI looked up a principal whose ID starts with a " character, and no such principal exists.
Why it happens
The Azure CLI defaults to json output. A query that returns a single string returns a quoted JSON string.
Command substitution does not strip those quotes — to the shell they are ordinary characters in the output. The variable ends up holding 38 characters instead of a GUID’s 36.
The fix
Ask for TSV output:
principalId=$(az webapp identity assign \
--resource-group <resource-group> \
--name <web-app-name> \
--query principalId \
--output tsv)
The role assignment then goes through with no error.