When doing automated deployments to Azure, I found that I was missing a single approach for authentication when used both in a release pipeline, and when doing ad hoc testing during development.
I needed something that let me use an Azure Service Principal for automated processes, as well as using my private credentials for other usages.
After many iterations, I think I have something that is worthwhile sharing with others, in the form of simple templates that gives you a kick-start to any Azure project!
For the sake of completeness, I have included code for authenticating to Azure using bash (for those of you that are working in a Linux environment), PowerShell (both using the Azure PowerShell module and Azure CLI v2 for Windows) and even DOS batch format (for those of you who are really old-school and on Windows).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
SP_NAME=$1 | |
SP_PW=$2 | |
SP_TENANT=$3 | |
# Authenticate to Azure | |
if [ -z "$SP_NAME" ] || [ -z "$SP_PW" ] || [ -z "$SP_TENANT" ] | |
then | |
LOGIN_RESULT=$(az login) | |
else | |
LOGIN_RESULT=$(az login –username $SP_NAME –password $SP_PW –tenant $SP_TENANT –service-principal 2> /dev/null) | |
fi | |
if [ -z "$LOGIN_RESULT" ] | |
then | |
echo "Failed to authenticate to Azure!" | |
else | |
echo "Authenticated to Azure" | |
fi | |
# YOUR CODE GOES HERE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[System.Diagnostics.CodeAnalysis.SuppressMessage('AvoidUsingPlainTextForPassword', '', Target='ProcessParameter')] | |
[CmdletBinding()] | |
param ( | |
[Parameter()] | |
[Alias('SPName','Username','un')] | |
[string] $ServicePrincipalName, | |
[Parameter()] | |
[Alias('SPPassword','Password','pw')] | |
[string] $ServicePrincipalPassword, | |
[Parameter()] | |
[Alias('id')] | |
[string] $TenantId | |
) | |
try { | |
#region Azure Authentication | |
if ((-not $ServicePrincipalName) -or (-not $ServicePrincipalPassword) -or (-not $TenantId)) { | |
Write-Verbose 'Authenticating using interactive login' | |
$loginResult = az login | |
} | |
else { | |
Write-Verbose 'Authenticating with Username and Password' | |
$loginResult = az login —username $ServicePrincipalName —password $ServicePrincipalPassword —tenant $TenantId —service–principal | |
} | |
if ($loginResult) { | |
Write-Output $loginResult | ConvertFrom-Json | |
} | |
#endregion | |
# YOUR CODE GOES HERE | |
} | |
catch { | |
Write-Warning $_.Exception.Message | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[CmdletBinding(DefaultParameterSetName = 'Credential')] | |
param ( | |
[Parameter(ParameterSetName = 'Credential')] | |
[System.Management.Automation.PSCredential] $Credential, | |
[Parameter(ParameterSetName = 'ClearText')] | |
[string] $ApplicationId, | |
[Parameter(ParameterSetName = 'ClearText')] | |
[string] $Password, | |
[Parameter(ParameterSetName = 'Credential')] | |
[Parameter(ParameterSetName = 'ClearText')] | |
[string] $TenantId | |
) | |
try { | |
#region Azure Authentication | |
# If credential object is supplied we are set to go | |
if ($PSCmdlet.MyInvocation.BoundParameters['Credential']) { | |
Write-Verbose 'Using supplied credentials to authenticate.' | |
} | |
# If ApplicationID and Password are supplied, use these to create a credential object | |
elseif ($ApplicationId -and $Password) { | |
Write-Verbose 'Using supplied ApplicationID and Password to authenticate' | |
$Credential = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList ($ApplicationId, (ConvertTo-SecureString $Password –AsPlainText –Force)) | |
} | |
# Else use interactive login | |
else { | |
Write-Verbose 'Using interactive login to authenticate.' | |
$Credential = $null | |
} | |
# Run Azure Login | |
if ($Credential) { | |
# Ask for Tenant ID if not supplied | |
if (-not ($TenantId)) { | |
$TenantId = Read-Host –Prompt 'Please enter Azure Tenant ID' | |
} | |
Login–AzureRmAccount –ServicePrincipal –Credential $Credential –TenantId $TenantId –ErrorAction Stop | |
} | |
else { | |
Login–AzureRmAccount –ErrorAction Stop | |
} | |
#endregion | |
# YOUR CODE GOES HERE | |
} | |
catch { | |
Write-Warning $_.Exception.Message | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
IF [%1]==[] ( | |
IF [%2]==[] ( | |
IF [%3]==[] ( | |
az login | |
) | |
) | |
) ELSE ( | |
az login –username %1 –password %2 –tenant %3 –service-principal | |
) | |
REM YOUR CODE GOES HERE |
As you see from the code, the two PowerShell templates are the most fleshed out, since PowerShell is what I normally use. In the future I might expand on the bash one, and I also want to do a Python template at one point. In either case, I’ll update this post with the additional code.
Using these should be quite evident, but if you have any questions don’t hesitate to contact me.