Generate certificate and add it to Azure Virtual Machine

Hello scripting maniacs! Today post will show you how to generate certificate and add it to Azure virtual machine using PowerShell script.

Last time I have a case to configure Azure Front Door service with virtual machines which will be set in the backend. However during setting up this service I found that on virtual machines certificate with proper names should be configured. I have an idea to create self signed certificate and simply import them to proper certificate store, but it wasn’t so easy.

First of all Azure Front Door require certificates which are signed by trusted certificate authority. Decided to use Let’s encrypt because it’s quite popular and have a lot possibilities with automation of renewal process. Other problem was that Let’s encrypt in order to verify DNS name need to have access to DNS server. It’s hard to do it if your domain is on premise, so we decided to delegate specific domain to DNS Zone in Azure .

I automated whole process for generate certificate and add it Azure virtual machine, however following prerequisiteis must be met:

  • Posh-ACME module must be installed (Let’s Encrypt module)
  • Az module must be installed
  • Account under which script will be run must have access to manage TXT records in delegated Azure DNS Zone (you can use custom role) and to access KeyVault and virtual machine

Script:

param (
    [String]  $TenantId ='',
    [String]  $SubscriptionId='',
    [String]  $Environment='PROD',
    [String]  $KeyVaultName='',
    [String]  $KeyVaultResourceGroup='',
    [String]  $VMName='',
    [String]  $VMResourceGroup='',
    [String]  $CertificateStore='',
    [String]  $DnsRecordName=''
)

$ErrorActionPreference = 'Stop'
$ContactMail = "mail@test.com"

# Set Let's Encrypt Enviornment
Set-PAServer "LE_$Environment"

# Connect to Azure and select proper subscription
Connect-AzAccount -Credential $Credentials -TenantId $TenantId
Select-AzSubscription -SubscriptionId $SubscriptionId

$azureContext = Get-AzContext
$currentAzureProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile;
$currentAzureProfileClient = New-Object Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient($currentAzureProfile);
$azureAccessToken = $currentAzureProfileClient.AcquireAccessToken($azureContext.Tenant.Id).AccessToken;
$azParams = @{
    AZSubscriptionId=$SubscriptionId
    AZAccessToken=$azureAccessToken
  }

# issue a cert

$certificate = New-PACertificate $DnsRecordName -DnsPlugin Azure -PluginArgs $azParams -AcceptTOS -Contact $ContactMail -Force
$Password = $certificate.PfxPass
Import-AzKeyVaultCertificate -VaultName $KeyVaultName -Name "$VMName-cert" -FilePath $certificate.PfxFullChain -Password $Password
Set-AzKeyVaultSecret -VaultName $KeyVaultName -Name "$VMName-cert" -ContentType $DnsRecordName -SecretValue $Password

# Gather certtificate from KeyVault

$certURL= (Get-AzKeyVaultSecret -VaultName $KeyVaultName -Name $VMName"-cert").id
# Gather information about VM
$vm= Get-AzVM -ResourceGroupName $VMResourceGroup -Name $VMName
# Gather information about key vault ID
$vaultId= (Get-AzKeyVault -ResourceGroupName $KeyVaultResourceGroup -VaultName $KeyVaultName).ResourceId
# Add certificate to store on VM
$vm = Add-AzVMSecret -VM $vm -SourceVaultId $vaultId -CertificateStore $CertificateStore -CertificateUrl $certURL
# Update virtual machine with new certificate
Update-AzVM -ResourceGroupName $VMResourceGroup -VM $VM

$PublicSettings = '{
    "fileUris":["https://raw.githubusercontent.com/Azure-Samples/compute-automation-configurations/master/secure-iis.ps1"],
    "commandToExecute":"powershell -ExecutionPolicy Unrestricted -File secure-iis.ps1"
}'

Set-AzureRMVMExtension -ResourceGroupName $VMResourceGroup `
    -ExtensionName "IIS" `
    -VMName "$VMName" `
    -Location $vm.location `
    -Publisher "Microsoft.Compute" `
    -ExtensionType "CustomScriptExtension" `
    -TypeHandlerVersion 1.8 `
    -SettingString $publicSettings

Hope it will be usefull for some of you 😉

Enjoy!

2 thoughts on “Generate certificate and add it to Azure Virtual Machine

  1. Thank you for sharing this useful post. There is a small typo though in line 47. It should be Add-AzVMSecret instead of Add-AVMSecret.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.