/// <summary> /// Upon notification of activation of a subscription from AMP, deploy the ARM template. /// </summary> /// <param name="provisionModel"></param> /// <param name="azureLocation"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task ProcessStartProvisioningAsync( Subscription subscription, string azureLocation, CancellationToken cancellationToken = default) { Offer offer = await _context.Offers.FindAsync(subscription.OfferId); Plan plan = await _context.Plans.FindAsync(subscription.OfferId, subscription.PlanId); string deploymentName = $"{plan.PlanName}{offer.OfferName}{new Random().Next(0, 9999).ToString("D4")}"; // deployment name cannot exceed 64 characters, otherwise returns 400 string isvSubscriptionId = offer.HostSubscription.ToString(); // get the subscribe template for this plan string templatePath = await GetTemplatePath( offer, plan, FulfillmentAction.Activate ); object parameters = await GetTemplateParameters( offer, plan, FulfillmentAction.Activate ); // create a resource group for the subscription var resourceGroup = (await _provisioningClient.CreateOrUpdateResourceGroupAsync( Guid.NewGuid(), Guid.NewGuid(), isvSubscriptionId, $"luna-{subscription.SubscriptionId}", azureLocation, cancellationToken )).Name; // deploy the ARM template // note that the rollback property is set to false here because this is a fresh resource group with nothing to fallback on if this deployment fails await _provisioningClient.PutDeploymentAsync( requestId : Guid.NewGuid(), correlationId : Guid.NewGuid(), subscriptionId : isvSubscriptionId, resourceGroup : resourceGroup, deploymentName : deploymentName, templatePath : templatePath, parameters : parameters, cancellationToken : cancellationToken); }
public async Task <Subscription> DeployArmTemplateAsync(Guid subscriptionId) { Subscription subscription = await _context.Subscriptions.FindAsync(subscriptionId); ValidateSubscriptionAndInputState(subscription); try { if (subscription.ResourceGroup == null) { // If resource group is not created, transit to ProvisioningPending state to create resource group return(await TransitToNextState(subscription, ProvisioningState.ProvisioningPending)); } Offer offer = await FindOfferById(subscription.OfferId); Plan plan = await FindPlanById(subscription.PlanId); string deploymentName = $"{plan.PlanName}{offer.OfferName}{new Random().Next(0, 9999).ToString("D4")}"; // deployment name cannot exceed 64 characters, otherwise returns 400 string isvSubscriptionId = offer.HostSubscription.ToString(); string templatePath = await GetTemplatePath(plan, subscription.ProvisioningType); if (templatePath == null) { // If template is not specified, do nothing and transit to WebhookPending state return(await TransitToNextState(subscription, ProvisioningState.WebhookPending)); } // Reevaluate parameters if not subscribe. If it is subscribe, the parameters are evaluated when creating resource group if (!subscription.ProvisioningType.Equals(nameof(ProvisioningType.Subscribe))) { await EvaluateParameters(offer, plan, subscription); } templatePath = await _storageUtility.GetFileReferenceWithSasKeyAsync(templatePath); JObject parameters = new JObject(); using (WebClient client = new WebClient()) { string content = client.DownloadString(templatePath); Context context = await SetContext(offer.OfferName, subscription.Owner, subscriptionId, plan.PlanName, subscription.ProvisioningType); var paramList = ARMTemplateHelper.GetArmTemplateParameters(content); foreach (var param in paramList) { JProperty value = new JProperty("value", context.Parameters[param.Key]); parameters.Add(param.Key, new JObject(value)); } } _logger.LogInformation( LoggingUtils.ComposeHttpClientLogMessage( _provisioningClient.GetType().Name, nameof(_provisioningClient.PutDeploymentAsync), subscriptionId)); var result = await _provisioningClient.PutDeploymentAsync( Guid.NewGuid(), Guid.NewGuid(), isvSubscriptionId, subscription.ResourceGroup, deploymentName, parameters : parameters, templatePath : templatePath); subscription.DeploymentName = result.Name; _logger.LogInformation($"Running ARM deployment {deploymentName} for subscription {isvSubscriptionId} in resource group {subscription.ResourceGroup}."); return(await TransitToNextState(subscription, ProvisioningState.ArmTemplateRunning)); } catch (Exception e) { return(await HandleExceptions(subscription, e)); } }