Setup Azure VM with user assigned managed identity to access Azure KeyVault


Azure Key Vault is to secure the secrets safely and access them securely as needed without hard-coding them in our code to authenticate to various applications on various environments, but the main challenge here is to authenticate to Key Vault, and if it is compromised then the entire secrets in the vault will be compromised so it should be handled properly.

To overcome this and handle the secrets securely, Azure has come up with a concept called Managed Identities for Azure Resources as a feature in Azure Active Directory, which will help us to authenticate between the azure resources with a trusted relationship.

There are two types of managed identities, one is System Assigned Managed Identity (SAMI) and the other is User Assigned Managed Identity (UAMI), however I am not going to discuss more about the Managed Identities here, you can refer to the Microsoft Docs. 

In this demo, I am going to enable User Assigned Managed Identity between Azure Virtual Machine and Azure Key Vault using PowerShell to access the Key Vault from the VM and retrieve the secrets with a trusted relationship. You can enable the User Assigned Managed Identity while creating the VM itself, but for our demo I am going to enable it after the VM is created, and the steps are as follows…

  • Create a new Virtual Machine
  • Create a Managed Identity
  • Create a Key Vault
  • Add a secret to Key Vault
  • Grant Reader IAM role on Key Vault to Managed Identity
  • Grant access policy to Managed Identity on Key Vault to get the secrets from
  • Enable User Assigned Managed Identity on Virtual Machine
  • Test the access on the Virtual Machine

Create a new Virtual Machine

For our demo I am going to create a simple windows VM with all default values using the New-AzVM CmdLet…

# Create a Resource Group
$rgName = 'Test-RG'
$location = 'westus'
$null = New-AzResourceGroup -Name $rgName -Location $location

# Create a Virtual Machine
$vmName = 'Test-VM'
$userName = 'sysadmin'
$plainTextPassword = 'P@ssw0rd!'
$securePassword = $plainTextPassword | ConvertTo-SecureString -AsPlainText -Force
$credential = [pscredential]::new($userName, $securePassword)
$vm = New-AzVM -ResourceGroupName $rgName -Name $vmName `
                -Location $location -Credential $credential

The above code will create a brand new VM with all defaults and allow the RDP (3389) and PowerShell Remoting (5985) ports. If you want to create a fully configured VM of your choice then you can refer to the script on my GitHub Repo. 

Users with Contributor role can create & manage Virtual Machines.

Create a Managed Identity

Install and import the module Az.ManagedServiceIdentity to create managed identity using New-AzUserAssignedIdentityCmdLet, and this module is not part of Az PowerShell module.

# Install and Import the module
$moduleName = 'Az.ManagedServiceIdentity'
Install-Module -Name $moduleName -Force
Import-Module -Name $moduleName

# Create User Assugned Managed Identity
$identityName = 'amuai'
$identity = New-AzUserAssignedIdentity -Name $identityName `
                                        -ResourceGroupName $rgName -Location $location

The above command will create a User Assigned Managed Identity named amuai.

Create a Key Vault

Create an Azure Key Vault to store secrets, which we will access it from the Virtual Machine using the Managed Identity…

# Create Azure Key Vault
$keyVaultName = 'testakv99'
$keyVault = New-AzKeyVault -ResourceGroupName $rgName `
                            -Name $keyVaultName -Location $location

The above command will create an Azure Key Vault named testakv99, and now we will add a secret to it.

Add a secret to Key Vault

For this demo, we will add the same password that was used to create our test VM.

# Add a secret to Key Vault
$null = Set-AzKeyVaultSecret -VaultName $keyVaultName `
                            -Name $userName -SecretValue $securePassword

Users having the access to Key Vault will have the same access on all the secrets in the vault, so please add the secrets only required to the user.

Grant Reader IAM role on Key Vault to Managed Identity

For this demo, the managed identity is required to read the credentials from the Key Vault, so we need to grant the Reader role on the Key Vault to the Managed Identity.

# Grant Reader role to Managed Identity on Key Vault
$null = New-AzRoleAssignment -ApplicationId $identity.ClientId `
                            -RoleDefinitionName Reader -Scope $keyVault.ResourceId
 

IAM role is limited to the Key Vault resource only and has no effect on accessing the secrets. You need to grant Key Vault access policy to get the secret.

Grant access policy to Managed Identity on Key Vault to get the secrets from

Since this is a demo and we only need to get the secret to be used in our code on the managed identity enabled VM, we will grant GETAccess Policy on Key Vault to managed identity.

# Grant GET permissions to secrets on Key Key Vault to managed identity
Set-AzKeyVaultAccessPolicy -ResourceGroupName $rgName -VaultName $keyVaultName `
                            -ServicePrincipalName $identity.ClientId -PermissionsToSecrets get

Now we need to assign this identity and enable User Assigned Managed Identity on Virtual Machine.

Enable User Assigned Managed Identity on Virtual Machine

Since we have already created a VM and have that VM object in $vm, we will use the same variable for our demo or else you can get the existing VM using Get-AzVM CmdLet.

# Assign the identity and enable User Assigned Managed Identity on Virtual Machine.
$null = Update-AzVM -ResourceGroupName $rgName -VM $vm `
                    -IdentityType UserAssigned -IdentityID $identity.Id

All done, now let’s test this on the Managed Identity enabled VM.

Test the access on the Virtual Machine

Now let’s test the access to Key Vault from the VM without an explicit authentication and get the secret from the Key Vault.

Since I want to use the secret in the PowerShell code, I will test the access and retrieve the secret using the PowerShell itself, so I will install Az module on the VM for our testing purpose.

If you are not using this secret in the PowerShell, you can use the REST methods to get the secrets from the Key Vault, please refer to the Microsoft Docs  for the same.

Get the public ip of the VM and connect to it…

# Get the public ip of the new VM
$vmPIP = Get-AzPublicIpAddress -ResourceGroupName $rgName -Name $vmName | % IpAddress
 

Now let’s install the Az module and authenticate to Azure using the Identity flag and access the secret…

## On the NEW VM in which User Assigned Managed Identity enabled
# Enter-PSSession -ComputerName $vmPIP -Credential $credential

# Install NuGet package provider where Az module is available 
Install-PackageProvider -Name NuGet -Force

# Install the Az module
Install-Module -Name Az -Force

# Login to Azure with managed identity
Login-AzAccount -Identity

# Get the secret from the Key Vault
$kvName = 'testakv99'
$keyName = 'sysadmin'
$Secret = Get-AzKeyVaultSecret -VaultName $kvName -Name $keyName | % SecretValueText

# You can use this secret in your code, since it is a demo I am writing it to screen
Write-Host "The password is: $Secret"

You can take a glance of the complete script from my GitHub Repo. 


Share it on     |   |   |   | 
  Prev:  

List and select in PowerShell console

  :Next  

Create and Build A Static Website With Hugo

comments powered by Disqus