azure-docs-sdk-java/docs-ref-conceptual/java-sdk-virtual-machines-i...

11 KiB

title description author manager ms.assetid ms.service ms.devlang ms.topic ms.date ms.author
Create VMs across regions in parallel | Microsoft Docs Sample code to create virtual machines across different Azure regions in parallel using the Azure SDK for Java rloutlaw douge e5a36699-2d96-4571-84f9-a6af13f3c067 Azure java article 03/30/2017 routlaw;asirveda

Create virtual machines across multiple regions from your Java applications

This sample creates virtual machines in parallel across different Azure regions using the Azure management libraries for Java.

[!IMPORTANT] The sample creates a total of 48 VMs running Ubuntu 16.04 LTS of size STANDARD_DS3_V2 across four regions. The sample code deletes these virtual machines before exiting. Make sure to check your service limits and quota before running this sample with the default number of VMs.

Run the sample

Create an authentication file and set an environment variable AZURE_AUTH_LOCATION with the full path to the file on your computer. Then run:

git clone https://github.com/Azure-Samples/compute-java-create-virtual-machines-across-regions-in-parallel.git
cd compute-java-create-virtual-machines-across-regions-in-parallel
mvn clean compile exec:java

View the complete code sample on GitHub.

Authenticate with Azure

[!INCLUDE auth-include]

Set locations and counts for the virtual machines

// use a Map to define how where and how many VMs to create 
Map<Region, Integer> virtualMachinesByLocation = new HashMap<Region, Integer>();

// create 12 virtual machines in four regions
virtualMachinesByLocation.put(Region.US_EAST, 12);
virtualMachinesByLocation.put(Region.US_SOUTH_CENTRAL, 12);
virtualMachinesByLocation.put(Region.US_WEST, 12);
virtualMachinesByLocation.put(Region.US_NORTH_CENTRAL, 12);

This Map is used later in the sample to set the distrubtion of the VMs worldwide.

Create a resource group

// logically associate the resources in the sample into a randomly named resource group
final String rgName = SdkContext.randomResourceName("rgCOPD", 24);
ResourceGroup resourceGroup = azure.resourceGroups().define(rgName)
                .withRegion(Region.US_EAST)
                .create();

Each resource in the sample is managed by this resource group. This makes the resources easy to clean up later by deleting the resource group.

Define the virtual machines

// list to store the VirtualMachine definitions
List<Creatable<VirtualMachine>> creatableVirtualMachines = new ArrayList<>();
    
// outer loop: iterate through each region included in the map
for (Map.Entry<Region, Integer> entry : virtualMachinesByLocation.entrySet()) {
    Region region = entry.getKey();
    Integer vmCount = entry.getValue();

    // Define one virtual network Creatable per region for the VMs to share
    String networkName = SdkContext.randomResourceName("vnetCOPD-", 20);
    Creatable<Network> networkCreatable = azure.networks().define(networkName)
           .withRegion(region)
           .withExistingResourceGroup(resourceGroup)
           .withAddressSpace("172.16.0.0/16");

    // Define one storage account Creatable per region for storing VM disks
    String storageAccountName = SdkContext.randomResourceName("stgcopd", 20);
    Creatable<StorageAccount> storageAccountCreatable = azure.storageAccounts()
        .define(storageAccountName)
              .withRegion(region)
              .withExistingResourceGroup(resourceGroup);

    // generate a common prefix for every VM name
    String linuxVMNamePrefix = SdkContext.randomResourceName("vm-", 15);

    // inner loop: iterate once for every VM instance in the region
    for (int i = 1; i <= vmCount; i++) {

        // Create one public IP address Creatable for each VM
        Creatable<PublicIpAddress> publicIpAddressCreatable = azure.publicIpAddresses()
             .define(String.format("%s-%d", linuxVMNamePrefix, i))
             .withRegion(region)
             .withExistingResourceGroup(resourceGroup)
             .withLeafDomainLabel(SdkContext.randomResourceName("pip", 10));

        publicIpCreatableKeys.add(publicIpAddressCreatable.key());

        // Create one virtual machine Creatable 
        Creatable<VirtualMachine> virtualMachineCreatable = azure.virtualMachines()
             .define(String.format("%s-%d", linuxVMNamePrefix, i))
             .withRegion(region)
             .withExistingResourceGroup(resourceGroup)
             .withNewPrimaryNetwork(networkCreatable)
             .withPrimaryPrivateIpAddressDynamic()
             .withNewPrimaryPublicIpAddress(publicIpAddressCreatable)
             .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_16_04_LTS)
             .withRootUsername(userName)
             .withSsh(sshKey)
             .withSize(VirtualMachineSizeTypes.STANDARD_DS3_V2)
             .withNewStorageAccount(storageAccountCreatable);
        // add the virtual machine Creatable to the list     
        creatableVirtualMachines.add(virtualMachineCreatable); 
     }
}

The outer for loop above iterates through each region, defining a virtual network Creatable and storage account Creatable for use by all virtual machines in that region. Learn more about using Creatables to create resources only as needed when using the management libraries.

The inner for loop gets a public IP address Creatable for the virtual machine and then defines a virtual machine Creatable using the Creatables for the virtual network, storage account, and public IP address defined previously. This VirtualMachine Creatable is then added to the creatableVirtualMachines list.

Create the virtual machines

// create all virtual machines defined in the list, return all Creatable objects used
// including networks, public IP addresses, and storage accounts
CreatedResources<VirtualMachine> virtualMachines = azure.virtualMachines().create(creatableVirtualMachines);

// list the IDs of each virtual machine created 
for (VirtualMachine virtualMachine : virtualMachines.values()) {
    System.out.println(virtualMachine.id());
}

// call createdRelatedResource(key) to get the resources used to define the virtual machines. 
// Save the key at the time you define the Creatable to use CreatedResources like this
for (String publicIpCreatableKey : publicIpCreatableKeys) {
    PublicIPAddress pip = 
         (PublicIPAddress) virtualMachines.createdRelatedResource(publicIpCreatableKey);
}

The azure.virtualMachines().create(creatableVirtualMachines) call creates all of the virtual machines defined in the creatableVirtualMachines List in parallel across the regions.

Use the returned CreatedResources<VirtualMachine> object to access any resources created in the Azure subscription during the the create() method, not just the returned VirtualMachine type. Cast the returned value from createdRelatedResources() to the correct type.

Learn more about working with Creatable<T> and CreatedResources in our library concepts article.

Delete the resource group

// finally block deletes the resource group before the code exits
// deleting a resource group deletes all resources created in it
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();
    }
}

This block deletes resources created in the sample before the sample exits.

Sample explanation

View the complete sample code on Github.

The sample uses Creatable objects to define a virtual network and storage account for each region hosting the virtual machines. Creatable objects are then defined for the public IP address for each virtual machine. The sample defines the virtual machines using these Creatable objects, and sample adds the VM definition to the virtualMachineCreatable list.

After the code adds every virtual machine definition to the list, azure.virtualMachines().create(creatableVirtualMachines) creates each virtual machine in parallel in Azure.

The sample code then gets the IP addresses for all of the created virtual machines from the returned CreatedResources object to create a Traffic Manager to distribute load across the virtual machines.

The finally block deletes the resources from your Azure subscription even in the case of an error.

Class used in sample Notes
VirtualMachine Query properties and manage state of virtual machines. Retrieved in list form from azure.virtualMachines().list() or by name or ID azure.virtualMachines().getByResourceGroup()
VirtualMachineSizeTypes Static values that map to virtual machine size options for use as a parameter to withSize() when defining a virtual machine.
PublicIpAddress Defined, but not immediately created, for each virtual machine through azure.publicIpAddresses().define(). Store the key for each Creatable and retrieve later through createdRelatedResource()
KnownLinuxVirtualMachineImage Set of Linux virtual machine options used as a parameter to withPopularLinuxImage() method when defining a virtual machine.
Network The sample defines one virtual network for each region through azure.networks().define() .

Next steps

[!INCLUDE next-steps]