Non-interactive login in Azure CLI (Xplat-CLI)

By default, when we are logging in to Azure in Azure CLI:

azure login

we need to go through an interactive login process:

info:    Executing command login
|info:    To sign in, use a web browser to open the page https://aka.ms/devicelogin and enter the code XXXXXXXXX to authenticate.

It is not so hard if we are going to do some administrative stuff, but it is very awkward if we are scripting something (as example: in BASH).

Of course there is a solution for this issue. Azure AD Application and Service Principal.

The AD application is the global representation of your application. It contains the credentials (an application id and either a password or certificate). The service principal is the local representation of your application in an Active Directory. It contains the role assignment.

As first, we need to log in to our Azure Subscription (interacive login):

azure login

Next, we need to use Subscription we want (if we have more than one):

azure account set {subscriptionId}

To create the AD application and service principal in one step, we need to provide the name of the app and a password:

azure ad sp create -n exampleapp -p {your-password}

The new service principal is returned. The Object Id is needed when granting permissions. The guide listed with the Service Principal Names is needed when logging in. This guide is the same value as the app id. In the sample applications, this value is referred to as the Client ID.

info:    Executing command ad sp create
+ Creating application exampleapp
+ Creating service principal for application {ApplicationId}
data:    Object Id:               {ObjectId}
data:    Display Name:            exampleapp
data:    Service Principal Names:
data:                             {ApplicationId}
data:                             http://exampleapp
info:    ad sp create command OK

Now we need to grant the service principal permissions on our subscription. In this example, we add the service principal to the Contributor role, which grants permission to manage everything except access to resources. For other roles, see RBAC: Built-in roles. For the ServicePrincipalName parameter, we are providing the ObjectId used when creating the application. Before running this command, we must allow some time for the new service principal to propagate throughout Active Directory.

azure role assignment create --objectId {ObjectId} -o Reader -c /subscriptions/{subscriptionId}/

Whenever you sign in as a service principal, you need to provide the tenant id of the directory for your AD app. A tenant is an instance of Active Directory. To retrieve the tenant id for your currently authenticated subscription, use:

azure account show

Which returns:

info:    Executing command account show
data:    Name                        : BizSpark
data:    ID                          : {subscriptionId}
data:    State                       : Enabled
data:    Tenant ID                   : {TenantId}
data:    Is Default                  : true
data:    Environment                 : AzureCloud
data:    Has Certificate             : No
data:    Has Access Token            : Yes
data:    User name                   : {UserName}
data:    
info:    account show command OK

Log in as the service principal.

azure login -u {ApplicationId} --service-principal --tenant {TenantId} -p {password}

And we are logged in:

info:    Executing command login
-info:    Added subscription BizSpark
+
info:    login command OK

This post is based on Microsoft Azure Documentation pages (link) and was created to address the needs of scripting guys (search queries) :)

Edit for azure-cli v2.0:

az ad sp create-for-rbac -n "https://<yourapp-address>" --role contributor --scopes /subscriptions/<subscription-id>/resourceGroups/<rg-name>

Just replace , and with proper values. This command will output:

{
"appId": "<app-id>",
"displayName": "<display-name>",
"name": "https://<yourapp-address>",
"password": "<pass-key>",
"tenant": "<tenant>"
}