/// <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> CreateResourceGroupAsync(Guid subscriptionId) { Subscription subscription = await _context.Subscriptions.FindAsync(subscriptionId); ValidateSubscriptionAndInputState(subscription); try { Offer offer = await FindOfferById(subscription.OfferId); Plan plan = await FindPlanById(subscription.PlanId); string isvSubscriptionId = offer.HostSubscription.ToString(); var parameters = await EvaluateParameters(offer, plan, subscription); subscription.EntryPointUrl = parameters.ContainsKey("entryPointUrl") ? parameters["entryPointUrl"].ToString() : ""; if (plan.SubscribeArmTemplateId == null) { // Don't need to deploy anything, transit to WebhookPending state return(await TransitToNextState(subscription, ProvisioningState.WebhookPending)); } string azureLocation = null; string resourceGroupName = $"{offer.OfferName}-{subscription.SubscriptionId}"; if (parameters.ContainsKey("resourceGroupLocation")) { azureLocation = parameters["resourceGroupLocation"].ToString(); } else { throw new LunaBadRequestUserException("The ResourceGroupLocation parameter is not specified.", UserErrorCode.ParameterNotProvided); } _logger.LogInformation( LoggingUtils.ComposeHttpClientLogMessage( _provisioningClient.GetType().Name, nameof(_provisioningClient.ResourceGroupExistsAsync), subscriptionId)); bool resourceGroupExists = await _provisioningClient.ResourceGroupExistsAsync( Guid.NewGuid(), Guid.NewGuid(), isvSubscriptionId, resourceGroupName, default); if (!resourceGroupExists) { _logger.LogInformation( LoggingUtils.ComposeHttpClientLogMessage( _provisioningClient.GetType().Name, nameof(_provisioningClient.CreateOrUpdateResourceGroupAsync), subscriptionId)); var result = await _provisioningClient.CreateOrUpdateResourceGroupAsync( Guid.NewGuid(), Guid.NewGuid(), isvSubscriptionId, resourceGroupName, azureLocation, default ); _logger.LogInformation($"Deploying resource group {resourceGroupName} in location {azureLocation}."); } else { throw new LunaConflictUserException($"Resource group with name {resourceGroupName} already exist."); } subscription.ResourceGroup = resourceGroupName; return(await TransitToNextState(subscription, ProvisioningState.DeployResourceGroupRunning)); } catch (Exception e) { return(await HandleExceptions(subscription, e)); } }