using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Azure.Identity; | |
using Azure.Storage.Blobs; | |
using Microsoft.Azure.WebJobs; | |
using Microsoft.Extensions.Logging; | |
using Microsoft.Azure.Management.ResourceGraph; | |
using Microsoft.Rest; | |
using Microsoft.Azure.Management.ResourceGraph.Models; | |
using Microsoft.Azure.Management.Subscription; | |
using Microsoft.Azure.Management.Subscription.Models; | |
using Newtonsoft.Json.Linq; | |
namespace RetrieveAzureVmData_wFuncAppMI | |
{ | |
public static class Function1 | |
{ | |
[FunctionName("Function1")] | |
public static async Task Run([TimerTrigger("0 */15 * * * *")] TimerInfo myTimer, ILogger log) | |
{ | |
log.LogInformation($"Starting function at: {DateTime.Now}"); | |
string accessToken = await ExtractAccessTokenFromCredentials( | |
new ManagedIdentityCredential()); | |
await WriteVmDataToStorageAccount(await GetVMData(accessToken, await GetAllAzureSubscriptions(accessToken, log), log)); | |
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}"); | |
} | |
private static async Task<string> ExtractAccessTokenFromCredentials(Azure.Core.TokenCredential tokenCredential) | |
{ | |
// Extract the access token from the supplied credentials | |
var accessToken = await tokenCredential.GetTokenAsync( | |
new Azure.Core.TokenRequestContext(new string[] { "https://management.core.windows.net/.default" }), | |
new System.Threading.CancellationToken()); | |
return accessToken.Token; | |
} | |
private static async Task<List<string>> GetAllAzureSubscriptions(string accessToken, ILogger log) | |
{ | |
// Pack the credentials in the format required next | |
ServiceClientCredentials serviceClientCreds = new TokenCredentials(accessToken); | |
// Get the subscriptions | |
SubscriptionClient subscriptionClient = new SubscriptionClient(serviceClientCreds); | |
IEnumerable<SubscriptionModel> allSubscriptions = await subscriptionClient.Subscriptions.ListAsync(); | |
log.LogInformation($"{allSubscriptions.Count()} subscriptions retrieved"); | |
// Extract the subscriptions' ids | |
List<string> allSubscriptionIds = new List<string>(); | |
foreach (var subscription in allSubscriptions) | |
{ | |
allSubscriptionIds.Add(subscription.SubscriptionId); | |
} | |
return allSubscriptionIds; | |
} | |
private static async Task<Newtonsoft.Json.Linq.JArray> GetVMData(string accessToken, | |
List<string> listOfAllAzureSubscriptionIds, ILogger log) | |
{ | |
ServiceClientCredentials serviceClientCreds = new TokenCredentials(accessToken); | |
ResourceGraphClient argClient = new ResourceGraphClient(serviceClientCreds); | |
string strQuery = @"Resources | |
| where type =~ 'microsoft.compute/virtualmachines' | |
| project id, vmId = tolower(tostring(id)), vmName = name | |
| join (Resources | |
| where type =~ 'microsoft.network/networkinterfaces' | |
| mv-expand ipconfig=properties.ipConfigurations | |
| project vmId = tolower(tostring(properties.virtualMachine.id)), privateIp = ipconfig.properties.privateIPAddress, publicIpId = tostring(ipconfig.properties.publicIPAddress.id) | |
| join kind=leftouter (Resources | |
| where type =~ 'microsoft.network/publicipaddresses' | |
| project publicIpId = id, publicIp = properties.ipAddress | |
) on publicIpId | |
| project-away publicIpId, publicIpId1 | |
| summarize privateIps = make_list(privateIp), publicIps = make_list(publicIp) by vmId | |
) on vmId | |
| project-away vmId, vmId1 | |
| sort by vmName asc"; | |
QueryRequest request = new QueryRequest(); | |
request.Subscriptions = listOfAllAzureSubscriptionIds; | |
request.Query = strQuery; | |
request.Options = new QueryRequestOptions { ResultFormat = ResultFormat.ObjectArray }; | |
JArray allVmData = new JArray(); | |
QueryResponse response; | |
do | |
{ | |
response = null; | |
try | |
{ | |
response = await argClient.ResourcesAsync(request); | |
request.Options.SkipToken = response.SkipToken; | |
} | |
catch (Exception e) | |
{ | |
log.LogInformation(e.ToString()); | |
} | |
log.LogInformation("No of records in current response page: " + response.Count); | |
allVmData.Merge(response.Data); | |
} while (!string.IsNullOrEmpty(response.SkipToken)); | |
return allVmData; | |
} | |
private static async Task WriteVmDataToStorageAccount(Newtonsoft.Json.Linq.JArray allVmData) | |
{ | |
string blockBlobName = "azureVMs.json"; | |
// Hard-coded connection string below. It would be ideal to read this from Azure Vault | |
var connectionString = "STORAGE_ACCOUNT_CONNECTION_STRING"; | |
// Build the object that will connect to the container within our target storage account | |
BlobContainerClient blobContainerClient = new BlobContainerClient(connectionString, "STORAGE_ACCOUNT_CONTAINER_NAME"); | |
// Write to Azure Blob Storage | |
BlobClient blobClient = blobContainerClient.GetBlobClient(blockBlobName); | |
using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(allVmData.ToString()))) | |
{ | |
await blobClient.UploadAsync(memoryStream, true); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment