Skip to content

Commit

Permalink
Addition of Spot instance support for VM and VMSS (ansible-collection…
Browse files Browse the repository at this point in the history
…s#559)

* Addition of Spot instance support for VM and VMSS

* PR comment relative to formatting

* Addition of spot instance test for azure_rm_virtualmachine and  vmss

* Changed default priority to None. Added validation for Spot param update

* Removed default values for spot instances parameters + formatting

* small change

Co-authored-by: Vincent Prince <[email protected]>
Co-authored-by: Fred-sun <[email protected]>
Co-authored-by: Fred-sun <[email protected]>
  • Loading branch information
4 people committed Aug 11, 2021
1 parent a73de60 commit 26f59cd
Show file tree
Hide file tree
Showing 4 changed files with 306 additions and 14 deletions.
59 changes: 59 additions & 0 deletions plugins/modules/azure_rm_virtualmachine.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,27 @@
- A valid Azure VM size value. For example, C(Standard_D4).
- Choices vary depending on the subscription and location. Check your subscription for available choices.
- Required when creating a VM.
priority:
description:
- Priority of the VM.
- C(None) is the equivalent of Regular VM.
choices:
- None
- Spot
eviction_policy:
description:
- Specifies the eviction policy for the Azure Spot virtual machine.
- Requires priority to be set to Spot.
choices:
- Deallocate
- Delete
max_price:
description:
- Specifies the maximum price you are willing to pay for a Azure Spot VM/VMSS.
- This price is in US Dollars.
- C(-1) indicates default price to be up-to on-demand.
- Requires priority to be set to Spot.
default: -1
admin_username:
description:
- Admin username used to access the VM after it is created.
Expand Down Expand Up @@ -539,6 +560,21 @@
product: f5-big-ip-best
publisher: f5-networks
- name: Create a VM with Spot Instance
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: testvm10
vm_size: Standard_D4
priority: Spot
eviction_policy: Deallocate
admin_username: chouseknecht
admin_password: <your password here>
image:
offer: CentOS
publisher: OpenLogic
sku: '7.1'
version: latest
- name: Power Off
azure_rm_virtualmachine:
resource_group: myResourceGroup
Expand Down Expand Up @@ -797,6 +833,9 @@ def __init__(self):
location=dict(type='str'),
short_hostname=dict(type='str'),
vm_size=dict(type='str'),
priority=dict(type='str', choices=['None', 'Spot']),
eviction_policy=dict(type='str', choices=['Deallocate', 'Delete']),
max_price=dict(type='float', default=-1),
admin_username=dict(type='str'),
admin_password=dict(type='str', no_log=True),
ssh_password_enabled=dict(type='bool', default=True),
Expand Down Expand Up @@ -841,6 +880,8 @@ def __init__(self):
self.location = None
self.short_hostname = None
self.vm_size = None
self.priority = None
self.eviction_policy = None
self.admin_username = None
self.admin_password = None
self.ssh_password_enabled = None
Expand Down Expand Up @@ -1045,6 +1086,17 @@ def exec_module(self, **kwargs):
results = vm_dict
current_osdisk = vm_dict['properties']['storageProfile']['osDisk']
current_ephemeral = current_osdisk.get('diffDiskSettings', None)
current_properties = vm_dict['properties']

if self.priority and self.priority != current_properties.get('priority', 'None'):
self.fail('VM Priority is not updatable: requested virtual machine priority is {0}'.format(self.priority))
if self.eviction_policy and \
self.eviction_policy != current_properties.get('evictionPolicy', None):
self.fail('VM Eviction Policy is not updatable: requested virtual machine eviction policy is {0}'.format(self.eviction_policy))
if self.max_price and \
vm_dict['properties'].get('billingProfile', None) and \
self.max_price != vm_dict['properties']['billingProfile'].get('maxPrice', None):
self.fail('VM Maximum Price is not updatable: requested virtual machine maximum price is {0}'.format(self.max_price))

if self.ephemeral_os_disk and current_ephemeral is None:
self.fail('Ephemeral OS disk not updatable: virtual machine ephemeral OS disk is {0}'.format(self.ephemeral_os_disk))
Expand Down Expand Up @@ -1303,6 +1355,13 @@ def exec_module(self, **kwargs):
zones=self.zones,
)

if self.priority == 'Spot':
vm_resource.priority = self.priority
vm_resource.eviction_policy = self.eviction_policy
vm_resource.billing_profile = self.compute_models.BillingProfile(
max_price=self.max_price
)

if self.license_type is not None:
vm_resource.license_type = self.license_type

Expand Down
61 changes: 61 additions & 0 deletions plugins/modules/azure_rm_virtualmachinescaleset.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,27 @@
choices:
- Manual
- Automatic
priority:
description:
- Priority of the VMSS.
- C(None) is the equivalent of Regular VM.
choices:
- None
- Spot
eviction_policy:
description:
- Specifies the eviction policy for the Azure Spot virtual machine.
- Requires priority to be set to Spot.
choices:
- Deallocate
- Delete
max_price:
description:
- Specifies the maximum price you are willing to pay for a Azure Spot VM/VMSS.
- This price is in US Dollars.
- C(-1) indicates default price to be up-to on-demand.
- Requires priority to be set to Spot.
default: -1
admin_username:
description:
- Admin username used to access the host after it is created. Required when creating a VM.
Expand Down Expand Up @@ -355,6 +376,23 @@
image:
name: customimage001
resource_group: myResourceGroup
- name: Create a VMSS with Spot Instance
azure_rm_virtualmachinescaleset:
resource_group: myResourceGroup
name: testvmss
vm_size: Standard_DS1_v2
capacity: 5
priority: Spot
eviction_policy: Deallocate
virtual_network_name: testvnet
upgrade_policy: Manual
subnet_name: testsubnet
admin_username: adminUser
admin_password: password01
managed_disk_type: Standard_LRS
image: customimage001
'''

RETURN = '''
Expand Down Expand Up @@ -495,6 +533,9 @@ def __init__(self):
tier=dict(type='str', choices=['Basic', 'Standard']),
capacity=dict(type='int', default=1),
upgrade_policy=dict(type='str', choices=['Automatic', 'Manual']),
priority=dict(type='str', choices=['None', 'Spot']),
eviction_policy=dict(type='str', choices=['Deallocate', 'Delete']),
max_price=dict(type='float', default=-1),
admin_username=dict(type='str'),
admin_password=dict(type='str', no_log=True),
ssh_password_enabled=dict(type='bool', default=True),
Expand Down Expand Up @@ -535,6 +576,8 @@ def __init__(self):
self.capacity = None
self.tier = None
self.upgrade_policy = None
self.priority = None
self.eviction_policy = None
self.admin_username = None
self.admin_password = None
self.ssh_password_enabled = None
Expand Down Expand Up @@ -697,6 +740,17 @@ def exec_module(self, **kwargs):
results = vmss_dict
current_osdisk = vmss_dict['properties']['virtualMachineProfile']['storageProfile']['osDisk']
current_ephemeral = current_osdisk.get('diffDiskSettings', None)
current_properties = vmss_dict['properties']['virtualMachineProfile']

if self.priority and self.priority != current_properties.get('priority', 'None'):
self.fail('VM Priority is not updatable: requested virtual machine priority is {0}'.format(self.priority))
if self.eviction_policy and \
self.eviction_policy != current_properties.get('evictionPolicy', None):
self.fail('VM Eviction Policy is not updatable: requested virtual machine eviction policy is {0}'.format(self.eviction_policy))
if self.max_price and \
vmss_dict['properties']['virtualMachineProfile'].get('billingProfile', None) and \
self.max_price != vmss_dict['properties']['virtualMachineProfile']['billingProfile'].get('maxPrice', None):
self.fail('VM Maximum Price is not updatable: requested virtual machine maximum price is {0}'.format(self.max_price))

if self.ephemeral_os_disk and current_ephemeral is None:
self.fail('Ephemeral OS disk not updatable: virtual machine scale set ephemeral OS disk is {0}'.format(self.ephemeral_os_disk))
Expand Down Expand Up @@ -922,6 +976,13 @@ def exec_module(self, **kwargs):
zones=self.zones
)

if self.priority == 'Spot':
vmss_resource.virtual_machine_profile.priority = self.priority
vmss_resource.virtual_machine_profile.eviction_policy = self.eviction_policy
vmss_resource.virtual_machine_profile.billing_profile = self.compute_models.BillingProfile(
max_price=self.max_price
)

if self.scale_in_policy:
vmss_resource.scale_in_policy = self.gen_scale_in_policy()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
- include_tasks: setup.yml

- name: Create minimal VM with Spot Instance default values
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}"
priority: Spot
eviction_policy: Deallocate
admin_username: "testuser"
ssh_password_enabled: false
ssh_public_keys:
- path: /home/testuser/.ssh/authorized_keys
key_data: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfoYlIV4lTPZTv7hXaVwQQuqBgGs4yeNRX0SPo2+HQt9u4X7IGwrtXc0nEUm6LfaCikMH58bOL8f20NTGz285kxdFHZRcBXtqmnMz2rXwhK9gwq5h1khc+GzHtdcJXsGA4y0xuaNcidcg04jxAlN/06fwb/VYwwWTVbypNC0gpGEpWckCNm8vlDlA55sU5et0SZ+J0RKVvEaweUOeNbFZqckGPA384imfeYlADppK/7eAxqfBVadVvZG8IJk4yvATgaIENIFj2cXxqu2mQ/Bp5Wr45uApvJsFXmi+v/nkiOEV1QpLOnEwAZo6EfFS4CCQtsymxJCl1PxdJ5LD4ZOtP [email protected]"
vm_size: Standard_A1_v2
virtual_network: "{{ network_name }}"
image:
offer: CentOS
publisher: OpenLogic
sku: '7.1'
version: latest
register: vm_output

- name: Ensure VM was created using Spot Instance default values
assert:
that:
- azure_vm.properties.priority == 'Spot'
- azure_vm.properties.evictionPolicy == 'Deallocate'
- azure_vm.properties.billingProfile.maxPrice == -1.0

- name: Delete VM
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}"
state: absent
vm_size: Standard_A1_v2

- name: Create minimal VM with custom Spot Instance values
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}"
priority: Spot
eviction_policy: Delete
max_price: 1.0
admin_username: "testuser"
ssh_password_enabled: false
ssh_public_keys:
- path: /home/testuser/.ssh/authorized_keys
key_data: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfoYlIV4lTPZTv7hXaVwQQuqBgGs4yeNRX0SPo2+HQt9u4X7IGwrtXc0nEUm6LfaCikMH58bOL8f20NTGz285kxdFHZRcBXtqmnMz2rXwhK9gwq5h1khc+GzHtdcJXsGA4y0xuaNcidcg04jxAlN/06fwb/VYwwWTVbypNC0gpGEpWckCNm8vlDlA55sU5et0SZ+J0RKVvEaweUOeNbFZqckGPA384imfeYlADppK/7eAxqfBVadVvZG8IJk4yvATgaIENIFj2cXxqu2mQ/Bp5Wr45uApvJsFXmi+v/nkiOEV1QpLOnEwAZo6EfFS4CCQtsymxJCl1PxdJ5LD4ZOtP [email protected]"
vm_size: Standard_A1_v2
virtual_network: "{{ network_name }}"
image:
offer: CentOS
publisher: OpenLogic
sku: '7.1'
version: latest
register: vm_output

- name: Ensure VM was created using custom spot instance values
assert:
that:
- azure_vm.properties.priority == 'Spot'
- azure_vm.properties.evictionPolicy == 'Delete'
- azure_vm.properties.billingProfile.maxPrice == 1.0

- name: Delete VM
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name }}"
state: absent
vm_size: Standard_A1_v2

- name: Destroy subnet
azure_rm_subnet:
resource_group: "{{ resource_group }}"
virtual_network: "{{ network_name }}"
name: "{{ subnet_name }}"
state: absent

- name: Destroy virtual network
azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ network_name }}"
state: absent
Loading

0 comments on commit 26f59cd

Please sign in to comment.