async Task <string> CreateVmSettingsString(string region, int vmId, int studyId, int sandboxId, VirtualMachineCreateDto userInput)
        {
            var vmSettings = _mapper.Map <VmSettingsDto>(userInput);

            var availableOs = await _virtualMachineOperatingSystemService.AvailableOperatingSystems(region);

            vmSettings.OperatingSystemCategory = AzureVmUtil.GetOsCategory(availableOs, vmSettings.OperatingSystem);

            vmSettings.Password = await StoreNewVmPasswordAsKeyVaultSecretAndReturnReference(studyId, sandboxId, vmSettings.Password);

            var diagStorageResource = await CloudResourceQueries.GetDiagStorageAccountEntry(_db, sandboxId);

            vmSettings.DiagnosticStorageAccountName = diagStorageResource.ResourceName;

            var networkResource = await CloudResourceQueries.GetNetworkEntry(_db, sandboxId);

            vmSettings.NetworkName = networkResource.ResourceName;

            var networkSetting = CloudResourceConfigStringSerializer.NetworkSettings(networkResource.ConfigString);

            vmSettings.SubnetName = networkSetting.SandboxSubnetName;

            vmSettings.Rules = VmRuleUtils.CreateInitialVmRules(vmId);
            return(CloudResourceConfigStringSerializer.Serialize(vmSettings));
        }
        async Task <List <CloudResource> > GetSandboxVirtualMachinesList(SepesDbContext db, int sandboxId)
        {
            var queryable = CloudResourceQueries.SandboxVirtualMachinesQueryable(db, sandboxId);

            var vmList = await queryable.ToListAsync();

            if (!vmList.Any())
            {
                return(new List <CloudResource>());
            }

            var sandbox = vmList.FirstOrDefault().Sandbox;

            await _studyPermissionService.VerifyAccessOrThrow(sandbox.Study, UserOperation.Study_Read);

            return(vmList);
        }
        public async Task <VmDto> CreateAsync(int sandboxId, VirtualMachineCreateDto userInput)
        {
            CloudResource vmResourceEntry = null;

            try
            {
                ValidateVmPasswordOrThrow(userInput.Password);

                GenericNameValidation.ValidateName(userInput.Name);

                _logger.LogInformation($"Creating Virtual Machine for sandbox: {sandboxId}");

                var sandbox = await _sandboxModelService.GetByIdForResourceCreationAsync(sandboxId, UserOperation.Study_Crud_Sandbox);

                var virtualMachineName = AzureResourceNameUtil.VirtualMachine(sandbox.Study.Name, sandbox.Name, userInput.Name);

                await _cloudResourceCreateService.ValidateThatNameDoesNotExistThrowIfInvalid(virtualMachineName);

                var tags = ResourceTagFactory.SandboxResourceTags(_config, sandbox.Study, sandbox);

                var region = RegionStringConverter.Convert(sandbox.Region);

                userInput.DataDisks = await TranslateDiskSizes(sandbox.Region, userInput.DataDisks);

                var resourceGroup = await CloudResourceQueries.GetResourceGroupEntry(_db, sandboxId);

                //Make this dependent on bastion create operation to be completed, since bastion finishes last
                var dependsOn = await CloudResourceQueries.GetCreateOperationIdForBastion(_db, sandboxId);

                vmResourceEntry = await _cloudResourceCreateService.CreateVmEntryAsync(sandboxId, resourceGroup, region.Name, tags, virtualMachineName, dependsOn, null);

                //Create vm settings and immeately attach to resource entry
                var vmSettingsString = await CreateVmSettingsString(sandbox.Region, vmResourceEntry.Id, sandbox.Study.Id, sandboxId, userInput);

                vmResourceEntry.ConfigString = vmSettingsString;
                await _cloudResourceUpdateService.Update(vmResourceEntry.Id, vmResourceEntry);

                var queueParentItem = new ProvisioningQueueParentDto
                {
                    Description = $"Create VM for Sandbox: {sandboxId}"
                };

                queueParentItem.Children.Add(new ProvisioningQueueChildDto()
                {
                    ResourceOperationId = vmResourceEntry.Operations.FirstOrDefault().Id
                });

                await _provisioningQueueService.SendMessageAsync(queueParentItem);

                var dtoMappedFromResource = _mapper.Map <VmDto>(vmResourceEntry);

                return(dtoMappedFromResource);
            }
            catch (Exception ex)
            {
                try
                {
                    //Delete resource if created
                    if (vmResourceEntry != null)
                    {
                        await _cloudResourceDeleteService.HardDeleteAsync(vmResourceEntry.Id);
                    }
                }
                catch (Exception rollbackEx)
                {
                    _logger.LogError(rollbackEx, $"Failed to roll back VM creation for sandbox {sandboxId}");
                }

                throw new Exception($"Failed to create VM: {ex.Message}", ex);
            }
        }