diff --git a/plugins/modules/azure_rm_virtualmachine.py b/plugins/modules/azure_rm_virtualmachine.py index 01a93ae24..8c2ac844b 100644 --- a/plugins/modules/azure_rm_virtualmachine.py +++ b/plugins/modules/azure_rm_virtualmachine.py @@ -137,6 +137,23 @@ availability_set: description: - Name or ID of an existing availability set to add the VM to. The I(availability_set) should be in the same resource group as VM. + proximity_placement_group: + description: + - The name or ID of the proximity placement group the VM should be associated with. + type: dict + suboptions: + id: + description: + - The ID of the proximity placement group the VM should be associated with. + type: str + name: + description: + - The Name of the proximity placement group the VM should be associated with. + type: str + resource_group: + description: + - The resource group of the proximity placement group the VM should be associated with. + type: str storage_account_name: description: - Name of a storage account that supports creation of VHD blobs. @@ -651,6 +668,9 @@ "availabilitySet": { "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroup/myResourceGroup/providers/Microsoft.Compute/availabilitySets/MYAVAILABILITYSET" }, + "proximityPlacementGroup": { + "id": "/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Compute/proximityPlacementGroups/testid13" + }, "hardwareProfile": { "vmSize": "Standard_D1" }, @@ -821,6 +841,13 @@ def extract_names_from_blob_uri(blob_uri, storage_suffix): return extracted_names +proximity_placement_group_spec = dict( + id=dict(type='str'), + name=dict(type='str'), + resource_group=dict(type='str') +) + + class AzureRMVirtualMachine(AzureRMModuleBase): def __init__(self): @@ -849,6 +876,7 @@ def __init__(self): os_disk_size_gb=dict(type='int'), managed_disk_type=dict(type='str', choices=['Standard_LRS', 'StandardSSD_LRS', 'Premium_LRS']), os_disk_name=dict(type='str'), + proximity_placement_group=dict(type='dict', options=proximity_placement_group_spec), os_type=dict(type='str', choices=['Linux', 'Windows'], default='Linux'), public_ip_allocation_method=dict(type='str', choices=['Dynamic', 'Static', 'Disabled'], default='Static', aliases=['public_ip_allocation']), @@ -896,6 +924,7 @@ def __init__(self): self.os_disk_size_gb = None self.managed_disk_type = None self.os_disk_name = None + self.proximity_placement_group = None self.network_interface_names = None self.remove_on_absent = set() self.tags = None @@ -1027,6 +1056,7 @@ def exec_module(self, **kwargs): if self.image and isinstance(self.image, dict): if all(key in self.image for key in ('publisher', 'offer', 'sku', 'version')): marketplace_image = self.get_marketplace_image_version() + if self.image['version'] == 'latest': self.image['version'] = marketplace_image.name self.log("Using image version {0}".format(self.image['version'])) @@ -1275,6 +1305,17 @@ def exec_module(self, **kwargs): if self.zones: self.fail("Parameter error: you can't use Availability Set and Availability Zones at the same time") + proximity_placement_group_resource = None + if self.proximity_placement_group is not None: + if self.proximity_placement_group.get('id') is not None: + proximity_placement_group_resource = self.compute_models.SubResource(id=self.proximity_placement_group['id']) + elif self.proximity_placement_group.get('name') is not None and self.proximity_placement_group.get('resource_group') is not None: + proximity_placement_group = self.get_proximity_placement_group(self.proximity_placement_group.get('resource_group'), + self.proximity_placement_group.get('name')) + proximity_placement_group_resource = self.compute_models.SubResource(id=proximity_placement_group.id) + else: + self.fail("Parameter error: Please recheck your proximity placement group ") + # Get defaults if not self.network_interface_names: default_nic = self.create_default_nic() @@ -1351,6 +1392,7 @@ def exec_module(self, **kwargs): network_interfaces=nics ), availability_set=availability_set_resource, + proximity_placement_group=proximity_placement_group_resource, plan=plan, zones=self.zones, ) @@ -1522,6 +1564,13 @@ def exec_module(self, **kwargs): storage_account_type=vm_dict['properties']['storageProfile']['osDisk']['managedDisk'].get('storageAccountType') ) + proximity_placement_group_resource = None + try: + proximity_placement_group_resource = self.compute_models.SubResource(id=vm_dict['properties']['proximityPlacementGroup'].get('id')) + except Exception: + # pass if the proximity Placement Group + pass + availability_set_resource = None try: availability_set_resource = self.compute_models.SubResource(id=vm_dict['properties']['availabilitySet'].get('id')) @@ -1575,6 +1624,7 @@ def exec_module(self, **kwargs): image_reference=image_reference ), availability_set=availability_set_resource, + proximity_placement_group=proximity_placement_group_resource, network_profile=self.compute_models.NetworkProfile( network_interfaces=nics ) @@ -2013,6 +2063,12 @@ def get_custom_image_reference(self, name, resource_group=None): self.fail("Error could not find image with name {0}".format(name)) return None + def get_proximity_placement_group(self, resource_group, name): + try: + return self.compute_client.proximity_placement_groups.get(resource_group, name) + except Exception as exc: + self.fail("Error fetching proximity placement group {0} - {1}".format(name, str(exc))) + def get_availability_set(self, resource_group, name): try: return self.compute_client.availability_sets.get(resource_group, name) diff --git a/plugins/modules/azure_rm_virtualmachine_info.py b/plugins/modules/azure_rm_virtualmachine_info.py index 9d9a7406c..579fa3e26 100644 --- a/plugins/modules/azure_rm_virtualmachine_info.py +++ b/plugins/modules/azure_rm_virtualmachine_info.py @@ -198,6 +198,12 @@ sample: [ "myNetworkInterface" ] + proximityPlacementGroup: + description: + - The name or ID of the proximity placement group the VM should be associated with. + type: dict + returned: always + sample: { "id": "/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Compute/proximityPlacementGroups/testid13"} os_disk_caching: description: - Type of OS disk caching. @@ -408,6 +414,7 @@ def serialize_vm(self, vm): new_result['state'] = 'present' new_result['location'] = vm.location new_result['vm_size'] = result['properties']['hardwareProfile']['vmSize'] + new_result['proximityPlacementGroup'] = result['properties'].get('proximityPlacementGroup') new_result['zones'] = result.get('zones', None) os_profile = result['properties'].get('osProfile') if os_profile is not None: diff --git a/tests/integration/targets/azure_rm_virtualmachine/tasks/azure_test_ephemeral_os.yml b/tests/integration/targets/azure_rm_virtualmachine/tasks/azure_test_ephemeral_os.yml index be705e164..4169333b9 100644 --- a/tests/integration/targets/azure_rm_virtualmachine/tasks/azure_test_ephemeral_os.yml +++ b/tests/integration/targets/azure_rm_virtualmachine/tasks/azure_test_ephemeral_os.yml @@ -1,11 +1,19 @@ - include_tasks: setup.yml -- name: Create minimal VM with defaults +- name: create proximity placement group + azure_rm_proximityplacementgroup: + resource_group: "{{ resource_group }}" + name: testproximityplacement + register: output + +- name: Create minimal VM with proximentplace group azure_rm_virtualmachine: resource_group: "{{ resource_group }}" name: "{{ vm_name }}" admin_username: "testuser" ssh_password_enabled: false + proximity_placement_group: + id: "{{ output.state.id }}" ssh_public_keys: - path: /home/testuser/.ssh/authorized_keys key_data: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfoYlIV4lTPZTv7hXaVwQQuqBgGs4yeNRX0SPo2+HQt9u4X7IGwrtXc0nEUm6LfaCikMH58bOL8f20NTGz285kxdFHZRcBXtqmnMz2rXwhK9gwq5h1khc+GzHtdcJXsGA4y0xuaNcidcg04jxAlN/06fwb/VYwwWTVbypNC0gpGEpWckCNm8vlDlA55sU5et0SZ+J0RKVvEaweUOeNbFZqckGPA384imfeYlADppK/7eAxqfBVadVvZG8IJk4yvATgaIENIFj2cXxqu2mQ/Bp5Wr45uApvJsFXmi+v/nkiOEV1QpLOnEwAZo6EfFS4CCQtsymxJCl1PxdJ5LD4ZOtP xiuxi.sun@qq.com"