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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 10
0
        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;
        }