We were struggling too much to get the extension working, and it's proving unreliable to use in a production environment. We've resorted to using a Custom Script Extension with a PowerShell script that does what the extension should do. This is proving to be much more reliable, and we can output logs to a file to diagnose what's not working if something goes wrong, whereas with the extension, it's a guessing game.
Azure Key Vault virtual machine extension for Windows
I've tried following the instructions here to set up the Key Vault Extension for Windows using PowerShell. My PowerShell script is:
# Build settings
$settings = ".\key-vault-settings.json"
$extName = "KeyVaultForWindows"
$extPublisher = "Microsoft.Azure.KeyVault"
$extType = "KeyVaultForWindows"
# Add extension to Virtual Machine Scale Sets
$vmss = Get-AzVmss -ResourceGroupName devtestmornevm -VMScaleSetName devtestmornevm
Add-AzVmssExtension -VirtualMachineScaleSet $vmss -Name $extName -Publisher $extPublisher -Type $extType -TypeHandlerVersion "3.0" -Setting $settings
# Start the deployment
Update-AzVmss -ResourceGroupName devtestmornevm -VMScaleSetName devtestmornevm -VirtualMachineScaleSet $vmss
This is my key-vault-settings.json file:
{
"secretsManagementSettings": {
"pollingIntervalInS": "3600",
"linkOnRenewal": true,
"observedCertificates":
[
{
"url": "https://devtestmornevmss.vault.azure.net/secrets/Certificate1",
"certificateStoreName": "MY",
"certificateStoreLocation": "LocalMachine"
},
{
"url": "https://devtestmornevmss.vault.azure.net/secrets/Certificate2",
"certificateStoreName": "MY",
"certificateStoreLocation": "LocalMachine"
}
]},
"authenticationSettings": {
"msiEndpoint": "http://169.254.169.254/metadata/identity/oauth2/token",
"msiClientId": "31f84835-57e6-46d6-9000-87f70631a152"
}
}
The VMSS is set up with a User Assigned Managed Identity, which has these properties:
The msiClientId in the JSON is the Client ID of the Managed Identity. The msiEndpoint was taken from your Azure documentation. I cannot find any other resource that explains what to put there.
After running the script, I get the following error, which is also shown on the extension page on the Azure portal when looking at the extension.
Enable failed for plugin (name: Microsoft.Azure.KeyVault.KeyVaultForWindows, version 3.0.2138.56) with exception Command C:\Packages\Plugins\Microsoft.Azure.KeyVault.KeyVaultForWindows\3.0.2138.56\enable-disable-kvvm.cmd of Microsoft.Azure.KeyVault.KeyVaultForWindows has exited with Exit code: 2. Error: The service is not responding to the control function. More help is available by typing NET HELPMSG 2186.
Also, some additional information. If I run this .NET code on the VM, it runs successfully, which indicates that the VM has got access to the Key Vault, but it is the Extension specifically that is not working.
class Program
{
static void Main(string[] args)
{
string secretName = "mySecret";
string keyVaultName = "devtestmornevmss";
var kvUri = "https://devtestmornevmss.vault.azure.net";
SecretClientOptions options = new SecretClientOptions()
{
Retry =
{
Delay= TimeSpan.FromSeconds(2),
MaxDelay = TimeSpan.FromSeconds(16),
MaxRetries = 5,
Mode = RetryMode.Exponential
}
};
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential(),options);
Console.Write("Input the value of your secret > ");
string secretValue = Console.ReadLine();
Console.Write("Creating a secret in " + keyVaultName + " called '" + secretName + "' with the value '" + secretValue + "' ...");
client.SetSecret(secretName, secretValue);
Console.WriteLine(" done.");
Console.WriteLine("Forgetting your secret.");
secretValue = "";
Console.WriteLine("Your secret is '" + secretValue + "'.");
Console.WriteLine("Retrieving your secret from " + keyVaultName + ".");
KeyVaultSecret secret = client.GetSecret(secretName);
Console.WriteLine("Your secret is '" + secret.Value + "'.");
Console.Write("Deleting your secret from " + keyVaultName + " ...");
client.StartDeleteSecret(secretName);
System.Threading.Thread.Sleep(5000);
Console.WriteLine(" done.");
}
}