SecretManagement and accessing Linux VMs in Azure

Hello folks,

A couple weeks ago I wrote about how I leveraged PowerShell SecretManagement to generalize a demo environment.  In that article I only talked about Windows running in Azure.  However, my colleague Thomas Maurer revisited the topic in his article,  Stop typing PowerShell credentials in demos using PowerShell SecretManagement.  Thomas really concentrated on how the local Secret Store can help when you have demos of local that need secrets, versus my article that concentrated more on how the SecretManagement module paired with the Az.KeyVault module can help manage not only demo environment but help manage local accounts across production environments.

In response to both these articles we got a lot of questions, so I decided to address one of them here.

Will it work for linux?

Absolutely, you can have PowerShell on , and import the modules mentioned in the articles. 

One of the differences that in most case we use SSH keys to access a VM running in Azure. And Azure has a couple ways of securely storing that information.  When creating a you can generate one at deployment, upload your own, or use an existing one already in azure. 


When using “Use existing one stored in Azure” it refers to a separate repo in azure different than Azure Key Vault.  It actually saves the key in a portal service SSK Keys.


The SSH Keys portal service give you the ability to download the public key so you can connect to the appropriate VMs. 


In one of the production environment that I'm currently involved with. We do not allow public IP assigned to VMs without a proper business case.  I actually agree with this policy since it limits the number of attack vectors.  So, we use Azure Bastion.  Connecting  using Azure Bastion offers the possibility to use one of several ways to to the VMs. 

  • Password
  • SSH Private Key
  • SSH Private Key from Local File
  • SSH Private Key from Azure Key Vault

Using Azure Key Vault to securely store your keys and secrets allows you to manage the SSH keys by setting expiration dates, apply proper versioning, assign tags AND have them available to the Azure Bastion with the option of requesting the Passphrase.


Just like my previous article.  In order to manage these keys, you can schedule an Azure task, or an Azure Function to monitor the expiration dates and renewregenerate the SSH Keys for you when appropriate.  As a proof-of-concept I used the same Azure Account as my last article with a new runbook to create the SSH keys for my environment and store them in Azure Key Vault


    [string]$ResourceGroupName = "Secret-Demo",
    [string]$vaultname = "SecretDemoVault"

Disable-AzContextAutosave -Scope Process

$VERSION = "1.0"
$SecretStoreName = "AzKeyVault"
$currentDay = (get-date).ToString("dMyyyyhhmmtt")
$ExpirationDate = (GET-DATE).AddMonths(2)

Write-Output "Runbook started. Version: $VERSION at $currentDay"
Write-Output "---------------------------------------------------"

# Authenticate with your Automation Account
$connection = Get-AutomationConnection -Name AzureRunAsConnection
    # Wrap authentication in retry logic for transient network failures
    $logonAttempt = 0
    while(!($connectionResult) -and ($logonAttempt -le 10))
        # Logging in to Azure...
        $connectionResult = Connect-AzAccount `
                                -ServicePrincipal `
                                -Tenant $connection.TenantID `
                                -ApplicationId $connection.ApplicationID `
                                -CertificateThumbprint $connection.CertificateThumbprint

        Start-Sleep -Seconds 30

# Set Azure Context

    $AzureContext = Get-AzSubscription -SubscriptionId $connection.SubscriptionID
    $SubID = $

#Create Password

    $Length = 24
    $characters = @([char[]]@(48..57),[char[]]@(65..90),[char[]]@(97..122),@('!','#','%','^','*','(',')','-','+','/','{','}','~','[',']'))
    $SSH_KEY_PASSWORD = ($Characters | Get-Random -Count $Length ) -join ''

# Register keyvault

Register-SecretVault -Name $SecretStoreName -ModuleName Az.KeyVault -VaultParameters @{ AZKVaultName = $vaultname; SubscriptionId = $SubID }

# create key and set it in Key Vault

$KeyPath = $env:TEMP
New-RSAKeyPair -Length 2048 -Password $password -Path $KeyPathid_rsa -Force

$SSH_PRIVATE_KEY_array = Get-Content $KeyPath/id_rsa
$SSH_PUBLIC_KEY = Get-Content $KeyPath/
$SSH_PUBLIC_PEM_array = Get-Content $KeyPath/id_rsa.pem

Set-Secret -Name "SSH-Passphrase-demo" -Secret $SSH_KEY_PASSWORD -Vault $SecretStoreName
Set-Secret -Name "SSH-PrivateKey-demo" -Secret $SSH_PRIVATE_KEY -Vault $SecretStoreName
Set-Secret -Name "SSH-PublicKey-demo" -Secret $SSH_PUBLIC_KEY -Vault $SecretStoreName
Set-Secret -Name "SSH-PublicKeypem-demo" -Secret $SSH_PUBLIC_PEM -Vault $SecretStoreName

Please note that this runbook uses the New-RSAKeyPair cmdlet from the  PEMEncrypt module imported in my Automantion environment from the PowerShell Galery. 

Now, again this is a proof-of-concept piece of code. For production use a lot of changes would be required (not an exhaustive list)

  • Expiration dates you be set.
  • A function to validate that the afore mentioned expiration is not imminent.
  • A function to update the key on each VM in a set environment.

So, in conclusion,  yes,  you can use these new module on a VM of you can use these new modules to help you manage the access to these Linux VMs.

I hope this helps.



This article was originally published by Microsoft's Secure Blog. You can find the original article here.