azure_rm_virtualmachine (and _facts): add boot_diagnostics control and facts (#49661)

This commit is contained in:
James E. King III 2019-05-14 15:06:07 -04:00 committed by Zim Kalinowski
parent 0d2a120454
commit 75788ecff4
6 changed files with 448 additions and 119 deletions

View file

@ -2,6 +2,7 @@
#
# Copyright (c) 2016 Matt Davis, <mdavis@ansible.com>
# Chris Houseknecht, <house@redhat.com>
# Copyright (c) 2018 James E. King, III (@jeking3) <jking@apache.org>
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
@ -277,8 +278,8 @@ options:
remove_on_absent:
description:
- "When removing a VM using state 'absent', also remove associated resources."
- "It can be 'all' or 'all_autocreated' or a list with any of the following: ['network_interfaces', 'virtual_storage', 'public_ips']."
- "To remove all resources referred by VM use 'all'."
- "It can be a list with any of the following: ['all', 'all_autocreated', 'network_interfaces', 'virtual_storage', 'public_ips']."
- "To remove all resources referred by VM use 'all' (this includes autocreated)."
- "To remove all resources that were automatically created while provisioning VM use 'all_autocreated'."
- Any other input will be ignored.
default: ['all']
@ -352,6 +353,26 @@ options:
description:
- Specifies the certificate store on the Virtual Machine to which the certificate
should be added. The specified certificate store is implicitly in the LocalMachine account.
boot_diagnostics:
description:
- Manage boot diagnostics settings for a virtual machine. Boot diagnostics
includes a serial console and remote console screenshots.
version_added: '2.9'
suboptions:
enabled:
description:
- Flag indicating if boot diagnostics is enabled.
required: true
type: bool
storage_account:
description:
- The name of an existing storage account to use for boot diagnostics.
- If omitted and C(storage_account_name) is defined one level up, that
will be used instead.
- If omitted and C(storage_account_name) is not defined one level up, and
C(enabled) is I(true), then a default storage account will be created
or used for the virtual machine to hold the boot diagnostics data.
required: false
extends_documentation_fragment:
- azure
@ -361,7 +382,7 @@ author:
- "Chris Houseknecht (@chouseknecht)"
- "Matt Davis (@nitzmahone)"
- "Christopher Perrin (@cperrin88)"
- "James E. King III (@jeking3)"
'''
EXAMPLES = '''
@ -452,6 +473,8 @@ EXAMPLES = '''
network_interfaces: testvm001
storage_container: osdisk
storage_blob: osdisk.vhd
boot_diagnostics:
enabled: yes
image:
offer: CoreOS
publisher: CoreOS
@ -798,7 +821,8 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
accept_terms=dict(type='bool', default=False),
license_type=dict(type='str', choices=['Windows_Server', 'Windows_Client']),
vm_identity=dict(type='str', choices=['SystemAssigned']),
winrm=dict(type='list')
winrm=dict(type='list'),
boot_diagnostics=dict(type='dict'),
)
self.resource_group = None
@ -842,6 +866,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
self.zones = None
self.license_type = None
self.vm_identity = None
self.boot_diagnostics = None
self.results = dict(
changed=False,
@ -853,6 +878,45 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
super(AzureRMVirtualMachine, self).__init__(derived_arg_spec=self.module_arg_spec,
supports_check_mode=True)
@property
def boot_diagnostics_present(self):
return self.boot_diagnostics is not None and 'enabled' in self.boot_diagnostics
def get_boot_diagnostics_storage_account(self, limited=False, vm_dict=None):
"""
Get the boot diagnostics storage account.
Arguments:
- limited - if true, limit the logic to the boot_diagnostics storage account
this is used if initial creation of the VM has a stanza with
boot_diagnostics disabled, so we only create a storage account
if the user specifies a storage account name inside the boot_diagnostics
schema
- vm_dict - if invoked on an update, this is the current state of the vm including
tags, like the default storage group tag '_own_sa_'.
Normal behavior:
- try the self.boot_diagnostics.storage_account field
- if not there, try the self.storage_account_name field
- if not there, use the default storage account
If limited is True:
- try the self.boot_diagnostics.storage_account field
- if not there, None
"""
bsa = None
if 'storage_account' in self.boot_diagnostics:
bsa = self.get_storage_account(self.boot_diagnostics['storage_account'])
elif limited:
return None
elif self.storage_account_name:
bsa = self.get_storage_account(self.storage_account_name)
else:
bsa = self.create_default_storage_account(vm_dict=vm_dict)
self.log("boot diagnostics storage account:")
self.log(self.serialize_obj(bsa, 'StorageAccount'), pretty_print=True)
return bsa
def exec_module(self, **kwargs):
for key in list(self.module_arg_spec.keys()) + ['tags']:
@ -869,6 +933,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
results = dict()
vm = None
network_interfaces = []
requested_storage_uri = None
requested_vhd_uri = None
data_disk_requested_vhd_uri = None
disable_ssh_password = None
@ -943,7 +1008,8 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
if self.storage_account_name and not self.managed_disk_type:
properties = self.get_storage_account(self.storage_account_name)
requested_vhd_uri = '{0}{1}/{2}'.format(properties.primary_endpoints.blob,
requested_storage_uri = properties.primary_endpoints.blob
requested_vhd_uri = '{0}{1}/{2}'.format(requested_storage_uri,
self.storage_container_name,
self.storage_blob_name)
@ -1044,6 +1110,46 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
if self.license_type is not None and vm_dict['properties'].get('licenseType') != self.license_type:
differences.append('License Type')
changed = True
# Defaults for boot diagnostics
if 'diagnosticsProfile' not in vm_dict['properties']:
vm_dict['properties']['diagnosticsProfile'] = {}
if 'bootDiagnostics' not in vm_dict['properties']['diagnosticsProfile']:
vm_dict['properties']['diagnosticsProfile']['bootDiagnostics'] = {
'enabled': False,
'storageUri': None
}
if self.boot_diagnostics_present:
current_boot_diagnostics = vm_dict['properties']['diagnosticsProfile']['bootDiagnostics']
boot_diagnostics_changed = False
if self.boot_diagnostics['enabled'] != current_boot_diagnostics['enabled']:
current_boot_diagnostics['enabled'] = self.boot_diagnostics['enabled']
boot_diagnostics_changed = True
boot_diagnostics_storage_account = self.get_boot_diagnostics_storage_account(
limited=not self.boot_diagnostics['enabled'], vm_dict=vm_dict)
boot_diagnostics_blob = boot_diagnostics_storage_account.primary_endpoints.blob if boot_diagnostics_storage_account else None
if current_boot_diagnostics['storageUri'] != boot_diagnostics_blob:
current_boot_diagnostics['storageUri'] = boot_diagnostics_blob
boot_diagnostics_changed = True
if boot_diagnostics_changed:
differences.append('Boot Diagnostics')
changed = True
# Adding boot diagnostics can create a default storage account after initial creation
# this means we might also need to update the _own_sa_ tag
own_sa = (self.tags or {}).get('_own_sa_', None)
cur_sa = vm_dict.get('tags', {}).get('_own_sa_', None)
if own_sa and own_sa != cur_sa:
if 'Tags' not in differences:
differences.append('Tags')
if 'tags' not in vm_dict:
vm_dict['tags'] = {}
vm_dict['tags']['_own_sa_'] = own_sa
changed = True
self.differences = differences
elif self.state == 'absent':
@ -1066,7 +1172,6 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
if changed:
if self.state == 'present':
default_storage_account = None
if not vm:
# Create the VM
self.log("Create virtual machine {0}".format(self.name))
@ -1103,14 +1208,15 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
# os disk
if not self.storage_account_name and not self.managed_disk_type:
storage_account = self.create_default_storage_account()
self.log("storage account:")
self.log("os disk storage account:")
self.log(self.serialize_obj(storage_account, 'StorageAccount'), pretty_print=True)
requested_vhd_uri = 'https://{0}.blob.{1}/{2}/{3}'.format(
requested_storage_uri = 'https://{0}.blob.{1}/'.format(
storage_account.name,
self._cloud_environment.suffixes.storage_endpoint,
self._cloud_environment.suffixes.storage_endpoint)
requested_vhd_uri = '{0}{1}/{2}'.format(
requested_storage_uri,
self.storage_container_name,
self.storage_blob_name)
default_storage_account = storage_account # store for use by data disks if necessary
if not self.short_hostname:
self.short_hostname = self.name
@ -1135,7 +1241,9 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
publisher=self.plan.get('publisher'),
promotion_code=self.plan.get('promotion_code'))
license_type = self.license_type
# do this before creating vm_resource as it can modify tags
if self.boot_diagnostics_present and self.boot_diagnostics['enabled']:
boot_diag_storage_account = self.get_boot_diagnostics_storage_account()
vm_resource = self.compute_models.VirtualMachine(
location=self.location,
@ -1206,6 +1314,12 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
elif not vm_resource.os_profile.windows_configuration.win_rm:
vm_resource.os_profile.windows_configuration.win_rm = winrm
if self.boot_diagnostics_present:
vm_resource.diagnostics_profile = self.compute_models.DiagnosticsProfile(
boot_diagnostics=self.compute_models.BootDiagnostics(
enabled=self.boot_diagnostics['enabled'],
storage_uri=boot_diag_storage_account.primary_endpoints.blob))
if self.admin_password:
vm_resource.os_profile.admin_password = self.admin_password
@ -1237,13 +1351,9 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
if data_disk.get('storage_account_name'):
data_disk_storage_account = self.get_storage_account(data_disk['storage_account_name'])
else:
if(not default_storage_account):
data_disk_storage_account = self.create_default_storage_account()
self.log("data disk storage account:")
self.log(self.serialize_obj(data_disk_storage_account, 'StorageAccount'), pretty_print=True)
default_storage_account = data_disk_storage_account # store for use by future data disks if necessary
else:
data_disk_storage_account = default_storage_account
data_disk_storage_account = self.create_default_storage_account()
self.log("data disk storage account:")
self.log(self.serialize_obj(data_disk_storage_account, 'StorageAccount'), pretty_print=True)
if not data_disk.get('storage_container_name'):
data_disk['storage_container_name'] = 'vhds'
@ -1292,7 +1402,7 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
term = self.marketplace_client.marketplace_agreements.get(
publisher_id=plan_publisher, offer_id=plan_product, plan_id=plan_name)
term.accepted = True
agreement = self.marketplace_client.marketplace_agreements.create(
self.marketplace_client.marketplace_agreements.create(
publisher_id=plan_publisher, offer_id=plan_product, plan_id=plan_name, parameters=term)
except Exception as exc:
self.fail(("Error accepting terms for virtual machine {0} with plan {1}. " +
@ -1353,9 +1463,6 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
)
else:
os_profile = None
license_type = None
if self.license_type is None:
license_type = "None"
vm_resource = self.compute_models.VirtualMachine(
location=vm_dict['location'],
@ -1384,6 +1491,12 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
if self.license_type is not None:
vm_resource.license_type = self.license_type
if self.boot_diagnostics is not None:
vm_resource.diagnostics_profile = self.compute_models.DiagnosticsProfile(
boot_diagnostics=self.compute_models.BootDiagnostics(
enabled=vm_dict['properties']['diagnosticsProfile']['bootDiagnostics']['enabled'],
storage_uri=vm_dict['properties']['diagnosticsProfile']['bootDiagnostics']['storageUri']))
if vm_dict.get('tags'):
vm_resource.tags = vm_dict['tags']
@ -1661,26 +1774,26 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
except Exception as exc:
self.fail("Error deleting virtual machine {0} - {1}".format(self.name, str(exc)))
if 'all_autocreated' in self.remove_on_absent:
if 'all' in self.remove_on_absent or 'all_autocreated' in self.remove_on_absent:
self.remove_autocreated_resources(vm.tags)
else:
# TODO: parallelize nic, vhd, and public ip deletions with begin_deleting
# TODO: best-effort to keep deleting other linked resources if we encounter an error
if self.remove_on_absent.intersection(set(['all', 'virtual_storage'])):
self.log('Deleting VHDs')
self.delete_vm_storage(vhd_uris)
self.log('Deleting managed disks')
self.delete_managed_disks(managed_disk_ids)
if self.remove_on_absent.intersection(set(['all', 'network_interfaces'])):
self.log('Deleting network interfaces')
for nic_dict in nic_names:
self.delete_nic(nic_dict['resource_group'], nic_dict['name'])
# TODO: parallelize nic, vhd, and public ip deletions with begin_deleting
# TODO: best-effort to keep deleting other linked resources if we encounter an error
if self.remove_on_absent.intersection(set(['all', 'virtual_storage'])):
self.log('Deleting VHDs')
self.delete_vm_storage(vhd_uris)
self.log('Deleting managed disks')
self.delete_managed_disks(managed_disk_ids)
if self.remove_on_absent.intersection(set(['all', 'public_ips'])):
self.log('Deleting public IPs')
for pip_dict in pip_names:
self.delete_pip(pip_dict['resource_group'], pip_dict['name'])
if self.remove_on_absent.intersection(set(['all', 'network_interfaces'])):
self.log('Deleting network interfaces')
for nic_dict in nic_names:
self.delete_nic(nic_dict['resource_group'], nic_dict['name'])
if self.remove_on_absent.intersection(set(['all', 'public_ips'])):
self.log('Deleting public IPs')
for pip_dict in pip_names:
self.delete_pip(pip_dict['resource_group'], pip_dict['name'])
return True
@ -1841,10 +1954,15 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
return True
return False
def create_default_storage_account(self):
def create_default_storage_account(self, vm_dict=None):
'''
Create a default storage account <vm name>XXXX, where XXXX is a random number. If <vm name>XXXX exists, use it.
Otherwise, create one.
Create (once) a default storage account <vm name>XXXX, where XXXX is a random number.
NOTE: If <vm name>XXXX exists, use it instead of failing. Highly unlikely.
If this method is called multiple times across executions it will return the same
storage account created with the random name which is stored in a tag on the VM.
vm_dict is passed in during an update, so we can obtain the _own_sa_ tag and return
the default storage account we created in a previous invocation
:return: storage account object
'''
@ -1853,6 +1971,15 @@ class AzureRMVirtualMachine(AzureRMModuleBase):
if self.tags is None:
self.tags = {}
if self.tags.get('_own_sa_', None):
# We previously created one in the same invocation
return self.get_storage_account(self.tags['_own_sa_'])
if vm_dict and vm_dict.get('tags', {}).get('_own_sa_', None):
# We previously created one in a previous invocation
# We must be updating, like adding boot diagnostics
return self.get_storage_account(vm_dict['tags']['_own_sa_'])
# Attempt to find a valid storage account name
storage_account_name_base = re.sub('[^a-zA-Z0-9]', '', self.name[:20].lower())
for i in range(0, 5):

View file

@ -24,7 +24,7 @@ version_added: "2.7"
short_description: Get virtual machine facts.
description:
- Get facts for all virtual machines of a resource group.
- Get facts for one or all virtual machines in a resource group.
options:
resource_group:
@ -76,6 +76,32 @@ vms:
returned: always
type: str
sample: admin
boot_diagnostics:
description:
- Information about the boot diagnostics settings.
returned: always
type: complex
contains:
enabled:
description:
- Indicates if boot diagnostics are enabled.
type: bool
sample: true
storage_uri:
description:
- Indicates the storage account used by boot diagnostics.
type: str
sample: https://mystorageaccountname.blob.core.windows.net/
console_screenshot_uri:
description:
- Contains a URI to grab a console screenshot.
- Only present if enabled.
type: str
serial_console_log_uri:
description:
- Contains a URI to grab the serial console log.
- Only present if enabled.
type: str
data_disks:
description:
- List of attached data disks.
@ -206,8 +232,7 @@ except Exception:
# This is handled in azure_rm_common
pass
from ansible.module_utils.azure_rm_common import AzureRMModuleBase, azure_id_to_dict
from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict
from ansible.module_utils.azure_rm_common import AzureRMModuleBase
from ansible.module_utils.six.moves.urllib.parse import urlparse
import re
@ -358,6 +383,18 @@ class AzureRMVirtualMachineFacts(AzureRMModuleBase):
'id': image.get('id', None)
}
new_result['boot_diagnostics'] = {
'enabled': 'diagnosticsProfile' in result['properties'] and
'bootDiagnostics' in result['properties']['diagnosticsProfile'] and
result['properties']['diagnosticsProfile']['bootDiagnostics']['enabled'] or False,
'storage_uri': 'diagnosticsProfile' in result['properties'] and
'bootDiagnostics' in result['properties']['diagnosticsProfile'] and
result['properties']['diagnosticsProfile']['bootDiagnostics']['storageUri'] or None
}
if new_result['boot_diagnostics']['enabled']:
new_result['boot_diagnostics']['console_screenshot_uri'] = result['properties']['instanceView']['bootDiagnostics']['consoleScreenshotBlobUri']
new_result['boot_diagnostics']['serial_console_log_uri'] = result['properties']['instanceView']['bootDiagnostics']['serialConsoleLogBlobUri']
vhd = result['properties']['storageProfile']['osDisk'].get('vhd')
if vhd is not None:
url = urlparse(vhd['uri'])

View file

@ -1 +1,3 @@
- include: setup.yml
- include: virtualmachine.yml
- include: teardown.yml

View file

@ -0,0 +1,74 @@
- name: Create random names
set_fact:
storage_account: "{{ resource_group | hash('md5') | truncate(24, True, '') }}"
storage_account2: "{{ resource_group | hash('md5') | truncate(18, True, '') }}"
vm_name1: "vm1{{ resource_group | hash('md5') | truncate(5, True, '') }}"
vm_name2: "vm2{{ resource_group | hash('md5') | truncate(5, True, '') }}"
vm_name3: "vm3{{ resource_group | hash('md5') | truncate(5, True, '') }}"
vm_name4: "vm4{{ resource_group | hash('md5') | truncate(5, True, '') }}"
abs_name1: "avbs1{{ resource_group | hash('md5') | truncate(3, True, '') }}"
abs_name2: "avbs2{{ resource_group | hash('md5') | truncate(3, True, '') }}"
- name: Create storage account
azure_rm_storageaccount:
resource_group: "{{ resource_group }}"
name: "{{ storage_account }}"
account_type: Standard_LRS
- name: Create 2nd storage account
azure_rm_storageaccount:
resource_group: "{{ resource_group }}"
name: "{{ storage_account2 }}"
account_type: Standard_LRS
- name: Create an availability set
azure_rm_availabilityset:
name: "{{ abs_name1 }}"
resource_group: "{{ resource_group }}"
- name: Create virtual network
azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
address_prefixes: "10.10.0.0/16"
- name: Add subnet
azure_rm_subnet:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
address_prefix: "10.10.0.0/24"
virtual_network: "{{ vm_name1 }}"
- name: Create public ip
azure_rm_publicipaddress:
resource_group: "{{ resource_group }}"
allocation_method: Static
name: "{{ vm_name1 }}"
- name: Create security group
azure_rm_securitygroup:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
purge_rules: yes
rules:
- name: ALLOW_SSH
protocol: Tcp
destination_port_range: 22
access: Allow
priority: 100
direction: Inbound
- name: ALLOW_HTTP
protocol: Tcp
destination_port_range: 80
access: Allow
priority: 110
direction: Inbound
- name: Create NIC for single nic VM
azure_rm_networkinterface:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
virtual_network: "{{ vm_name1 }}"
subnet: "{{ vm_name1 }}"
public_ip_name: "{{ vm_name1 }}"
security_group: "{{ vm_name1 }}"

View file

@ -0,0 +1,62 @@
- name: Destroy NIC for single nic VM
azure_rm_networkinterface:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
state: absent
- name: Destroy 2nd security group
azure_rm_securitygroup:
resource_group: "{{ resource_group }}"
name: "{{ vm_name2 }}"
state: absent
- name: Destroy security group
azure_rm_securitygroup:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
state: absent
- name: Destroy subnet
azure_rm_subnet:
resource_group: "{{ resource_group }}"
virtual_network: "{{ vm_name1 }}"
name: "{{ vm_name1 }}"
state: absent
- name: Destroy virtual network
azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
state: absent
- name: Destroy public ip
azure_rm_publicipaddress:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
state: absent
- name: Destroy 2nd availability set
azure_rm_availabilityset:
resource_group: "{{ resource_group }}"
name: "{{ abs_name2 }}"
state: absent
- name: Destroy an availability set
azure_rm_availabilityset:
resource_group: "{{ resource_group }}"
name: "{{ abs_name1 }}"
state: absent
- name: Destroy 2nd storage account
azure_rm_storageaccount:
resource_group: "{{ resource_group }}"
name: "{{ storage_account2 }}"
force_delete_nonempty: true
state: absent
- name: Destroy storage account
azure_rm_storageaccount:
resource_group: "{{ resource_group }}"
name: "{{ storage_account }}"
force_delete_nonempty: true
state: absent

View file

@ -1,71 +1,4 @@
- name: Create random names
set_fact:
storage_account: "{{ resource_group | hash('md5') | truncate(24, True, '') }}"
vm_name1: "vm1{{ resource_group | hash('md5') | truncate(5, True, '') }}"
vm_name2: "vm2{{ resource_group | hash('md5') | truncate(5, True, '') }}"
vm_name3: "vm3{{ resource_group | hash('md5') | truncate(5, True, '') }}"
abs_name1: "avbs1{{ resource_group | hash('md5') | truncate(3, True, '') }}"
abs_name2: "avbs2{{ resource_group | hash('md5') | truncate(3, True, '') }}"
- name: Create storage account
azure_rm_storageaccount:
resource_group: "{{ resource_group }}"
name: "{{ storage_account }}"
account_type: Standard_LRS
- name: Create an availability set
azure_rm_availabilityset:
name: "{{ abs_name1 }}"
resource_group: "{{ resource_group }}"
- name: Create virtual network
azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
address_prefixes: "10.10.0.0/16"
- name: Add subnet
azure_rm_subnet:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
address_prefix: "10.10.0.0/24"
virtual_network: "{{ vm_name1 }}"
- name: Create public ip
azure_rm_publicipaddress:
resource_group: "{{ resource_group }}"
allocation_method: Static
name: "{{ vm_name1 }}"
- name: Create security group
azure_rm_securitygroup:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
purge_rules: yes
rules:
- name: ALLOW_SSH
protocol: Tcp
destination_port_range: 22
access: Allow
priority: 100
direction: Inbound
- name: ALLOW_HTTP
protocol: Tcp
destination_port_range: 80
access: Allow
priority: 110
direction: Inbound
- name: Create NIC for single nic VM
azure_rm_networkinterface:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
virtual_network: "{{ vm_name1 }}"
subnet: "{{ vm_name1 }}"
public_ip_name: "{{ vm_name1 }}"
security_group: "{{ vm_name1 }}"
- name: Create virtual machine with a single NIC
- name: Create virtual machine with a single NIC and no boot diagnostics
register: output
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
@ -91,7 +24,92 @@
- assert:
that:
- azure_vm.properties.provisioningState == 'Succeeded'
- azure_vm.properties.availabilitySet.id
# initial response from creation has no diagnosticsProfile
# if you run it again however, there is one in the response
# so we handle both cases
- "'diagnosticsProfile' not in azure_vm.properties or not azure_vm.properties.diagnosticsProfile.bootDiagnostics.enabled"
- name: Get facts for virtual machine without boot diagnostics disabled
azure_rm_virtualmachine_facts:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
register: output
- assert:
that:
- output.vms != []
- not output.vms[0].boot_diagnostics.enabled
- not output.vms[0].boot_diagnostics.storage_uri
- name: Enable boot diagnostics on an existing VM for the first time without specifying a storage account
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
boot_diagnostics:
enabled: true
# without specifying storage_account you get a new default storage account for the VM
register: output
- assert:
that:
- azure_vm.properties.diagnosticsProfile.bootDiagnostics.enabled
- azure_vm.properties.diagnosticsProfile.bootDiagnostics.storageUri is defined
- azure_vm.properties.instanceView.bootDiagnostics.consoleScreenshotBlobUri is defined
- azure_vm.properties.instanceView.bootDiagnostics.serialConsoleLogBlobUri is defined
- name: Get facts for virtual machine with boot diagnostics enabled
azure_rm_virtualmachine_facts:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
register: output
- assert:
that:
- output.vms != []
- output.vms[0].boot_diagnostics.enabled
- output.vms[0].boot_diagnostics.storage_uri is defined
- output.vms[0].boot_diagnostics.console_screenshot_uri is defined
- output.vms[0].boot_diagnostics.serial_console_log_uri is defined
- name: Change the boot diagnostics storage account while enabled
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
boot_diagnostics:
enabled: true
storage_account: "{{ storage_account2 }}"
ignore_errors: true
register: output
- name: Disable boot diagnostics and change the storage account at the same time
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
boot_diagnostics:
enabled: false
storage_account: "{{ storage_account }}"
register: output
- assert:
that:
- not azure_vm.properties.diagnosticsProfile.bootDiagnostics.enabled
- name: Re-enable boot diagnostics on an existing VM where it was previously configured
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name1 }}"
boot_diagnostics:
enabled: true
register: output
- assert:
that:
- azure_vm.properties.diagnosticsProfile.bootDiagnostics.enabled
- azure_vm.properties.diagnosticsProfile.bootDiagnostics.storageUri is defined
- azure_vm.properties.instanceView.bootDiagnostics.consoleScreenshotBlobUri is defined
- azure_vm.properties.instanceView.bootDiagnostics.serialConsoleLogBlobUri is defined
# - add_host:
# name: new_azure_vm
@ -244,8 +262,7 @@
- assert:
that: azure_publicipaddresses | length == 0
- name: Create virtual machine without public ip address
register: output
- name: Create virtual machine without public ip address and with boot diagnostics enabled
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: testvmnoip
@ -256,14 +273,21 @@
os_type: Linux
public_ip_allocation_method: Disabled
availability_set: "{{ abs_name1 }}"
boot_diagnostics:
enabled: true
image:
offer: UbuntuServer
publisher: Canonical
sku: 16.04-LTS
version: latest
register: output
- assert:
that:
- azure_vm.properties.diagnosticsProfile.bootDiagnostics.enabled
- azure_vm.properties.diagnosticsProfile.bootDiagnostics.storageUri is defined
- azure_vm.properties.instanceView.bootDiagnostics.consoleScreenshotBlobUri is defined
- azure_vm.properties.instanceView.bootDiagnostics.serialConsoleLogBlobUri is defined
- not 'publicIPAddress' in output.ansible_facts.azure_vm.properties.networkProfile.networkInterfaces[0].properties.ipConfigurations[0].properties
- name: Delete VM with no public ip
@ -271,6 +295,7 @@
resource_group: "{{ resource_group }}"
name: testvmnoip
state: absent
remove_on_absent: all_autocreated
vm_size: Standard_A0
async: 5000
poll: 0
@ -280,7 +305,7 @@
- name: testnic011
resource_group: "{{ resource_group_secondary }}"
- name: testnic012
resource_group: "{{ resource_group_secondary }}"
resource_group: "{{ resource_group_secondary }}"
- name: Create an availability set
azure_rm_availabilityset:
@ -307,11 +332,10 @@
name: "{{ item.name }}"
virtual_network: "{{ vn.state.id }}"
subnet: "{{ vm_name2 }}"
security_group: "{{ vm_name1 }}"
security_group: "{{ vm_name2 }}"
loop: "{{ niclist }}"
- name: Create virtual machine with two NICs
register: output
azure_rm_virtualmachine:
resource_group: "{{ resource_group }}"
name: "{{ vm_name2 }}"
@ -334,6 +358,8 @@
version: latest
tags:
abc: def
register: output
- assert:
that:
- azure_vm.properties.availabilitySet.id
@ -350,7 +376,7 @@
that:
- results.vms | length == 1
- results.vms[0].name == "{{ vm_name2 }}"
- results.vms[0].location == 'eastus'
- results.vms[0].location
- results.vms[0].admin_username == 'adminuser'
- results.vms[0].resource_group == "{{ resource_group }}"
- results.vms[0].power_state != None
@ -548,6 +574,7 @@
- name: Assert that autocreated resources were deleted
assert:
that:
# what about the default storage group?
- output_nic.ansible_facts.azure_networkinterfaces | length == 0
- output_nsg.ansible_facts.azure_securitygroups | length == 0
- output_pip.ansible_facts.azure_publicipaddresses | length == 0