public void CanCreateFromCustomImageWithManagedDisk() { using (var context = FluentMockContext.Start(GetType().FullName)) { var userName = "******"; var password = TestUtilities.GenerateName("Pa5$"); var publicIPDnsLabel = SdkContext.RandomResourceName("pip", 10); var customImageName = SdkContext.RandomResourceName("img", 10); var vmssName = SdkContext.RandomResourceName("vmss", 10); var resourceManager = TestHelper.CreateRollupClient(); var computeManager = TestHelper.CreateComputeManager(); var networkManager = TestHelper.CreateNetworkManager(); var rgName = TestUtilities.GenerateName("rgfluentchash-"); try { var resourceGroup = resourceManager.ResourceGroups .Define(rgName) .WithRegion(Location) .Create(); var vm = computeManager.VirtualMachines.Define(SdkContext.RandomResourceName("vm", 10)) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithNewPrimaryNetwork("10.0.0.0/28") .WithPrimaryPrivateIPAddressDynamic() .WithNewPrimaryPublicIPAddress(publicIPDnsLabel) .WithPopularLinuxImage(KnownLinuxVirtualMachineImage.UbuntuServer16_04_Lts) .WithRootUsername(userName) .WithRootPassword(password) .WithUnmanagedDisks() .DefineUnmanagedDataDisk("disk-1") .WithNewVhd(100) .WithLun(1) .Attach() .DefineUnmanagedDataDisk("disk-2") .WithNewVhd(50) .WithLun(2) .Attach() .WithSize(VirtualMachineSizeTypes.Parse("Standard_D2a_v4")) .Create(); Assert.NotNull(vm); TestHelper.DeprovisionAgentInLinuxVM(vm.GetPrimaryPublicIPAddress().Fqdn, 22, userName, password); vm.Deallocate(); vm.Generalize(); var virtualMachineCustomImage = computeManager.VirtualMachineCustomImages .Define(customImageName) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .FromVirtualMachine(vm) .Create(); Assert.NotNull(virtualMachineCustomImage); var network = networkManager .Networks .Define(SdkContext.RandomResourceName("vmssvnet", 15)) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithAddressSpace("10.0.0.0/28") .WithSubnet("subnet1", "10.0.0.0/28") .Create(); var publicLoadBalancer = ScaleSet.CreateHttpLoadBalancers(resourceManager, resourceGroup, "1", Location); var vmScaleSet = computeManager.VirtualMachineScaleSets .Define(vmssName) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithSku(VirtualMachineScaleSetSkuTypes.StandardD5v2) .WithExistingPrimaryNetworkSubnet(network, "subnet1") .WithExistingPrimaryInternetFacingLoadBalancer(publicLoadBalancer) .WithoutPrimaryInternalLoadBalancer() .WithLinuxCustomImage(virtualMachineCustomImage.Id) .WithRootUsername(userName) .WithRootPassword(password) .Create(); var virtualMachineScaleSetVMs = vmScaleSet.VirtualMachines; var virtualMachines = virtualMachineScaleSetVMs.List(); Assert.Equal(virtualMachines.Count(), vmScaleSet.Capacity); foreach (var vm1 in virtualMachines) { Assert.True(vm1.IsOSBasedOnCustomImage); Assert.False(vm1.IsOSBasedOnPlatformImage); Assert.False(vm1.IsOSBasedOnStoredImage); Assert.True(vm1.IsManagedDiskEnabled); Assert.NotNull(vm1.UnmanagedDataDisks); Assert.Empty(vm1.UnmanagedDataDisks); Assert.NotNull(vm1.DataDisks); Assert.Equal(2, vm1.DataDisks.Count); // Disks from data disk image from custom image Assert.True(vm1.DataDisks.ContainsKey(1)); var disk = vm1.DataDisks[1]; Assert.Equal(100, disk.Size); Assert.True(vm1.DataDisks.ContainsKey(2)); disk = vm1.DataDisks[2]; Assert.Equal(50, disk.Size); } vmScaleSet.Deallocate(); // Updating and adding disk as part of VMSS Update seems consistency failing, CRP is aware of // this, hence until it is fixed comment-out the test // // { // "startTime": "2017-01-25T06:10:55.2243509+00:00", // "endTime": "2017-01-25T06:11:07.8649525+00:00", // "status": "Failed", // "error": { // "code": "InternalExecutionError", // "message": "An internal execution error occurred." // }, // "name": "6786df83-ed3f-4d7a-bf58-d295b96fef46" // } // // vmScaleSet.Update() // .WithDataDiskUpdated(1, 200) // update not supported // .WithNewDataDisk(100) // .Apply(); // // vmScaleSet.Start(); // // virtualMachineScaleSetVMs = vmScaleSet.VirtualMachines; // virtualMachines = virtualMachineScaleSetVMs.List(); // foreach (VirtualMachineScaleSetVM vm1 in virtualMachines) { // Assert.True(vm1.IsOSBasedOnCustomImage()); // Assert.False(vm1.IsOSBasedOnPlatformImage()); // Assert.False(vm1.IsOSBasedOnStoredImage()); // Assert.True(vm1.IsManagedDiskEnabled()); // Assert.NotNull(vm1.UnmanagedDataDisks()); // Assert.Equal(vm1.UnmanagedDataDisks().Size(), 0); // Assert.NotNull(vm1.DataDisks()); // Assert.Equal(vm1.DataDisks().Size(), 3); // Assert.True(vm1.DataDisks().ContainsKey(1)); // VirtualMachineDataDisk disk = vm1.DataDisks().Get(1); // Assert.Equal(disk.Size(), 200); // Assert.True(vm1.DataDisks().ContainsKey(2)); // disk = vm1.DataDisks().Get(2); // Assert.Equal(disk.Size(), 50); // Assert.True(vm1.DataDisks().ContainsKey(0)); // disk = vm1.DataDisks().Get(0); // Assert.Equal(disk.Size(), 100); // } } finally { try { resourceManager.ResourceGroups.DeleteByName(rgName); } catch { } } } }
public void CanCreateUpdateFromPIRWithManagedDisk() { using (var context = FluentMockContext.Start(GetType().FullName)) { var vmssName = SdkContext.RandomResourceName("vmss", 10); var resourceManager = TestHelper.CreateRollupClient(); var computeManager = TestHelper.CreateComputeManager(); var networkManager = TestHelper.CreateNetworkManager(); var rgName = TestUtilities.GenerateName("rgfluentchash-"); try { var resourceGroup = resourceManager.ResourceGroups .Define(rgName) .WithRegion(Location) .Create(); var network = networkManager .Networks .Define(SdkContext.RandomResourceName("vmssvnet", 15)) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithAddressSpace("10.0.0.0/28") .WithSubnet("subnet1", "10.0.0.0/28") .Create(); var publicLoadBalancer = ScaleSet.CreateHttpLoadBalancers(resourceManager, resourceGroup, "1", Location); var vmScaleSet = computeManager.VirtualMachineScaleSets .Define(vmssName) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithSku(VirtualMachineScaleSetSkuTypes.StandardD5v2) .WithExistingPrimaryNetworkSubnet(network, "subnet1") .WithExistingPrimaryInternetFacingLoadBalancer(publicLoadBalancer) .WithoutPrimaryInternalLoadBalancer() .WithPopularLinuxImage(KnownLinuxVirtualMachineImage.UbuntuServer16_04_Lts) .WithRootUsername("jvuser") .WithRootPassword(TestUtilities.GenerateName("Pa5$")) .WithNewDataDisk(100) .WithNewDataDisk(100, 1, CachingTypes.ReadWrite) .WithNewDataDisk(100, 2, CachingTypes.ReadOnly) .Create(); var virtualMachineScaleSetVMs = vmScaleSet.VirtualMachines; var virtualMachines = virtualMachineScaleSetVMs.List(); Assert.Equal(virtualMachines.Count(), vmScaleSet.Capacity); foreach (var vm in virtualMachines) { Assert.True(vm.IsOSBasedOnPlatformImage); Assert.False(vm.IsOSBasedOnCustomImage); Assert.False(vm.IsOSBasedOnStoredImage); Assert.True(vm.IsManagedDiskEnabled); Assert.NotNull(vm.UnmanagedDataDisks); Assert.Empty(vm.UnmanagedDataDisks); Assert.NotNull(vm.DataDisks); Assert.Equal(3, vm.DataDisks.Count); } vmScaleSet.Update() .WithoutDataDisk(0) .WithNewDataDisk(50) .Apply(); virtualMachineScaleSetVMs = vmScaleSet.VirtualMachines; virtualMachines = virtualMachineScaleSetVMs.List(); Assert.Equal(virtualMachines.Count(), vmScaleSet.Capacity); foreach (var vm in virtualMachines) { Assert.NotNull(vm.DataDisks); Assert.Equal(3, vm.DataDisks.Count); } // test attach/detach data disk to single instance string diskName = SdkContext.RandomResourceName("disk", 10); IDisk disk0 = computeManager.Disks .Define(diskName) .WithRegion(Location) .WithExistingResourceGroup(rgName) .WithData() .WithSizeInGB(32) .Create(); var vmEnumerator = virtualMachines.GetEnumerator(); vmEnumerator.MoveNext(); IVirtualMachineScaleSetVM vm0 = vmEnumerator.Current; vmEnumerator.MoveNext(); IVirtualMachineScaleSetVM vm1 = vmEnumerator.Current; int existDiskLun = 2; int newDiskLun = 10; // cannot detach non-exist disk Assert.Throws <InvalidOperationException>( () => vm0.Update().WithoutDataDisk(newDiskLun) ); // cannot detach disk from VMSS model Assert.Throws <InvalidOperationException>( () => vm0.Update().WithoutDataDisk(existDiskLun) ); // cannot attach disk with same lun Assert.Throws <InvalidOperationException>( () => vm0.Update().WithExistingDataDisk(disk0, existDiskLun, CachingTypes.None) ); // cannot attach disk with same lun Assert.Throws <InvalidOperationException>( () => vm0.Update().WithExistingDataDisk(disk0, newDiskLun, CachingTypes.None).WithExistingDataDisk(disk0, newDiskLun, CachingTypes.None) ); // attach disk int vmssModelDiskCount = vm0.DataDisks.Count; vm0.Update() .WithExistingDataDisk(disk0, newDiskLun, CachingTypes.ReadWrite) .Apply(); Assert.Equal(vmssModelDiskCount + 1, vm0.DataDisks.Count); // cannot attach disk that already attached disk0.Refresh(); Assert.Throws <InvalidOperationException>( () => vm1.Update() .WithExistingDataDisk(disk0, newDiskLun, CachingTypes.None) .Apply() ); // detach disk vm0.Update() .WithoutDataDisk(newDiskLun) .Apply(); Assert.Equal(vmssModelDiskCount, vm0.DataDisks.Count); } finally { try { resourceManager.ResourceGroups.DeleteByName(rgName); } catch { } } } }
public void CanCreateUpdateFromPIRWithManagedDisk() { using (var context = FluentMockContext.Start(GetType().FullName)) { var vmssName = SdkContext.RandomResourceName("vmss", 10); var resourceManager = TestHelper.CreateRollupClient(); var computeManager = TestHelper.CreateComputeManager(); var networkManager = TestHelper.CreateNetworkManager(); var rgName = TestUtilities.GenerateName("rgfluentchash-"); try { var resourceGroup = resourceManager.ResourceGroups .Define(rgName) .WithRegion(Location) .Create(); var network = networkManager .Networks .Define(SdkContext.RandomResourceName("vmssvnet", 15)) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithAddressSpace("10.0.0.0/28") .WithSubnet("subnet1", "10.0.0.0/28") .Create(); var publicLoadBalancer = ScaleSet.CreateHttpLoadBalancers(resourceManager, resourceGroup, "1", Location); var vmScaleSet = computeManager.VirtualMachineScaleSets .Define(vmssName) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithSku(VirtualMachineScaleSetSkuTypes.StandardD5v2) .WithExistingPrimaryNetworkSubnet(network, "subnet1") .WithExistingPrimaryInternetFacingLoadBalancer(publicLoadBalancer) .WithoutPrimaryInternalLoadBalancer() .WithPopularLinuxImage(KnownLinuxVirtualMachineImage.UbuntuServer16_04_Lts) .WithRootUsername("jvuser") .WithRootPassword("123OData!@#123") .WithNewDataDisk(100) .WithNewDataDisk(100, 1, CachingTypes.ReadWrite) .WithNewDataDisk(100, 2, CachingTypes.ReadOnly) .Create(); var virtualMachineScaleSetVMs = vmScaleSet.VirtualMachines; var virtualMachines = virtualMachineScaleSetVMs.List(); Assert.Equal(virtualMachines.Count(), vmScaleSet.Capacity); foreach (var vm in virtualMachines) { Assert.True(vm.IsOSBasedOnPlatformImage); Assert.False(vm.IsOSBasedOnCustomImage); Assert.False(vm.IsOSBasedOnStoredImage); Assert.True(vm.IsManagedDiskEnabled); Assert.NotNull(vm.UnmanagedDataDisks); Assert.Empty(vm.UnmanagedDataDisks); Assert.NotNull(vm.DataDisks); Assert.Equal(3, vm.DataDisks.Count); } vmScaleSet.Update() .WithoutDataDisk(0) .WithNewDataDisk(50) .Apply(); virtualMachineScaleSetVMs = vmScaleSet.VirtualMachines; virtualMachines = virtualMachineScaleSetVMs.List(); Assert.Equal(virtualMachines.Count(), vmScaleSet.Capacity); foreach (var vm in virtualMachines) { Assert.NotNull(vm.DataDisks); Assert.Equal(3, vm.DataDisks.Count); } } finally { try { resourceManager.ResourceGroups.DeleteByName(rgName); } catch { } } } }
public Func <RegionalContext, IRegionalEndpoint> BuildVMScaleSetApp(GlobalContext context) { var options = (CustomResourceOptions)ResourceOptions.Merge(context.Options, new CustomResourceOptions { DeleteBeforeReplace = true }); var file = File.ReadAllText("./vm/vmCustomData.yaml"); return((RegionalContext region) => { var location = region.Location; var domainName = $"rnddnplm{location}"; //TODO: random var publicIp = new PublicIp($"pip-{location}", new PublicIpArgs { ResourceGroupName = resourceGroup.Name, Location = location, AllocationMethod = "Static", DomainNameLabel = domainName, }, options); var loadBalancer = new LoadBalancer($"lb-{location}", new LoadBalancerArgs { ResourceGroupName = resourceGroup.Name, Location = location, FrontendIpConfigurations = { new LoadBalancerFrontendIpConfigurationsArgs { Name = "PublicIPAddress", PublicIpAddressId = publicIp.Id, } } }, options); var bpepool = new BackendAddressPool($"bap-{location}", new BackendAddressPoolArgs { ResourceGroupName = resourceGroup.Name, LoadbalancerId = loadBalancer.Id, }, options); var probe = new Probe($"ssh-probe-{location}".Truncate(16), new ProbeArgs { ResourceGroupName = resourceGroup.Name, LoadbalancerId = loadBalancer.Id, Port = 80, }, options); var rule = new Rule($"rule-{location}", new RuleArgs { ResourceGroupName = resourceGroup.Name, BackendAddressPoolId = bpepool.Id, BackendPort = 80, FrontendIpConfigurationName = "PublicIPAddress", FrontendPort = 80, LoadbalancerId = loadBalancer.Id, ProbeId = probe.Id, Protocol = "Tcp", }, options); var vnet = new VirtualNetwork($"vnet-{location}", new VirtualNetworkArgs { ResourceGroupName = resourceGroup.Name, Location = location, AddressSpaces = { "10.0.0.0/16" }, }, options); var subnet = new Subnet($"subnet-{location}", new SubnetArgs { ResourceGroupName = resourceGroup.Name, AddressPrefix = "10.0.2.0/24", VirtualNetworkName = vnet.Name, }, options); var customData = Output.All <string>(context.CosmosAccount.Endpoint, context.CosmosAccount.PrimaryMasterKey, context.Database.Name, context.Container.Name) .Apply(values => { return file.Replace("${ENDPOINT}", values[0]) .Replace("${MASTER_KEY}", values[1]) .Replace("${DATABASE}", values[2]) .Replace("${COLLECTION}", values[3]) .Replace("${LOCATION}", location); }); var scaleSet = new ScaleSet($"vmss-{location}", new ScaleSetArgs { ResourceGroupName = resourceGroup.Name, Location = location, NetworkProfiles = { new ScaleSetNetworkProfilesArgs { IpConfigurations = { new ScaleSetNetworkProfilesIpConfigurationsArgs { LoadBalancerBackendAddressPoolIds ={ bpepool.Id }, Name = "IPConfiguration", Primary = true, SubnetId = subnet.Id, } }, Name = "networkprofile", Primary = true, } }, OsProfile = new ScaleSetOsProfileArgs { AdminUsername = "******", AdminPassword = "******", ComputerNamePrefix = "lab", CustomData = customData, }, OsProfileLinuxConfig = new ScaleSetOsProfileLinuxConfigArgs { DisablePasswordAuthentication = false }, Sku = new ScaleSetSkuArgs { Capacity = 1, Name = "Standard_DS1_v2", Tier = "Standard", }, StorageProfileDataDisks = { new ScaleSetStorageProfileDataDisksArgs { Caching = "ReadWrite", CreateOption = "Empty", DiskSizeGb = 10, Lun = 0, } }, StorageProfileImageReference = new ScaleSetStorageProfileImageReferenceArgs { Offer = "UbuntuServer", Publisher = "Canonical", Sku = "18.04-LTS", Version = "latest", }, StorageProfileOsDisk = new ScaleSetStorageProfileOsDiskArgs { Caching = "ReadWrite", CreateOption = "FromImage", ManagedDiskType = "Standard_LRS", Name = "", }, UpgradePolicyMode = "Automatic", }, (CustomResourceOptions)ResourceOptions.Merge(options, new ResourceOptions { DependsOn = { bpepool, rule } })); var autoscale = new AutoscaleSetting($"as-{location}", new AutoscaleSettingArgs { ResourceGroupName = resourceGroup.Name, Location = location, Notification = new AutoscaleSettingNotificationArgs { Email = new AutoscaleSettingNotificationEmailArgs { CustomEmails = { "*****@*****.**" }, SendToSubscriptionAdministrator = true, SendToSubscriptionCoAdministrator = true, }, }, Profiles = { new AutoscaleSettingProfilesArgs { Capacity = new AutoscaleSettingProfilesCapacityArgs { Default = 1, Maximum = 10, Minimum = 1, }, Name = "defaultProfile", Rules = { new AutoscaleSettingProfilesRulesArgs { MetricTrigger = new AutoscaleSettingProfilesRulesMetricTriggerArgs { MetricName = "Percentage CPU", MetricResourceId = scaleSet.Id, Operator = "GreaterThan", Statistic = "Average", Threshold = 75, TimeAggregation = "Average", TimeGrain = "PT1M", TimeWindow = "PT5M", }, ScaleAction = new AutoscaleSettingProfilesRulesScaleActionArgs { Cooldown = "PT1M", Direction = "Increase", Type = "ChangeCount", Value = 1, }, }, new AutoscaleSettingProfilesRulesArgs { MetricTrigger = new AutoscaleSettingProfilesRulesMetricTriggerArgs { MetricName = "Percentage CPU", MetricResourceId = scaleSet.Id, Operator = "LessThan", Statistic = "Average", Threshold = 25, TimeAggregation = "Average", TimeGrain = "PT1M", TimeWindow = "PT5M", }, ScaleAction = new AutoscaleSettingProfilesRulesScaleActionArgs { Cooldown = "PT1M", Direction = "Decrease", Type = "ChangeCount", Value = 1, }, }, } } }, TargetResourceId = scaleSet.Id, }, options); return new AzureEndpoint(publicIp.Id); }); }
public void CanEnableWithCreatableStorageOnManagedVMSSCreation() { using (var context = FluentMockContext.Start(GetType().FullName)) { var vmssName = SdkContext.RandomResourceName("vmss", 10); var resourceManager = TestHelper.CreateRollupClient(); var computeManager = TestHelper.CreateComputeManager(); var networkManager = TestHelper.CreateNetworkManager(); var storageManager = TestHelper.CreateStorageManager(); var rgName = TestUtilities.GenerateName("rgvmss-"); var storageName = TestUtilities.GenerateName("stg"); try { var resourceGroup = resourceManager.ResourceGroups .Define(rgName) .WithRegion(Location) .Create(); var network = networkManager.Networks .Define("vmssvnet") .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithAddressSpace("10.0.0.0/28") .WithSubnet("subnet1", "10.0.0.0/28") .Create(); var publicLoadBalancer = ScaleSet.CreateInternetFacingLoadBalancer(resourceManager, resourceGroup, "1", LoadBalancerSkuType.Basic, Location); List <String> backends = new List <string>(); foreach (String backend in publicLoadBalancer.Backends.Keys) { backends.Add(backend); } Assert.True(backends.Count == 2); var creatableStorageAccount = storageManager.StorageAccounts .Define(storageName) .WithRegion(Location) .WithExistingResourceGroup(rgName); var virtualMachineScaleSet = computeManager.VirtualMachineScaleSets .Define(vmssName) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithSku(VirtualMachineScaleSetSkuTypes.StandardA0) .WithExistingPrimaryNetworkSubnet(network, "subnet1") .WithExistingPrimaryInternetFacingLoadBalancer(publicLoadBalancer) .WithPrimaryInternetFacingLoadBalancerBackends(backends[0], backends[1]) .WithoutPrimaryInternalLoadBalancer() .WithPopularLinuxImage(KnownLinuxVirtualMachineImage.UbuntuServer16_04_Lts) .WithRootUsername("jvuser") .WithRootPassword("123OData!@#123") .WithBootDiagnostics(creatableStorageAccount) .Create(); Assert.NotNull(virtualMachineScaleSet); Assert.True(virtualMachineScaleSet.IsBootDiagnosticsEnabled); Assert.NotNull(virtualMachineScaleSet.BootDiagnosticsStorageUri); Assert.Contains(storageName, virtualMachineScaleSet.BootDiagnosticsStorageUri); } finally { try { resourceManager.ResourceGroups.DeleteByName(rgName); } catch { } } } }
public void CanEnableWithCreatableStorageOnUnManagedVMSSCreation() { using (var context = FluentMockContext.Start(GetType().FullName)) { var vmssName = SdkContext.RandomResourceName("vmss", 10); var resourceManager = TestHelper.CreateRollupClient(); var computeManager = TestHelper.CreateComputeManager(); var networkManager = TestHelper.CreateNetworkManager(); var storageManager = TestHelper.CreateStorageManager(); var rgName = TestUtilities.GenerateName("rgvmss-"); var storageName = TestUtilities.GenerateName("stg"); try { var resourceGroup = resourceManager.ResourceGroups .Define(rgName) .WithRegion(Location) .Create(); var network = networkManager.Networks .Define("vmssvnet") .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithAddressSpace("10.0.0.0/28") .WithSubnet("subnet1", "10.0.0.0/28") .Create(); var publicLoadBalancer = ScaleSet.CreateInternetFacingLoadBalancer(resourceManager, resourceGroup, "1", LoadBalancerSkuType.Basic, Location); List <String> backends = new List <string>(); foreach (String backend in publicLoadBalancer.Backends.Keys) { backends.Add(backend); } Assert.True(backends.Count == 2); var creatableStorageAccount = storageManager.StorageAccounts .Define(storageName) .WithRegion(Location) .WithExistingResourceGroup(rgName); var virtualMachineScaleSet = computeManager.VirtualMachineScaleSets .Define(vmssName) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithSku(VirtualMachineScaleSetSkuTypes.StandardA0) .WithExistingPrimaryNetworkSubnet(network, "subnet1") .WithExistingPrimaryInternetFacingLoadBalancer(publicLoadBalancer) .WithPrimaryInternetFacingLoadBalancerBackends(backends[0], backends[1]) .WithoutPrimaryInternalLoadBalancer() .WithPopularLinuxImage(KnownLinuxVirtualMachineImage.UbuntuServer16_04_Lts) .WithRootUsername("jvuser") .WithRootPassword("123OData!@#123") .WithUnmanagedDisks() .WithBootDiagnostics(creatableStorageAccount) // This storage account should be used for BDiagnostics not OS disk storage account .Create(); Assert.NotNull(virtualMachineScaleSet); Assert.True(virtualMachineScaleSet.IsBootDiagnosticsEnabled); Assert.NotNull(virtualMachineScaleSet.BootDiagnosticsStorageUri); Assert.Contains(storageName, virtualMachineScaleSet.BootDiagnosticsStorageUri); // There should be a different storage account created for VMSS OS Disk var inner = virtualMachineScaleSet.Inner; Assert.NotNull(inner); Assert.NotNull(inner.VirtualMachineProfile); Assert.NotNull(inner.VirtualMachineProfile.StorageProfile); Assert.NotNull(inner.VirtualMachineProfile.StorageProfile.OsDisk); var containers = inner.VirtualMachineProfile.StorageProfile.OsDisk.VhdContainers; Assert.False(containers.Count() == 0); bool notFound = true; foreach (var containerStorageUri in containers) { if (containerStorageUri.StartsWith(virtualMachineScaleSet.BootDiagnosticsStorageUri, StringComparison.OrdinalIgnoreCase)) { notFound = false; break; } } Assert.True(notFound); } finally { try { resourceManager.ResourceGroups.DeleteByName(rgName); } catch { } } } }
public VmScalesetStack() { var applicationPort = 80; var resourceGroup = new ResourceGroup("vmss-rg"); var network = new VirtualNetwork("vnet", new VirtualNetworkArgs { ResourceGroupName = resourceGroup.Name, AddressSpaces = { "10.0.0.0/16" } } ); var subnet = new Subnet("subnet", new SubnetArgs { ResourceGroupName = resourceGroup.Name, Name = "default", AddressPrefixes = "10.0.1.0/24", VirtualNetworkName = network.Name }); var publicIp = new PublicIp("public-ip", new PublicIpArgs { ResourceGroupName = resourceGroup.Name, AllocationMethod = "Dynamic" }); var lb = new LoadBalancer("lb", new LoadBalancerArgs { ResourceGroupName = resourceGroup.Name, FrontendIpConfigurations = new List <LoadBalancerFrontendIpConfigurationArgs> { new LoadBalancerFrontendIpConfigurationArgs { Name = "PublicIPAddress", PublicIpAddressId = publicIp.Id } } }); var bpePool = new BackendAddressPool("bpepool", new BackendAddressPoolArgs { ResourceGroupName = resourceGroup.Name, LoadbalancerId = lb.Id, }); var sshProbe = new Probe("ssh-probe", new ProbeArgs { ResourceGroupName = resourceGroup.Name, LoadbalancerId = lb.Id, Port = applicationPort, }); var natRule = new Rule("lbnatrule-http", new RuleArgs { ResourceGroupName = resourceGroup.Name, BackendAddressPoolId = bpePool.Id, BackendPort = applicationPort, FrontendIpConfigurationName = "PublicIPAddress", FrontendPort = applicationPort, LoadbalancerId = lb.Id, ProbeId = sshProbe.Id, Protocol = "Tcp", }); var scaleSet = new ScaleSet("vmscaleset", new ScaleSetArgs { ResourceGroupName = resourceGroup.Name, NetworkProfiles = new ScaleSetNetworkProfileArgs { IpConfigurations = new ScaleSetNetworkProfileIpConfigurationArgs[] { new ScaleSetNetworkProfileIpConfigurationArgs { LoadBalancerBackendAddressPoolIds = bpePool.Id, Name = "IPConfiguration", Primary = true, SubnetId = subnet.Id, } }, Name = "networkprofile", Primary = true }, OsProfile = new ScaleSetOsProfileArgs { ComputerNamePrefix = "vmlab", AdminUsername = "******", AdminPassword = "******", CustomData = @"#!/bin/bash echo ""Hello, World by $HOSTNAME!"" > index.html nohup python -m SimpleHTTPServer 80 &" }, OsProfileLinuxConfig = new ScaleSetOsProfileLinuxConfigArgs { DisablePasswordAuthentication = false }, Sku = new ScaleSetSkuArgs { Capacity = 1, Name = "Standard_DS1_v2", Tier = "Standard", }, StorageProfileOsDisk = new ScaleSetStorageProfileOsDiskArgs { Caching = "ReadWrite", CreateOption = "FromImage", ManagedDiskType = "Standard_LRS", Name = "" }, StorageProfileDataDisks = new ScaleSetStorageProfileDataDiskArgs { Caching = "ReadWrite", CreateOption = "Empty", DiskSizeGb = 10, Lun = 0 }, StorageProfileImageReference = new ScaleSetStorageProfileImageReferenceArgs { Offer = "UbuntuServer", Publisher = "Canonical", Sku = "16.04-LTS", Version = "latest", }, UpgradePolicyMode = "Manual" }, new CustomResourceOptions { DeleteBeforeReplace = true, DependsOn = bpePool }); var autoscale = new AutoscaleSetting("vmss-autoscale", new AutoscaleSettingArgs { ResourceGroupName = resourceGroup.Name, Notification = new AutoscaleSettingNotificationArgs { Email = new AutoscaleSettingNotificationEmailArgs { CustomEmails = new string[] { "*****@*****.**" }, SendToSubscriptionAdministrator = true, SendToSubscriptionCoAdministrator = true, }, }, Profiles = new AutoscaleSettingProfileArgs[] { new AutoscaleSettingProfileArgs { Capacity = new AutoscaleSettingProfileCapacityArgs { Default = 2, Maximum = 10, Minimum = 2, }, Name = "defaultProfile", Rules = new AutoscaleSettingProfileRuleArgs[] { new AutoscaleSettingProfileRuleArgs { MetricTrigger = new AutoscaleSettingProfileRuleMetricTriggerArgs { MetricName = "Percentage CPU", MetricResourceId = scaleSet.Id, Operator = "GreaterThan", Statistic = "Average", Threshold = 75, TimeAggregation = "Average", TimeGrain = "PT1M", TimeWindow = "PT5M", }, ScaleAction = new AutoscaleSettingProfileRuleScaleActionArgs { Cooldown = "PT1M", Direction = "Increase", Type = "ChangeCount", Value = 1, }, }, new AutoscaleSettingProfileRuleArgs { MetricTrigger = new AutoscaleSettingProfileRuleMetricTriggerArgs { MetricName = "Percentage CPU", MetricResourceId = scaleSet.Id, Operator = "LessThan", Statistic = "Average", Threshold = 25, TimeAggregation = "Average", TimeGrain = "PT1M", TimeWindow = "PT5M", }, ScaleAction = new AutoscaleSettingProfileRuleScaleActionArgs { Cooldown = "PT1M", Direction = "Decrease", Type = "ChangeCount", Value = 1, }, } } } }, TargetResourceId = scaleSet.Id }); // The public IP address is not allocated until the VM is running, so wait for that // resource to create, and then lookup the IP address again to report its public IP. this.IpAddress = Output .Tuple <string, string, string>(scaleSet.Id, publicIp.Name, resourceGroup.Name) .Apply <string>(async t => { (_, string name, string resourceGroupName) = t; var ip = await GetPublicIP.InvokeAsync(new GetPublicIPArgs { Name = name, ResourceGroupName = resourceGroupName }); return(ip.IpAddress); }); }
public MyStack() { // Retrieve options from config, optionally using defaults var config = new Pulumi.Config(); var region = config.Get("region") ?? "CentralUS"; // App Gateway Options InputList <string> addressSpace = (config.Get("addressSpace") ?? "10.0.0.0/16").Split(','); var privateSubnetPrefix = config.Get("privateSubnet") ?? "10.0.2.0/24"; var publicSubnetPrefix = config.Get("publicSubnet") ?? "10.0.1.0/24"; var dnsPrefix = config.Get("dnsPrefix") ?? "aspnettodo"; var backendPort = config.GetInt32("backendPort") ?? 80; var backendProtocol = config.Get("backendProtocol") ?? "HTTP"; var frontendPort = config.GetInt32("frontendPort") ?? backendPort; var frontendProtocol = config.Get("frontendProtocol") ?? backendProtocol; // VMSS options var instanceCount = config.GetInt32("instanceCount") ?? 2; InputList <string> zones = (config.Get("zones") ?? "1,2").Split(','); var instanceSize = config.Get("instanceSize") ?? "Standard_B1s"; var instanceNamePrefix = config.Get("instanceNamePrefix") ?? "web"; var adminUser = config.Get("adminUser") ?? "webadmin"; var adminPassword = config.Get("adminPassword"); // Create an Azure Resource Group var resourceGroup = new ResourceGroup($"{stackId}-rg", new ResourceGroupArgs { Location = region }); // Create Networking components var vnet = new VirtualNetwork($"{stackId}-vnet", new VirtualNetworkArgs { ResourceGroupName = resourceGroup.Name, AddressSpaces = addressSpace }); // Create a private subnet for the VMSS var privateSubnet = new Subnet($"{stackId}-privateSubnet", new SubnetArgs { ResourceGroupName = resourceGroup.Name, AddressPrefix = privateSubnetPrefix, VirtualNetworkName = vnet.Name }); // Create a public subnet for the Application Gateway var publicSubnet = new Subnet($"{stackId}-publicSubnet", new SubnetArgs { ResourceGroupName = resourceGroup.Name, AddressPrefix = publicSubnetPrefix, VirtualNetworkName = vnet.Name }); // Create a public IP and App Gateway var publicIp = new PublicIp($"{stackId}-pip", new PublicIpArgs { ResourceGroupName = resourceGroup.Name, Sku = "Basic", AllocationMethod = "Dynamic", DomainNameLabel = dnsPrefix }, new CustomResourceOptions { DeleteBeforeReplace = true }); var appGw = new ApplicationGateway($"{stackId}-appgw", new ApplicationGatewayArgs { ResourceGroupName = resourceGroup.Name, Sku = new ApplicationGatewaySkuArgs { Tier = "Standard", Name = "Standard_Small", Capacity = 1 }, FrontendIpConfigurations = new InputList <Pulumi.Azure.Network.Inputs.ApplicationGatewayFrontendIpConfigurationsArgs> { new Pulumi.Azure.Network.Inputs.ApplicationGatewayFrontendIpConfigurationsArgs { Name = $"{stackId}-appgw-ipconfig-0", PublicIpAddressId = publicIp.Id, } }, FrontendPorts = new InputList <Pulumi.Azure.Network.Inputs.ApplicationGatewayFrontendPortsArgs> { new Pulumi.Azure.Network.Inputs.ApplicationGatewayFrontendPortsArgs { Name = $"Port{frontendPort}", Port = frontendPort } }, BackendAddressPools = new InputList <Pulumi.Azure.Network.Inputs.ApplicationGatewayBackendAddressPoolsArgs> { new Pulumi.Azure.Network.Inputs.ApplicationGatewayBackendAddressPoolsArgs { Name = $"{stackId}-bepool-0", } }, BackendHttpSettings = new InputList <ApplicationGatewayBackendHttpSettingsArgs> { new ApplicationGatewayBackendHttpSettingsArgs { Name = $"{backendProtocol}Settings", Protocol = backendProtocol, Port = backendPort, CookieBasedAffinity = "Disabled" } }, GatewayIpConfigurations = new InputList <ApplicationGatewayGatewayIpConfigurationsArgs> { new ApplicationGatewayGatewayIpConfigurationsArgs { Name = "IPConfiguration", SubnetId = publicSubnet.Id } }, HttpListeners = new InputList <ApplicationGatewayHttpListenersArgs> { new ApplicationGatewayHttpListenersArgs { Name = $"{frontendProtocol}Listener", Protocol = frontendProtocol, FrontendIpConfigurationName = $"{stackId}-appgw-ipconfig-0", FrontendPortName = $"Port{frontendPort}" } }, RequestRoutingRules = new InputList <ApplicationGatewayRequestRoutingRulesArgs> { new ApplicationGatewayRequestRoutingRulesArgs { Name = "Default", BackendAddressPoolName = $"{stackId}-bepool-0", HttpListenerName = $"{frontendProtocol}Listener", RuleType = "Basic", BackendHttpSettingsName = $"{backendProtocol}Settings" } } }); // Create the scale set var scaleSet = new ScaleSet($"{stackId}-vmss", new ScaleSetArgs { ResourceGroupName = resourceGroup.Name, Location = resourceGroup.Location, Zones = new InputList <string> { "1", "2" }, NetworkProfiles = { new ScaleSetNetworkProfilesArgs { AcceleratedNetworking = false, IpConfigurations = { new ScaleSetNetworkProfilesIpConfigurationsArgs { Name = "IPConfiguration", Primary = true, SubnetId = privateSubnet.Id, // Associate scaleset with app gateway ApplicationGatewayBackendAddressPoolIds = new InputList <string> { appGw.BackendAddressPools.Apply(bePools => bePools[0].Id) } } }, Name = "networkprofile", Primary = true } }, OsProfile = new ScaleSetOsProfileArgs { AdminUsername = adminUser, AdminPassword = adminPassword, ComputerNamePrefix = instanceNamePrefix }, Sku = new ScaleSetSkuArgs { Capacity = instanceCount, Name = instanceSize, Tier = "Standard", }, StorageProfileImageReference = new ScaleSetStorageProfileImageReferenceArgs { Offer = "WindowsServer", Publisher = "MicrosoftWindowsServer", Sku = "2019-Datacenter-Core", Version = "latest", }, StorageProfileOsDisk = new ScaleSetStorageProfileOsDiskArgs { Caching = "ReadWrite", CreateOption = "FromImage", ManagedDiskType = "Standard_LRS", Name = "", }, // Enable VM agent and script extension UpgradePolicyMode = "Automatic", OsProfileWindowsConfig = new ScaleSetOsProfileWindowsConfigArgs { ProvisionVmAgent = true }, Extensions = new InputList <ScaleSetExtensionsArgs> { new ScaleSetExtensionsArgs { Publisher = "Microsoft.Compute", Name = "IIS-Script-Extension", Type = "CustomScriptExtension", TypeHandlerVersion = "1.4", // Settings is a JSON string // This command uses powershell to install windows webserver features Settings = "{\"commandToExecute\":\"powershell Add-WindowsFeature Web-Server,Web-Asp-Net45,NET-Framework-Features\"}" } } }); this.PublicUrl = publicIp.Fqdn; }
public void ShouldUsesVMSSOSUnManagedDiskImplicitStorage() { using (var context = FluentMockContext.Start(GetType().FullName)) { var vmssName = SdkContext.RandomResourceName("vmss", 10); var resourceManager = TestHelper.CreateRollupClient(); var computeManager = TestHelper.CreateComputeManager(); var networkManager = TestHelper.CreateNetworkManager(); var rgName = TestUtilities.GenerateName("rgvmss-"); try { var resourceGroup = resourceManager.ResourceGroups .Define(rgName) .WithRegion(Location) .Create(); var network = networkManager.Networks .Define("vmssvnet") .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithAddressSpace("10.0.0.0/28") .WithSubnet("subnet1", "10.0.0.0/28") .Create(); var publicLoadBalancer = ScaleSet.CreateInternetFacingLoadBalancer(resourceManager, resourceGroup, "1", LoadBalancerSkuType.Basic, Location); List <String> backends = new List <string>(); foreach (String backend in publicLoadBalancer.Backends.Keys) { backends.Add(backend); } Assert.True(backends.Count == 2); var virtualMachineScaleSet = computeManager.VirtualMachineScaleSets .Define(vmssName) .WithRegion(Location) .WithExistingResourceGroup(resourceGroup) .WithSku(VirtualMachineScaleSetSkuTypes.StandardA0) .WithExistingPrimaryNetworkSubnet(network, "subnet1") .WithExistingPrimaryInternetFacingLoadBalancer(publicLoadBalancer) .WithPrimaryInternetFacingLoadBalancerBackends(backends[0], backends[1]) .WithoutPrimaryInternalLoadBalancer() .WithPopularLinuxImage(KnownLinuxVirtualMachineImage.UbuntuServer16_04_Lts) .WithRootUsername("jvuser") .WithRootPassword(TestUtilities.GenerateName("Pa5$")) .WithUnmanagedDisks() .WithBootDiagnostics() .Create(); Assert.NotNull(virtualMachineScaleSet); Assert.True(virtualMachineScaleSet.IsBootDiagnosticsEnabled); Assert.NotNull(virtualMachineScaleSet.BootDiagnosticsStorageUri); var inner = virtualMachineScaleSet.Inner; Assert.NotNull(inner); Assert.NotNull(inner.VirtualMachineProfile); Assert.NotNull(inner.VirtualMachineProfile.StorageProfile); Assert.NotNull(inner.VirtualMachineProfile.StorageProfile.OsDisk); var containers = inner.VirtualMachineProfile.StorageProfile.OsDisk.VhdContainers; Assert.False(containers.Count == 0); // Boot diagnostics should share storage used for os/disk containers bool found = containers.Any(containerStorageUri => containerStorageUri.StartsWith(virtualMachineScaleSet.BootDiagnosticsStorageUri, StringComparison.OrdinalIgnoreCase)); Assert.True(found); } finally { try { resourceManager.ResourceGroups.DeleteByName(rgName); } catch { } } } }