Publish an Azure RM Web App using a Service Principal in PowerShell

Introduction

Deploying an Azure Web App is almost stupidly simple. If I were to list the methods and tools I’d still be typing next week. The problem with many of these tools and process is that they do a whole lot of magic under the hood which makes the process difficult to manage in source control.

I’m a big believer that all code (including deployment code) should be in the application source repository so it can be run by any tool or release pipeline – including manually by development teams. This ensures that whatever deployment process is used, it is the same no matter who or what runs it – and we end up continuously testing the deployment code and process.

So I decided to go and find out how to deploy an Azure Web App using PowerShell using an Service Principal.

Where is Publish-AzureRMWebsiteProject?

If you look through the Azure PowerShell cmdlets you’ll find a service manager one called Publish-AzureWebsiteProject. This cmdlet looks like it should do the trick, but it isn’t suitable because it requires authentication by a user account instead of a service principal.

Only service principal accounts can be authenticated using automation. Therefore using Publish-AzureWebsiteProject would only work if a development team member was able to interactively login– which would prevent the same process being used for automation or our continuous delivery pipeline. The newer Azure Resource Manager cmdlets (*-AzureRM*) all support a login using a service principal, but the problem is that there is no Publish-AzureRMWebsiteProject cmdlet.

So, to work around this limitation I determined I had to use Web Deploy/MSDeploy. The purpose of this post is to share the PowerShell function/code and process I used to do this. This will work with and without Web App deployment slots.

Note: in my case our teams put all deployment code into a PowerShell PSake task in the application source code repository to make it trivial for anyone to run the deployment. The continuous delivery pipeline was also able to call the exact same task to perform the deployment. There is no requirement to use PowerShell PSake – just a simple PowerShell script will do.

The Code

So, I’ll start by just pasting the function that does performs the task:

Just save this file as Publish-AzureRMWebappProject.ps1 and you’re ready to start publishing (almost).

Before you can use this function you’ll need to get a few things sorted:

  1. Create a Service Principal with a password to use to deploy the web app using the instructions on this page.
  2. Make sure you have got the latest version of the Azure PowerShell Modules installed (I used v4.0.0). See this page for instructions.
  3. Make sure you’ve got MSDeploy.exe installed on your computer – see this page for instructions. You can pass the path to MSDeploy.exe into the Publish-AzureRMWebappProject.ps1 using the MSDeployPath parameter.
  4. Gather the following things (there are many ways of doing that – but I’ll leave it up to you to figure out what works for you):
    1. the Subscription Id of the subscription you’ll be deploying to.
    2. the Tenant Id of the Azure Active Directory containing your Service Principal.
    3. the Application Id that was displayed to you when you created the Service Principal.
    4. the Password you assigned when you created the Service Principal.

Once you have got all this information you can call the script above like this:

Note: You’ll need to make sure to replace the variables $SubscriptionId, $TenantId, $Password and $Username with the values for your Azure Subscription, Tenancy and Service Principal.

When everything is done correctly this is what happens when you run it (with -Verbose enabled):

ss_webappdeploy_publishazurermwebappproject

Note: in the case above I was installing to a deployment staging slot called offline, so the new version of my website wouldn’t have been visible in my production slot until I called the Swap-AzureRmWebAppSlot cmdlet to swap the offline slot with my production slot.

All in all, this is fairly robust and allows our development teams and our automation and continuous delivery pipeline to all use the exact same deployment code which reduces deployment failures.

If you’re interested in more details about the code/process, please feel free to ask questions.

Thanks for reading.

Using Azure Key Vault with PowerShell – Part 1

Azure Key Vault is used to safeguard and manage cryptographic keys, certificates and secrets used by cloud applications and services (you can still consume these on-premise though). This allows other application, services or users in an Azure subscription to store and retrieve these cryptographic keyscertificates and secrets.

Once cryptographic keys, certificates and secrets have been stored in a Azure Key Vault access policies can be configured to provide access to them by other users or applications.

Azure Key Vault also stores all past versions of a cryptographic key, certificate or secret when they are updated. So this allows easily rolling back if anything breaks.

This post is going to show how:

  1. Set up an Azure Key Vault using the PowerShell Azure Module.
  2. Set administration access policies on the Azure Key Vault.
  3. Grant other users or applications access to cryptographic keyscertificates or secrets.
  4. Add, retrieve and remove a cryptographic key from the Azure Key Vault.
  5. Add, retrieve and remove a secret from the Azure Key Vault.

Requirements

Before getting started there is a few things that will be needed:

  1. An Azure account. I’m sure you’ve already got one, but if not create a free one here.
  2. The Azure PowerShell module needs to be installed. Click here for instructions on how install it.

Install the Key Vault

The first task is to customize and install the Azure Key Vault using the following PowerShell script.

But first, the variables in the PowerShell script need to be customized to suit. The variables in the PowerShell script that needs to be set are:

  • $subscriptionName – the name of the Azure subscription to install the Key Vault into.
  • $resourceGroupName – the name of the Resource Group to create to contain the Key Vault.
  • $keyVaultName – the name of the Key Vault to create.
  • $location – the Azure data center to install the Key Vault to (use Get-AzureRMLocation to get a list of available Azure data centers).
  • $keyVaultAdminUsers – an array of users that will be given administrator (full control over cryptographic keys, certificates and secrets). The user names specified must match the full name of users found in the Azure AD assigned to the Azure tenancy.

ss_akv_create

It will take about 30 seconds for the Azure Key Vault to be installed. It will then show up in the Azure Subscription:

ss_akv_createcompleteportal

Assigning Permissions

Once the Azure Key Vault is setup and an administrator or two have been assigned, other access policies will usually need to be assigned to users and/or application or service principal.

To create an access policy to allow a user to get and list cryptographic keys, certificates and secrets if you know the User Principal Name:

Note: the above code assumes you still have the variables set from the ‘Install the Key Vault’ section.

If you only have the full name of the user then you’ll need to look up the Object Id for the user in the Azure AD:

Note: the above code assumes you still have the variables set from the ‘Install the Key Vault’ section.

To create an access policy to allow a service principal or application to get and list cryptographic keys if you know the Application Id (a GUID):

Note: the above code assumes you still have the variables set from the ‘Install the Key Vault’ section.

Changing the values of the PermissionsToKeys, PermissionsToCertificates and PermissionsToSecrets parameters in the cmdlets above allow different permissions to be set for each policy.

The available permissions for certificates, keys and secrets are:

An access policy can be removed from users or service principals using the Remove-AzureRmKeyVaultAccessPolicy cmdet:

Note: the above code assumes you still have the variables set from the ‘Install the Key Vault’ section.

Working with Secrets

Secrets can be created, updated, retrieved and deleted by users or applications that have been assigned with the appropriate policy.

Creating/Updating Secrets

To create a new secret, use the Set-AzureKeyVaultSecret cmdlet:

Note: the above code assumes you still have the variables set from the ‘Install the Key Vault’ section.

This will create a secret called MyAdminPassword with the value P@ssword!1 in the Azure Key Vault.

The secret can be updated to a new value using the same cmdlet:

Additional parameters can also be assigned to each version of a secret to control how it can be used:

  • ContentType – the type of content the secret contains (e.g. ‘txt’)
  • NotBefore – the date that the secret is valid after.
  • Expires – the date the secret is valid until.
  • Disable – marks the secret as disabled.
  • Tag – assigns tags to the secret.

For example:

ss_akv_secretupdatewithparameters

Retrieving Secrets

To retrieve the latest (current) version of a secret, use the Get-AzureKeyVaultSecret cmdlet:

This will assign the stored secret to the variable $secretText as a SecureString. This can then be passed to any other cmdlets that require a SecureString.

To list all the versions of a secret, add the IncludeVersions parameter:

ss_akv_secretallhistory

To retrieve a specific version of a secret, use the Get-AzureKeyVaultSecret cmdlet with the Version parameter specified:

Removing Secrets

Finally, to remove a secret use the Remove-AzureKeyVaultSecret cmdlet:

That pretty much covers managing and using secrets in Azure Key Vault using PowerShell.

Cryptographic keys and Certificates

In the next part of this series I’ll cover using Azure Key Vault to use and manage cryptographic keys and certificates. Thanks for sticking with me this far.