If you want to do anything with Azure, the tools Microsoft provide for humans – Visual Studio and the Azure Portal – are great. Unfortunately, if you want to automate any of your Azure activity – for example, deploying applications – then things get a bit tricky. Some Azure commands are available as simple command-line tools (eg. MsDeploy), but the preferred (and sometimes only) way is to use Powershell and the Azure cmdlets. And
with Powershell comes a few tricky authentication issues.
A warning: what I’m about to demonstrate is an approach, possibly not the best approach. I’m still trying to figure this stuff out, and this may not be the most secure method of doing things.
So the problem is this: My real-world deployment pipeline currently has automated Azure deployments via msdeploy.exe (all sorts of hassles and risks with the authentication credentials and the scripts are ugly, but it works). But as we want to use deployment slots for “zero-downtime deployments” (ship to staging slot, instantly switch slots to live), we need a smarter mechanism than manually swapping slots via the Portal. Swapping deployment slots is a one-liner in Powershell (“Set-AzureWebsite -Slot”), but as a proof of concept, I’m just going to get my script to connect to my Azure account and bring back some info. Then we can do some real damage and actually deploy code…
Setting Up Azure Powershell
So you’ll need to install Powershell and the Azure cmdlets. I had to upgrade to Powershell 4 to get this to work (also, I needed to re-install Azure Powershell after upgrading Powershell).
Fire up Powershell (you may also have an “Azure Powershell” shortcut available).
Check your Powershell version with this command:
Get the web Platform Installer and use it to install Azure Powershell –
You can run a test Azure command, for example:
Doesn’t matter if you get an error about your credentials, at this point only worry if you’re getting instant errors about unrecognised commands because you haven’t installed everything.
The Manual Process
So you fire up an Azure Powershell console session, and start doing stuff. And of course, you have to supply authentication credentials. So do
and log in to your Microsoft account at the prompt. Once logged in, you can run some commands. To see your details:
To see all your webapps:
To “log out” – either:
Remove-AzureAccount -Name email@example.com
So all of this is great if you’re a human, not so good if you’re a robot, because “login prompts”. We need a better way to authenticate.
If you’ve used MsDeploy to ship to Azure through either Visual Studio or the msdeploy.exe, you’ll have used publish profiles. These are per-application files that Azure provide containing authentication details (go to the portal and download the publish profile for each web app). However, you can’t really use these with Azure cmdlets, they’re “per-application”, which is an issue if you want to do something like swap between staging and live slots (actually, two apps with two publish profiles).
Thankfully, there’s another “account” publish profile you can use. Go to your Powershell console, make sure you’re logged in, and do:
There’s probably also a link to download this file on the portal somewhere, but I’ve yet to see it. Anyway, you should get a simple XML file called “SubscriptionName-date-credentials.publishsettings”. Save this somewhere safe.
Now you can do
Import-AzurePublishSettingsFile [.publishsettings file path]
And this imports the certificate, essentially “logging you in” as the trusted deployment user specified in the publish settings. Go run some “Get-AzureSubscription” and “Get-AzureWebsite” calls.
Scripting Azure Activity
You just did Azure stuff without having to deal with login prompts. Great. Now you can script all that up.
Create a simple script (text file) called “Connect.ps1” that contains this:
param([string]$publishSettingsPath) #Connect to account Import-AzurePublishSettingsFile -PublishSettingsFile $publishSettingsPath #Show account status echo "run Get-AzureSubscription" Get-AzureSubscription echo "run Get-AzureAccount" Get-AzureAccount #List all websites echo "run Get-AzureWebsite" Get-AzureWebsite
You can run this from a standard command prompt, with this call:
powershell -File Connect.ps1 C:\pathTo\myAzure.publishsettings
(The script takes a publish settings file path as an argument).
Adding Azure Powershell to an Automated Build Process
If you can script your Azure activity – and we just did – then you can add that to a build process. As a quick test, I dumped that Connect.ps1 script into an existing project and created a simple Team City build config to run it, so whenever I commit project changes to Git, I can have Team City connect to Azure.
All I had to do was create a Team City build step with the following configuration.
Runner type: Powershell Powershell run mode: version 4 Script: file (with path to .ps1 relative to build agent checkout/working directory) Script execution mode: external file Script arguments: C:\pathTo\myAzure.publishsettings
Run this build and go look in the build logs, and you should see the script output, same as when you ran it from a command prompt.
For reference – Team City’s PowerShell arguments are [-Version, 4.0, -NonInteractive, -ExecutionPolicy, ByPass,
-File, \TeamCity\buildAgent\work\etc\PowershellScripts\Connect.ps1, \AzurePublishProfiles\my-
So we now have scripts accessing our Azure account and running commands without hitting login prompts. This allows for automated deployments to Azure, including all the activities that were previously only available when using the portal. However, there’s a few security issues that you’ll likely want to address.
Security Issues and “logging out”
The recommended advice seems to be to remove all accounts before importing the publish settings file, to prevent confusion over which Azure account is used by the Powershell session. Given that you’re logging in with a text file instead of a password, it’s good security practice to delete the publish settings file once you’ve set up access. However, Azure sessions have a tendency to time-out, so you probably can’t just do a one-time download of this file to set up a build machine then delete it – you’re going to need access to this file whenever you want to run an automated deployment (hence my adding the import command to the powershell script). I’m still working on this one – I suspect that Azure Resource Manager is ultimately the way to go.
Outstanding security issues:
- Where to keep the publish settings file? For security, source control would be a bad move, as would a network share. Probably storing a copy on the (locked down) build machine is best, but for a distributed build setup (eg. Team City with multiple agents) your build configuration needs to look in a consistent place on each agent. Getting around importing a publish settings file would be the ultimate aim.
- How to “log out” at the end of the session? Remove-AzureAccount seems to want an account name you don’t have, but it can apparently be “smart” about choosing the correct account to remove. Remove-AzureSubscription would work. Also, these commands don’t “remove” anything from your Azure account, they just kill the cached authentication credentials for your Powershell session.
- Can I rename the publish settings file? Yes. No complaints when I did just that.
- I’m paranoid. How do I revoke and reset my publishing credentials? Um, TBC. You might be able to use the “Reset deployment credentials” option in the portal.
Links for more info
I borrowed various bits of info from various sources.
Microsoft’s Azure cmdlet reference: https://msdn.microsoft.com/library/azure/jj554330.aspx
Resetting deployment credentials (in any webapp “publish your app” section): https://blogs.msdn.microsoft.com/kaushal/2013/05/29/windows-azure-web-sites-reset-your-deployment-credentials-vs-reset-your-publish-profile-credentials/
Cached credentials and removing accounts: http://itproguru.com/expert/2015/03/how-to-remove-azure-accounts-cached-credentials-from-powershell-remove-azureaccount-for-all-accounts-step-by-step/