public static async Task <int> GetResourceGroupsCreated([ActivityTrigger] BaseTemplate template, ILogger log) { try { log.LogInformation($"Getting ResourceGroupsCreated in all subscriptions"); var resource = new TrialResource { Template = template, TenantId = template.TenantId }; var armClient = await ArmClient.GetAzureClient(resource, log); var count = 0; foreach (var sub in resource.Template.Subscriptions) { var resourceGroups = await armClient .WithSubscription(sub) .ResourceGroups .ListAsync(); count += resourceGroups.Where(a => GetQueueNameFromResourceGroupName(a.Name).Equals(template.QueueName)).Count(); } return(count); } catch (Exception ex) { LogException("Exception getting ResourceGroupsCreated", ex, log); } return(-1); }
public static async Task <TrialResource> CheckDeploymentStatus([ActivityTrigger] TrialResource resource, ILogger log) { try { log.LogInformation($"Checking Deployment Status {resource.ResourceGroupName} in {resource.SubscriptionId} |Attempt:{resource.Template.DeploymentCheckAttempt}/{resource.Template.DeploymentCheckTries} |Template{resource.Template.Name} |Region:{resource.Template.Region}"); var azure = await ArmClient.GetAzureClient(resource, log); var deployment = await azure.WithSubscription(resource.SubscriptionId).Deployments.GetByResourceGroupAsync(resource.ResourceGroupName, resource.AppServiceName); if (StringComparer.OrdinalIgnoreCase.Equals(deployment.ProvisioningState, "Succeeded")) { resource.Status = ResourceStatus.AvailableForAssignment; } else if (StringComparer.OrdinalIgnoreCase.Equals(deployment.ProvisioningState, "Failed") || StringComparer.OrdinalIgnoreCase.Equals(deployment.ProvisioningState, "Cancelled")) { resource.Status = ResourceStatus.Error; } else { resource.Status = ResourceStatus.DeploymentInProgress; } } catch (Exception ex) { LogException("Exception checking DeploymentStatus", ex, log); } return(resource); }
public static async Task <IAuthenticated> GetAzureClient(TrialResource resource, ILogger log) { if (_azureClient == null || DateTime.UtcNow >= _tokenExpiry) { if (DateTime.UtcNow >= _tokenExpiry) { log.LogInformation($"Renewing token at {DateTime.UtcNow.ToLongDateString()}"); } else { log.LogInformation($"Creating new azureclient at {DateTime.UtcNow.ToLongDateString()}"); } var tenantId = resource.TenantId; var tokenCredentials = new TokenCredentials(await _azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/")); var azureCredentials = new AzureCredentials( tokenCredentials, tokenCredentials, tenantId, AzureEnvironment.FromName(resource.Template.AzureEnvironment)); var client = RestClient .Configure() .WithEnvironment(AzureEnvironment.FromName(resource.Template.AzureEnvironment)) .WithLogLevel(resource.Template.DeploymentLoggingLevel.ToEnum <HttpLoggingDelegatingHandler.Level>()) .WithCredentials(azureCredentials) .Build(); _tokenExpiry = DateTime.UtcNow.AddMinutes(30); _azureClient = Azure .Authenticate(client, tenantId); } return((IAuthenticated)_azureClient); }
public static async Task CreateATrialResource([OrchestrationTrigger] DurableOrchestrationContext context) { DateTime start = DateTime.UtcNow; TrialResource resource = context.GetInput <TrialResource>(); context.SetCustomStatus("Started"); resource.SessionId = Guid.NewGuid(); resource.InstanceId = context.InstanceId; //telemetry.Context.Operation.Id = context.InstanceId; //telemetry.Context.Operation.Name = "CreateATrialResource"; //if (!String.IsNullOrEmpty(resource.AppServiceName)) //{ // telemetry.Context.User.Id = resource.AppServiceName; //} //telemetry.TrackEvent("DurableManageResources called"); //telemetry.TrackMetric("Test Metric", DateTime.Now.Millisecond); //var outputs = new List<string>(); resource = GetSubscriptionAndResourceGroupName(resource); context.SetCustomStatus("ResourceConfigSet"); resource = await context.CallActivityAsync <TrialResource>("CreateResourceGroup", resource); context.SetCustomStatus("ResourceGroupCreated"); resource = await context.CallActivityAsync <TrialResource>("StartDeployment", resource); context.SetCustomStatus("DeploymentStarted"); resource.Template.DeploymentCheckAttempt = 0; while ((resource.Status != ResourceStatus.AvailableForAssignment && resource.Status != ResourceStatus.Error) && resource.Template.DeploymentCheckAttempt++ < resource.Template.DeploymentCheckTries) { SdkContext.DelayProvider.Delay(resource.Template.DeploymentCheckIntervalSeconds * 1000); resource = await context.CallActivityAsync <TrialResource>("CheckDeploymentStatus", resource); context.SetCustomStatus("DeploymentGoingOn"); } context.SetCustomStatus("DeploymentCompleted"); resource = await context.CallActivityAsync <TrialResource>("AddResourceGroupToQueue", resource); context.SetCustomStatus("ResourceAddedToQueue"); resource = await context.CallActivityAsync <TrialResource>("TagQueuedUpItem", resource); context.SetCustomStatus("QueuedItemTagged"); //telemetry.TrackDependency( "ARM", "CreateATrialResource", JsonConvert.SerializeObject(resource), start, DateTime.UtcNow-start, true); // sleep between cleanups //DateTime nextCleanup = context.CurrentUtcDateTime.AddSeconds(10); //await context.CreateTimer(nextCleanup, CancellationToken.None); //context.ContinueAsNew(new TrialResource { TemplateName = "WordPress" }); return; }
public static async Task AddResourceGroupToQueue([ActivityTrigger] TrialResource resource, ILogger log) { try { log.LogInformation($"Adding ResourceGroup {resource.ResourceGroupName} to queue {resource.Template.QueueName} in {resource.SubscriptionId} region {resource.Template.Region}"); var queue = queueClient().GetQueueReference(resource.Template.QueueName); await queue.CreateIfNotExistsAsync(); await queue.AddMessageAsync(new CloudQueueMessage(JsonConvert.SerializeObject(resource))); } catch (Exception ex) { LogException("Exception queueing up ResourceGroup", ex, log); } }
public static async Task <TrialResource> CreateResourceGroup([ActivityTrigger] TrialResource resource, ILogger log) { try { log.LogInformation($"Creating ResourceGroup {resource.ResourceGroupName} in {resource.SubscriptionId} region {resource.Template.Region}"); var armClient = await ArmClient.GetAzureClient(resource, log); await armClient .WithSubscription(resource.SubscriptionId) .ResourceGroups.Define(resource.ResourceGroupName) .WithRegion(Region.Create(resource.Template.Region)) .CreateAsync(); } catch (Exception ex) { LogException("Exception creating ResourceGroup", ex, log); } return(resource); }
public static TrialResource GetSubscriptionAndResourceGroupName([ActivityTrigger] TrialResource resource) { resource.AppService = resource.Template.AppService.ToString(); resource.SubscriptionId = resource.Template.Subscriptions.OrderBy(a => Guid.NewGuid()).FirstOrDefault(); resource.TenantId = resource.Template.TenantId; var guid = Guid.NewGuid().ToString().Split('-')[1]; resource.ResourceGroupName = $"try-{resource.Template.QueueName}-{guid}"; resource.AppServiceName = resource.ResourceGroupName; resource.Template.ARMParameters = JsonConvert.SerializeObject(new Dictionary <string, Dictionary <string, object> > { { "msdeployPackageUrl", new Dictionary <string, object> { { "value", resource.Template.MSDeployPackageUrl ?? String.Empty } } }, { "appServiceName", new Dictionary <string, object> { { "value", resource.AppServiceName } } } }); return(resource); }
public static async Task <TrialResource> TagQueuedUpItem([ActivityTrigger] TrialResource resource, ILogger log) { try { log.LogInformation($"Tagging queued Up Item {resource.ResourceGroupName} in {resource.SubscriptionId} region {resource.Template.Region}"); var armClient = await ArmClient.GetAzureClient(resource, log); var rg = await armClient.WithSubscription(resource.SubscriptionId) .ResourceGroups.GetByNameAsync(resource.ResourceGroupName); await rg.Update().WithTag("deployed", "true").ApplyAsync(); resource.Status = ResourceStatus.AvailableForAssignment; } catch (Exception ex) { LogException("Exception tagging queued up Item", ex, log); } return(resource); }
public static async Task <TrialResource> StartDeployment([ActivityTrigger] TrialResource resource, ILogger log) { try { log.LogInformation($"Starting deployment {resource.ResourceGroupName} in {resource.SubscriptionId}"); var azure = await ArmClient.GetAzureClient(resource, log); await azure .WithSubscription(resource.SubscriptionId) .Deployments.Define(resource.AppServiceName) .WithExistingResourceGroup(resource.ResourceGroupName) .WithTemplateLink(resource.Template.ARMTemplateLink, null) .WithParameters(JsonConvert.DeserializeObject(resource.Template.ARMParameters)) .WithMode(resource.Template.DeploymentMode.ToEnum <DeploymentMode>()) .CreateAsync(); } catch (Exception ex) { LogException("Exception starting deployment", ex, log); } return(resource); }
public static async Task Run([QueueTrigger("create-items")] TrialResource myQueueItem, ILogger log) { log.LogInformation("CreateResource QueueTrigger function processed a request."); var subscriptionId = myQueueItem.SubscriptionId;; AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); var tenantId = myQueueItem.TenantId; var tokenCredentials = new TokenCredentials(await azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/").ConfigureAwait(false)); var azureCredentials = new AzureCredentials( tokenCredentials, tokenCredentials, tenantId, AzureEnvironment.FromName(myQueueItem.AzureEnvironment)); var client = RestClient .Configure() .WithEnvironment(AzureEnvironment.FromName(myQueueItem.AzureEnvironment)) .WithLogLevel(myQueueItem.DeploymentLoggingLevel.ToEnum <HttpLoggingDelegatingHandler.Level>()) .WithCredentials(azureCredentials) .Build(); var azure = Azure .Authenticate(client, tenantId) .WithSubscription(subscriptionId); // var resourceManagementClient = new ResourceManagementClient(client); string rgName = myQueueItem.ResourceGroupName; //SdkContext.RandomResourceName(myQueueItem.ResourceGroupName, 24); string deploymentName = myQueueItem.AppServiceName; try { //var templateJson = File.ReadAllText(System.IO.Path.Combine(context.FunctionDirectory, "..\\FreeFunctionARMTemplate.json")); //============================================================= // Create resource group. Console.WriteLine("Creating a resource group with name: " + rgName); await azure.ResourceGroups.Define(rgName) .WithRegion(myQueueItem.Region.ToEnum <Region>()) .CreateAsync(); Console.WriteLine("Created a resource group with name: " + rgName); //============================================================= // Create a deployment for an Azure App Service via an ARM template. Console.WriteLine("Starting a deployment for an Azure App Service: " + deploymentName); await azure.Deployments.Define(deploymentName) .WithExistingResourceGroup(rgName) .WithTemplateLink("", null) //.WithParameters(new Dictionary<string, Dictionary<string, object>>{ // { "hostingPlanName", new Dictionary<string, object>{{"value",deploymentName}}}, // { "skuName", new Dictionary<string, object>{{"value", "B1" }}}, // { "skuCapacity", new Dictionary<string, object>{{"value",1}}}, // { "webSiteName", new Dictionary<string, object>{{"value", deploymentName } }} // }) //.WithParameters(new Dictionary<string, Dictionary<string, object>>{ // { "msdeployPackageUrl", new Dictionary<string, object>{{"value", "https://tryappservicetemplates.blob.core.windows.net/zipped/Default/Express.zip" } }}, // { "appServiceName", new Dictionary<string, object>{{"value", deploymentName } }} // }) .WithParametersLink("", null) .WithMode(myQueueItem.DeploymentMode.ToEnum <DeploymentMode>()) .CreateAsync(); Console.WriteLine("Started a deployment for an Azure App Service: " + deploymentName); var deployment = await azure.Deployments.GetByResourceGroupAsync(rgName, deploymentName); Console.WriteLine("Current deployment status : " + deployment.ProvisioningState); var tries = 180; while (!(StringComparer.OrdinalIgnoreCase.Equals(deployment.ProvisioningState, "Succeeded") || StringComparer.OrdinalIgnoreCase.Equals(deployment.ProvisioningState, "Failed") || StringComparer.OrdinalIgnoreCase.Equals(deployment.ProvisioningState, "Cancelled")) && tries-- > 0) { SdkContext.DelayProvider.Delay(10000); deployment = await azure.Deployments.GetByResourceGroupAsync(rgName, deploymentName); Console.WriteLine("Current deployment status : " + deployment.ProvisioningState); } if (StringComparer.OrdinalIgnoreCase.Equals(deployment.ProvisioningState, "Succeeded")) { var res = deployment.Outputs; var sitesDeployed = deployment.Dependencies.Where(a => StringComparer.OrdinalIgnoreCase.Equals(a.ResourceType, "Microsoft.Web/sites")); if (sitesDeployed != null) { var siteList = new List <IWebApp>(); foreach (var site in sitesDeployed) { siteList.Add(await azure.WebApps.GetByIdAsync(site.Id)); } } } } catch (Exception ex) { Console.WriteLine(ex); } finally { try { Console.WriteLine("Deleting Resource Group: " + rgName); azure.ResourceGroups.DeleteByName(rgName); Console.WriteLine("Deleted Resource Group: " + rgName); } catch (NullReferenceException) { Console.WriteLine("Did not create any resources in Azure. No clean up is necessary"); } catch (Exception ex) { Console.WriteLine(ex); } } string name = myQueueItem.AppServiceName; }