Azure – Linux VM Image Creation – Powershell – With Service Principal/Account


I was working on creating generalized VM images for use with scale sets and auto-scaling and I found it rather painful to get the complete set of examples for:

  1. De-provision user/etc from VM.
  2. Use Azure Powershell with a Service principal.
  3. Generalize the VM and create an image.

So, here’s a short mostly-code post on how to do that.

Specific Steps

Fair warning… as far as I know, you can’t use the VM after doing this… but you can create a new copy of it from the image, so that doesn’t matter much.

Before getting to Powershell, run this in your VM to de-provision the most recently set up user account (e.g. I’ll install everything on user “john” created with the Azure VM).  This will remove that user.

sudo waagent -deprovision+user

Now, just run the below command after setting your own values for the 5 variables up top.  This will log in to the RM with the credentials you provide in the pop-up, and then it will stop and generalize the VM, adn tehn create an image from it and store that image in the same resource group as the VM.

$vmName = "YOUR_VM_NAME"
$rgName = "YOUR_RG_NAME"
$location = "YOUR_REGION"
$imageName = "YOUR_IMAGE_NAME"
$tenant = "YOUR_TENANT_ID"

$c = Get-Credential # Input your service principal client-id/secret.
Connect-AzureRmAccount -Credential $c -ServicePrincipal -Tenant $tenant

Stop-AzureRmVM -ResourceGroupName $rgName -Name $vmName -Force
Set-AzureRmVm -ResourceGroupName $rgName -Name $vmName -Generalized
$vm = Get-AzureRmVM -Name $vmName -ResourceGroupName $rgName
$image = New-AzureRmImageConfig -Location $location -SourceVirtualMachineId $vm.Id
New-AzureRmImage -Image $image -ImageName $imageName -ResourceGroupName $rgName

Configuration Trouble?

  • If you’re not sure what a service account / principal is or how to create one, the process is quite involved and I highly recommend following one of the many Microsoft-provided tutorials.
  • You can find your tenant ID by clicking the directory + subscription button at the top of the portal OR by hovering over your name/info at the top right corner.
  • The region strings can be tricky; but just Google the Microsoft site if you’re not sure.  A US East 2 example is “EastUS2”.

What’s Next?

Your VM image can now be found in that resource group – go to the portal and see.  You can go into the image in the portal and create a new VM from it, or you can use it to boot up a scale set, etc.

Azure Key Vault Usage

If you want to store passwords or certificates securely and have them separated from your application code, then Azure Key Vaults are a wonderful option.

You can even set up key vaults so that you can access them without providing a client ID, etc. which makes them ultra secure as you don’t have to provide your credentials in your code or config files.

Creating a Key Vault

To set up a key vault, you just:

  • Go to All Services in the portal.
  • Search for Key Vault.
  • Click create and then provide a name, resource group, and region.
    • Remember, all of your resources in Azure have to go into a resource group so they are logically identified and manageable.

Assigning Users

When you’re programmatically accessing resources in Azure, you always need a service principal.  You can get this by creating an azure App Registration.   This is involved, and if you’re doing this you probably already have one.  If not though, you can refer to this Microsoft tutorial for creating a service principal.

Assuming you have the principal ready, go into your vault in the portal and click “Access Policies”.  In here, you can pick which things you need to manage from a template, then give your service principal name and create.

Remember, after you do this and it shows the created one on the summary page, you STILL have to click “Save” at the top.  If you don’t, it’s not really there.  When you’re done refresh the web page with F5 to make sure it’s really there.

Adding Secrets

Adding secrets/passwords is simple.  Just click “Secrets” and then the (+) sign and type in your name/value.

Querying Secrets From an Application

This is very language dependent.  Microsoft has great tutorials for every language though.  Here are two for Python and Java for example:

Managed Service Identity

Now, we still have one problem here.  The key vault holds all of our passwords which is great… but we need a service principal (with a password) to access the vault.  So, if we leave that in our code or config files, we’re no better off in reality.

The final step is to read up on Managed Service Identities which let you configure a machine to securely talk to a key vault without providing the principal information.  This way your code and deployment config is 100% free of any passwords/etc.