/** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for * license information. */ package com.microsoft.azure.management.compute.samples; import com.jcraft.jsch.JSchException; import com.microsoft.azure.management.Azure; import com.microsoft.azure.management.compute.CachingTypes; import com.microsoft.azure.management.compute.Disk; import com.microsoft.azure.management.compute.DiskSkuTypes; import com.microsoft.azure.management.compute.KnownLinuxVirtualMachineImage; import com.microsoft.azure.management.compute.OperatingSystemTypes; import com.microsoft.azure.management.compute.Snapshot; import com.microsoft.azure.management.compute.VirtualMachine; import com.microsoft.azure.management.compute.VirtualMachineCustomImage; import com.microsoft.azure.management.compute.VirtualMachineDataDisk; import com.microsoft.azure.management.compute.VirtualMachineScaleSet; import com.microsoft.azure.management.compute.VirtualMachineScaleSetSkuTypes; import com.microsoft.azure.management.compute.VirtualMachineSizeTypes; import com.microsoft.azure.management.network.LoadBalancer; import com.microsoft.azure.management.network.Network; import com.microsoft.azure.management.network.PublicIPAddress; import com.microsoft.azure.management.network.TransportProtocol; import com.microsoft.azure.management.resources.fluentcore.arm.Region; import com.microsoft.azure.management.resources.fluentcore.utils.SdkContext; import com.microsoft.azure.management.samples.SSHShell; import com.microsoft.azure.management.samples.Utils; import com.microsoft.rest.LogLevel; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * This is sample will not be published, this is just to ensure out blog is honest. */ public final class ManageManagedDisks { /** * Main function which runs the actual sample. * @param azure instance of the azure client * @return true if sample runs successfully */ public static boolean runSample(Azure azure) { final Region region = Region.US_EAST; final String rgName = Utils.createRandomName("rgCOMV"); final String userName = "tirekicker"; final String sshkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCfSPC2K7LZcFKEO+/t3dzmQYtrJFZNxOsbVgOVKietqHyvmYGHEC0J2wPdAqQ/63g/hhAEFRoyehM+rbeDri4txB3YFfnOK58jqdkyXzupWqXzOrlKY4Wz9SKjjN765+dqUITjKRIaAip1Ri137szRg71WnrmdP3SphTRlCx1Bk2nXqWPsclbRDCiZeF8QOTi4JqbmJyK5+0UqhqYRduun8ylAwKKQJ1NJt85sYIHn9f1Rfr6Tq2zS0wZ7DHbZL+zB5rSlAr8QyUdg/GQD+cmSs6LvPJKL78d6hMGk84ARtFo4A79ovwX/Fj01znDQkU6nJildfkaolH2rWFG/qttD azjava@javalib.com"; try { // ::==Create a VM // Create a virtual machine with an implicit Managed OS disk and explicit Managed data disk System.out.println("Creating VM [with an implicit Managed OS disk and explicit Managed data disk]"); final String linuxVM1Name = SdkContext.randomResourceName("vm" + "-", 18); final String linuxVM1Pip = SdkContext.randomResourceName("pip" + "-", 18); VirtualMachine linuxVM1 = azure.virtualMachines() .define(linuxVM1Name) .withRegion(region) .withNewResourceGroup(rgName) .withNewPrimaryNetwork("10.0.0.0/28") .withPrimaryPrivateIPAddressDynamic() .withNewPrimaryPublicIPAddress(linuxVM1Pip) .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_16_04_LTS) .withRootUsername(userName) .withSsh(sshkey) .withNewDataDisk(100) .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) .create(); System.out.println("Created VM [with an implicit Managed OS disk and explicit Managed data disk]"); // Creation is simplified with implicit creation of managed disks without specifying all the disk details. You will notice that you do not require storage accounts // ::== Update the VM // Create a VMSS with implicit managed OS disks and explicit managed data disks System.out.println("Creating VMSS [with implicit managed OS disks and explicit managed data disks]"); final String vmScaleSetName = SdkContext.randomResourceName("vmss" + "-", 18); VirtualMachineScaleSet vmScaleSet = azure.virtualMachineScaleSets() .define(vmScaleSetName) .withRegion(region) .withExistingResourceGroup(rgName) .withSku(VirtualMachineScaleSetSkuTypes.STANDARD_D5_V2) .withExistingPrimaryNetworkSubnet(prepareNetwork(azure, region, rgName), "subnet1") .withExistingPrimaryInternetFacingLoadBalancer(prepareLoadBalancer(azure, region, rgName)) .withoutPrimaryInternalLoadBalancer() .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_16_04_LTS) .withRootUsername("tirekicker") .withSsh(sshkey) .withNewDataDisk(100) .withNewDataDisk(100, 1, CachingTypes.READ_WRITE) .withNewDataDisk(100, 2, CachingTypes.READ_ONLY) .withCapacity(3) .create(); System.out.println("Created VMSS [with implicit managed OS disks and explicit managed data disks]"); // Create an empty disk and attach to a VM (Manage Virtual Machine With Disk) System.out.println("Creating empty data disk [to attach to a VM]"); final String diskName = SdkContext.randomResourceName("dsk" + "-", 18); Disk dataDisk = azure.disks().define(diskName) .withRegion(region) .withExistingResourceGroup(rgName) .withData() .withSizeInGB(50) .create(); System.out.println("Created empty data disk [to attach to a VM]"); System.out.println("Creating VM [with new managed data disks and disk attached]"); final String linuxVM2Name = SdkContext.randomResourceName("vm" + "-", 10); final String linuxVM2Pip = SdkContext.randomResourceName("pip" + "-", 18); VirtualMachine linuxVM2 = azure.virtualMachines().define(linuxVM2Name) .withRegion(region) .withExistingResourceGroup(rgName) .withNewPrimaryNetwork("10.0.0.0/28") .withPrimaryPrivateIPAddressDynamic() .withNewPrimaryPublicIPAddress(linuxVM2Pip) .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_16_04_LTS) .withRootUsername(userName) .withSsh(sshkey) // Begin: Managed data disks .withNewDataDisk(100) .withNewDataDisk(100, 1, CachingTypes.READ_WRITE) .withExistingDataDisk(dataDisk) // End: Managed data disks .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) .create(); System.out.println("Created VM [with new managed data disks and disk attached]"); // Update a VM System.out.println("Updating VM [by detaching a disk and adding empty disk]"); linuxVM2.update() .withoutDataDisk(2) .withNewDataDisk(200) .apply(); System.out.println("Updated VM [by detaching a disk and adding empty disk]"); // Create a VM from an image (Create Virtual Machine Using Custom Image from VM) System.out.println("Preparing specialized virtual machine with un-managed disk"); final VirtualMachine linuxVM = prepareSpecializedUnmanagedVirtualMachine(azure, region, rgName); System.out.println("Prepared specialized virtual machine with un-managed disk"); System.out.println("Creating custom image from specialized virtual machine"); final String customImageName = SdkContext.randomResourceName("cimg" + "-", 10); VirtualMachineCustomImage virtualMachineCustomImage = azure.virtualMachineCustomImages() .define(customImageName) .withRegion(region) .withExistingResourceGroup(rgName) .fromVirtualMachine(linuxVM) // from a deallocated and generalized VM .create(); System.out.println("Created custom image from specialized virtual machine"); System.out.println("Creating VM [from custom image]"); final String linuxVM3Name = SdkContext.randomResourceName("vm" + "-", 10); VirtualMachine linuxVM3 = azure.virtualMachines().define(linuxVM3Name) .withRegion(region) .withExistingResourceGroup(rgName) .withNewPrimaryNetwork("10.0.0.0/28") .withPrimaryPrivateIPAddressDynamic() .withoutPrimaryPublicIPAddress() .withLinuxCustomImage(virtualMachineCustomImage.id()) .withRootUsername(userName) .withSsh(sshkey) .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) .create(); System.out.println("Created VM [from custom image]"); // Create a VM from a VHD (Create Virtual Machine Using Specialized VHD) final String linuxVMName4 = SdkContext.randomResourceName("vm" + "-", 10); final String specializedVhd = linuxVM.osUnmanagedDiskVhdUri(); azure.virtualMachines().deleteById(linuxVM.id()); System.out.println("Creating VM [by attaching un-managed disk]"); VirtualMachine linuxVM4 = azure.virtualMachines().define(linuxVMName4) .withRegion(region) .withExistingResourceGroup(rgName) .withNewPrimaryNetwork("10.0.0.0/28") .withPrimaryPrivateIPAddressDynamic() .withoutPrimaryPublicIPAddress() .withSpecializedOSUnmanagedDisk(specializedVhd, OperatingSystemTypes.LINUX) .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) .create(); System.out.println("Created VM [by attaching un-managed disk]"); // Create a Snapshot (Create Virtual Machine using specialized disks from snapshot) System.out.println("Preparing specialized virtual machine with managed disks"); final VirtualMachine linuxVM5 = prepareSpecializedManagedVirtualMachine(azure, region, rgName); Disk osDisk = azure.disks().getById(linuxVM5.osDiskId()); List<Disk> dataDisks = new ArrayList<>(); for (VirtualMachineDataDisk disk : linuxVM5.dataDisks().values()) { Disk d = azure.disks().getById(disk.id()); dataDisks.add(d); } System.out.println("Prepared specialized virtual machine with managed disks"); System.out.println("Deleting VM: " + linuxVM5.id()); azure.virtualMachines().deleteById(linuxVM5.id()); System.out.println("Deleted the VM: " + linuxVM5.id()); System.out.println("Creating snapshot [from managed OS disk]"); // Create a managed snapshot for an OS disk final String managedOSSnapshotName = SdkContext.randomResourceName("snp" + "-", 10); Snapshot osSnapshot = azure.snapshots().define(managedOSSnapshotName) .withRegion(region) .withExistingResourceGroup(rgName) .withLinuxFromDisk(osDisk) .create(); System.out.println("Created snapshot [from managed OS disk]"); System.out.println("Creating managed OS disk [from snapshot]"); // Create a managed disk from the managed snapshot for the OS disk final String managedNewOSDiskName = SdkContext.randomResourceName("dsk" + "-", 10); Disk newOSDisk = azure.disks().define(managedNewOSDiskName) .withRegion(region) .withExistingResourceGroup(rgName) .withLinuxFromSnapshot(osSnapshot) .withSizeInGB(100) .create(); System.out.println("Created managed OS disk [from snapshot]"); System.out.println("Creating managed data snapshot [from managed data disk]"); // Create a managed snapshot for a data disk final String managedDataDiskSnapshotName = SdkContext.randomResourceName("dsk" + "-", 10); Snapshot dataSnapshot = azure.snapshots().define(managedDataDiskSnapshotName) .withRegion(region) .withExistingResourceGroup(rgName) .withDataFromDisk(dataDisks.get(0)) .withSku(DiskSkuTypes.STANDARD_LRS) .create(); System.out.println("Created managed data snapshot [from managed data disk]"); System.out.println("Creating managed data disk [from managed snapshot]"); // Create a managed disk from the managed snapshot for the data disk final String managedNewDataDiskName = SdkContext.randomResourceName("dsk" + "-", 10); Disk newDataDisk = azure.disks().define(managedNewDataDiskName) .withRegion(region) .withExistingResourceGroup(rgName) .withData() .fromSnapshot(dataSnapshot) .create(); System.out.println("Created managed data disk [from managed snapshot]"); System.out.println("Creating VM [with specialized OS managed disk]"); final String linuxVM6Name = SdkContext.randomResourceName("vm" + "-", 10); VirtualMachine linuxVM6 = azure.virtualMachines().define(linuxVM6Name) .withRegion(region) .withExistingResourceGroup(rgName) .withNewPrimaryNetwork("10.0.0.0/28") .withPrimaryPrivateIPAddressDynamic() .withoutPrimaryPublicIPAddress() .withSpecializedOSDisk(newOSDisk, OperatingSystemTypes.LINUX) .withExistingDataDisk(newDataDisk) .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) .create(); System.out.println("Created VM [with specialized OS managed disk]"); // ::== Migrate a VM to managed disks with a single reboot System.out.println("Creating VM [with un-managed disk for migration]"); final String linuxVM7Name = SdkContext.randomResourceName("vm" + "-", 10); final String linuxVM7Pip = SdkContext.randomResourceName("pip" + "-", 18); VirtualMachine linuxVM7 = azure.virtualMachines().define(linuxVM7Name) .withRegion(region) .withNewResourceGroup(rgName) .withNewPrimaryNetwork("10.0.0.0/28") .withPrimaryPrivateIPAddressDynamic() .withNewPrimaryPublicIPAddress(linuxVM7Pip) .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_16_04_LTS) .withRootUsername("tirekicker") .withSsh(sshkey) .withUnmanagedDisks() // uses storage accounts .withNewUnmanagedDataDisk(100) .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) .create(); System.out.println("Created VM [with un-managed disk for migration]"); System.out.println("De-allocating VM :" + linuxVM7.id()); linuxVM7.deallocate(); System.out.println("De-allocated VM :" + linuxVM7.id()); System.out.println("Migrating VM"); linuxVM7.convertToManaged(); System.out.println("Migrated VM"); return true; } catch (Exception f) { System.out.println(f.getMessage()); f.printStackTrace(); } finally { try { System.out.println("Deleting Resource Group: " + rgName); azure.resourceGroups().deleteByName(rgName); System.out.println("Deleted Resource Group: " + rgName); } catch (NullPointerException npe) { System.out.println("Did not create any resources in Azure. No clean up is necessary"); } catch (Exception g) { g.printStackTrace(); } } return false; } /** * Main entry point. * @param args the parameters */ public static void main(String[] args) { try { //============================================================= // Authenticate final File credFile = new File(System.getenv("AZURE_AUTH_LOCATION")); Azure azure = Azure.configure() .withLogLevel(LogLevel.BASIC) .authenticate(credFile) .withDefaultSubscription(); // Print selected subscription System.out.println("Selected subscription: " + azure.subscriptionId()); runSample(azure); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } } private static VirtualMachine prepareSpecializedUnmanagedVirtualMachine(Azure azure, Region region, String rgName) { final String userName = "tirekicker"; final String password = "12NewPA$$w0rd!"; final String linuxVMName1 = SdkContext.randomResourceName("vm" + "-", 10); final String publicIpDnsLabel = SdkContext.randomResourceName("pip" + "-", 20); VirtualMachine linuxVM = azure.virtualMachines().define(linuxVMName1) .withRegion(region) .withNewResourceGroup(rgName) .withNewPrimaryNetwork("10.0.0.0/28") .withPrimaryPrivateIPAddressDynamic() .withNewPrimaryPublicIPAddress(publicIpDnsLabel) .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_16_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.STANDARD_D3_V2) .create(); // De-provision the virtual machine deprovisionAgentInLinuxVM(linuxVM.getPrimaryPublicIPAddress().fqdn(), 22, userName, password); System.out.println("Deallocate VM: " + linuxVM.id()); linuxVM.deallocate(); System.out.println("Deallocated VM: " + linuxVM.id() + "; state = " + linuxVM.powerState()); System.out.println("Generalize VM: " + linuxVM.id()); linuxVM.generalize(); System.out.println("Generalized VM: " + linuxVM.id()); return linuxVM; } private static VirtualMachine prepareSpecializedManagedVirtualMachine(Azure azure, Region region, String rgName) { final String userName = "tirekicker"; final String password = "12NewPA$$w0rd!"; final String linuxVMName1 = SdkContext.randomResourceName("vm" + "-", 10); final String publicIPDnsLabel = SdkContext.randomResourceName("pip" + "-", 20); VirtualMachine linuxVM = azure.virtualMachines().define(linuxVMName1) .withRegion(region) .withNewResourceGroup(rgName) .withNewPrimaryNetwork("10.0.0.0/28") .withPrimaryPrivateIPAddressDynamic() .withNewPrimaryPublicIPAddress(publicIPDnsLabel) .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_16_04_LTS) .withRootUsername(userName) .withRootPassword(password) .withNewDataDisk(100) .withNewDataDisk(200) .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) .create(); // De-provision the virtual machine deprovisionAgentInLinuxVM(linuxVM.getPrimaryPublicIPAddress().fqdn(), 22, userName, password); System.out.println("Deallocate VM: " + linuxVM.id()); linuxVM.deallocate(); System.out.println("Deallocated VM: " + linuxVM.id() + "; state = " + linuxVM.powerState()); System.out.println("Generalize VM: " + linuxVM.id()); linuxVM.generalize(); System.out.println("Generalized VM: " + linuxVM.id()); return linuxVM; } private static void deprovisionAgentInLinuxVM(String host, int port, String userName, String password) { SSHShell shell = null; try { System.out.println("Trying to de-provision: " + host); shell = SSHShell.open(host, port, userName, password); List<String> deprovisionCommand = new ArrayList<>(); deprovisionCommand.add("sudo waagent -deprovision+user --force"); String output = shell.runCommands(deprovisionCommand); System.out.println(output); } catch (JSchException jSchException) { System.out.println(jSchException.getMessage()); } catch (IOException ioException) { System.out.println(ioException.getMessage()); } catch (Exception exception) { System.out.println(exception.getMessage()); } finally { if (shell != null) { shell.close(); } } } private static Network prepareNetwork(Azure azure, Region region, String rgName) { final String vnetName = SdkContext.randomResourceName("vnet", 24); Network network = azure.networks().define(vnetName) .withRegion(region) .withNewResourceGroup(rgName) .withAddressSpace("172.16.0.0/16") .defineSubnet("subnet1") .withAddressPrefix("172.16.1.0/24") .attach() .create(); return network; } private static LoadBalancer prepareLoadBalancer(Azure azure, Region region, String rgName) { final String loadBalancerName1 = SdkContext.randomResourceName("intlb" + "-", 18); final String frontendName = loadBalancerName1 + "-FE1"; final String backendPoolName1 = loadBalancerName1 + "-BAP1"; final String backendPoolName2 = loadBalancerName1 + "-BAP2"; final String httpProbe = "httpProbe"; final String httpsProbe = "httpsProbe"; final String httpLoadBalancingRule = "httpRule"; final String httpsLoadBalancingRule = "httpsRule"; final String natPool50XXto22 = "natPool50XXto22"; final String natPool60XXto23 = "natPool60XXto23"; final String publicIpName = "pip-" + loadBalancerName1; PublicIPAddress publicIPAddress = azure.publicIPAddresses().define(publicIpName) .withRegion(region) .withExistingResourceGroup(rgName) .withLeafDomainLabel(publicIpName) .create(); LoadBalancer loadBalancer = azure.loadBalancers().define(loadBalancerName1) .withRegion(region) .withExistingResourceGroup(rgName) .definePublicFrontend(frontendName) .withExistingPublicIPAddress(publicIPAddress) .attach() // Add two backend one per rule .defineBackend(backendPoolName1) .attach() .defineBackend(backendPoolName2) .attach() // Add two probes one per rule .defineHttpProbe(httpProbe) .withRequestPath("/") .withPort(80) .attach() .defineHttpProbe(httpsProbe) .withRequestPath("/") .withPort(443) .attach() // Add two rules that uses above backend and probe .defineLoadBalancingRule(httpLoadBalancingRule) .withProtocol(TransportProtocol.TCP) .withFrontend(frontendName) .withFrontendPort(80) .withProbe(httpProbe) .withBackend(backendPoolName1) .attach() .defineLoadBalancingRule(httpsLoadBalancingRule) .withProtocol(TransportProtocol.TCP) .withFrontend(frontendName) .withFrontendPort(443) .withProbe(httpsProbe) .withBackend(backendPoolName2) .attach() // Add nat pools to enable direct VM connectivity for // SSH to port 22 and TELNET to port 23 .defineInboundNatPool(natPool50XXto22) .withProtocol(TransportProtocol.TCP) .withFrontend(frontendName) .withFrontendPortRange(5000, 5099) .withBackendPort(22) .attach() .defineInboundNatPool(natPool60XXto23) .withProtocol(TransportProtocol.TCP) .withFrontend(frontendName) .withFrontendPortRange(6000, 6099) .withBackendPort(23) .attach() .create(); return loadBalancer; } private ManageManagedDisks() { } }