Search code examples
c#azure-functionsazure-virtual-machineazure-monitoring

Finding idle Virtual Machines and deallocating them using Azure Function


I am creating an Azure Function that will find Virtual Machines that are idle or not in use to deallocate them. The Azure Function is now able to find all the Virtual Machines that are running and is able to deallocate them.

Now, how do I find if the VM is idle or no process running or no user is logged in? or any other parameter.

  • I tried to Run Command for finding CPU usage, but somehow it failed to execute (maybe due to permission issue);
  • I tried to Get Data from Azure Monitor > Metrics - Failed to do so.
  • Tried finding in Documentations, didn't get any relevant results.
[FunctionName("DeallocateVM")]
public static void DeallocateVM([TimerTrigger("0 0 * * * *")]TimerInfo myTimer, ILogger log)
{
    var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(ClientId, ClientSecret, TenantId, AzureEnvironment.AzureGlobalCloud);
    var azure = Azure.Configure().WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic).Authenticate(credentials).WithDefaultSubscription();
    var VirtualMachinesList = azure.VirtualMachines.List();
    foreach (var Vm in VirtualMachinesList)
    {
        log.LogInformation($"{Vm.Name}\t{Vm.ProvisioningState}\t{Vm.PowerState}\t{Vm.ResourceGroupName}\t{Vm.OSType}\t{Vm.OSDiskSize}");
        if (Vm.PowerState == PowerState.Running)
        {
            if (Vm.IsIdle())
                Vm.DeallocateAsync(); //Deallocate the VM
        }
    }
}
static bool IsIdle(this IVirtualMachine virtualMachine)
{
    return true; //How to find a VM is idle or not?
}

I expect only the Idle VMs to be deallocated but currently, all the Vms are deallocated.


Solution

  • You can get the metrics using the Monitor SDK. Example :

    var serviceCreds = ApplicationTokenProvider.LoginSilentAsync(azureTenantId, azureAppId, azureSecretKey).Result;
    MonitorClient monitorClient = new MonitorClient(serviceCreds) { SubscriptionId = subscriptionId };
    var resourceUrl = $"subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/virtualMachines/{machineName}";
    var metricNames = "(name.value eq 'Disk Write Operations/Sec' or  name.value eq 'Percentage CPU' or  name.value eq 'Network In' or  name.value eq 'Network Out' or  name.value eq 'Disk Read Operations/Sec' or  name.value eq 'Disk Read Bytes' or  name.value eq 'Disk Write Bytes')"; 
     string timeGrain = " and timeGrain eq duration'PT5M'";
     string startDate = " and startTime eq 2017-10-26T05:28:34.919Z";
     string endDate = " and endTime eq 2017-10-26T05:33:34.919Z";
     var odataFilterMetrics = new ODataQuery<MetricInner>(
                    $"{metricNames}{timeGrain}{startDate}{endDate}");
    
     var metrics = monitorClient.Metrics.ListWithHttpMessagesAsync(resourceUrl, odataFilterMetrics).Result;