Skip to content

Commit

Permalink
Add identity support to vmss module
Browse files Browse the repository at this point in the history
  • Loading branch information
p3ck committed Jun 4, 2024
1 parent 7597e14 commit 7e8537d
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 2 deletions.
100 changes: 98 additions & 2 deletions plugins/modules/azure_rm_virtualmachinescaleset.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,42 @@
Set C(key_data) to the actual value of the public key.
type: list
elements: dict
identity:
description:
- Identity for this resource.
type: dict
version_added: '2.5.0'
suboptions:
type:
description:
- Type of the managed identity
choices:
- SystemAssigned
- UserAssigned
- SystemAssigned, UserAssigned
- 'None'
default: 'None'
type: str
user_assigned_identities:
description:
- User Assigned Managed Identities and its options
required: false
type: dict
default: {}
suboptions:
id:
description:
- List of the user assigned IDs associated to this resource
required: false
type: list
elements: str
default: []
append:
description:
- If the list of identities has to be appended to current identities (true) or if it has to replace current identities (false)
required: false
type: bool
default: True
image:
description:
- Specifies the image used to build the VM.
Expand Down Expand Up @@ -653,12 +689,14 @@
from azure.core.exceptions import ResourceNotFoundError
from azure.mgmt.core.tools import parse_resource_id
from azure.core.exceptions import ResourceNotFoundError
from azure.mgmt.compute.models import (VirtualMachineScaleSetIdentity, UserAssignedIdentitiesValue)

except ImportError:
# This is handled in azure_rm_common
pass

from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase, azure_id_to_dict, format_resource_id
from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import azure_id_to_dict, format_resource_id
from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt
from ansible.module_utils.basic import to_native, to_bytes


Expand All @@ -667,7 +705,37 @@
AZURE_ENUM_MODULES = ['azure.mgmt.compute.models']


class AzureRMVirtualMachineScaleSet(AzureRMModuleBase):
user_assigned_identities_spec = dict(
id=dict(
type='list',
default=[],
elements='str'
),
append=dict(
type='bool',
default=True
)
)


managed_identity_spec = dict(
type=dict(
type='str',
choices=['SystemAssigned',
'UserAssigned',
'SystemAssigned, UserAssigned',
'None'],
default='None'
),
user_assigned_identities=dict(
type='dict',
options=user_assigned_identities_spec,
default={}
),
)


class AzureRMVirtualMachineScaleSet(AzureRMModuleBaseExt):

def __init__(self):

Expand Down Expand Up @@ -744,6 +812,10 @@ def __init__(self):
)
)
),
identity=dict(
type='dict',
options=managed_identity_spec
),
)

self.resource_group = None
Expand Down Expand Up @@ -786,6 +858,8 @@ def __init__(self):
self.orchestration_mode = None
self.os_disk_size_gb = None
self.security_profile = None
self._managed_identity = None
self.identity = None

mutually_exclusive = [('load_balancer', 'application_gateway')]
self.results = dict(
Expand All @@ -799,6 +873,14 @@ def __init__(self):
supports_check_mode=True,
mutually_exclusive=mutually_exclusive)

@property
def managed_identity(self):
if not self._managed_identity:
self._managed_identity = {"identity": VirtualMachineScaleSetIdentity,
"user_assigned": UserAssignedIdentitiesValue
}
return self._managed_identity

def exec_module(self, **kwargs):

for key in list(self.module_arg_spec.keys()) + ['tags']:
Expand Down Expand Up @@ -976,6 +1058,12 @@ def exec_module(self, **kwargs):
changed = True
vmss_dict['virtual_machine_profile']['storage_profile']['image_reference'] = image_reference.as_dict()

if self.identity:
update_identity, self.identity = self.update_identities(vmss_dict.get('identity', dict()))
if update_identity:
differences.append('Identity')
changed = True

update_tags, vmss_dict['tags'] = self.update_tags(vmss_dict.get('tags', dict()))
if update_tags:
differences.append('Tags')
Expand Down Expand Up @@ -1098,6 +1186,8 @@ def exec_module(self, **kwargs):
if self.state == 'present':
self.log("CHANGED: virtual machine scale set {0} does not exist but state is 'present'.".format(self.name))
changed = True
if self.identity:
update_identity, self.identity = self.update_identities(dict())

self.results['changed'] = changed
self.results['ansible_facts']['azure_vmss'] = results
Expand Down Expand Up @@ -1209,6 +1299,9 @@ def exec_module(self, **kwargs):
zones=self.zones
)

if self.identity:
vmss_resource.identity = self.identity

if self.priority == 'Spot':
vmss_resource.virtual_machine_profile.priority = self.priority
vmss_resource.virtual_machine_profile.eviction_policy = self.eviction_policy
Expand Down Expand Up @@ -1353,6 +1446,9 @@ def exec_module(self, **kwargs):
if self.terminate_event_timeout_minutes:
vmss_resource.virtual_machine_profile.scheduled_events_profile = self.gen_scheduled_event_profile()

if self.identity:
vmss_resource.identity = self.identity

if image_reference is not None:
vmss_resource.virtual_machine_profile.storage_profile.image_reference = image_reference

Expand Down
25 changes: 25 additions & 0 deletions plugins/modules/azure_rm_virtualmachinescaleset_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,30 @@
returned: always
type: str
sample: Standard_LRS
identity:
description:
- Identity for the Server.
type: complex
returned: when available
contains:
type:
description:
- Type of the managed identity
returned: always
sample: UserAssigned
type: str
user_assigned_identities:
description:
- User Assigned Managed Identities and its options
returned: always
type: complex
contains:
id:
description:
- Dict of the user assigned identities IDs associated to the Resource
returned: always
type: dict
elements: dict
image:
description:
- Image specification.
Expand Down Expand Up @@ -388,6 +412,7 @@ def exec_module(self, **kwargs):
'virtual_network_name': virtual_network_name,
'subnet_name': subnet_name,
'load_balancer': load_balancer_name,
'identity': vmss.get('identity', None),
'tags': vmss.get('tags')
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
- name: Gather Resource Group info
azure.azcollection.azure_rm_resourcegroup_info:
name: "{{ resource_group }}"
register: __rg_info

- name: Set location based on resource group
ansible.builtin.set_fact:
location: "{{ __rg_info.resourcegroups.0.location }}"

- name: Create User Managed Identities
azure_rm_resource:
resource_group: "{{ resource_group }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
resource_name: "{{ item }}"
api_version: "2023-01-31"
body:
location: "{{ location }}"
state: present
loop:
- "ansible-test-vmss-identity"
- "ansible-test-vmss-identity-2"

- name: Set identities IDs to test. Identities ansible-test-vmss-identity and ansible-test-vmss-identity-2 have to be created previously
ansible.builtin.set_fact:
user_identity_1: "/subscriptions/{{ azure_subscription_id }}/resourcegroups/{{ resource_group }}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ansible-test-vmss-identity"
user_identity_2: "/subscriptions/{{ azure_subscription_id }}/resourcegroups/{{ resource_group }}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ansible-test-vmss-identity-2"

- name: Prepare random number
ansible.builtin.set_fact:
rpfx: "{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"
Expand Down Expand Up @@ -139,6 +167,11 @@
disk_size_gb: 64
caching: ReadWrite
managed_disk_type: Standard_LRS
identity:
type: UserAssigned
user_assigned_identities:
id:
- "{{ user_identity_1 }}"
register: results

- name: Assert that VMSS can be created
Expand Down Expand Up @@ -173,6 +206,11 @@
disk_size_gb: 64
caching: ReadWrite
managed_disk_type: Standard_LRS
identity:
type: UserAssigned
user_assigned_identities:
id:
- "{{ user_identity_1 }}"
register: results

- name: Assert that VMSS can be created
Expand All @@ -189,6 +227,7 @@
ansible.builtin.assert:
that:
- output_scaleset.vmss[0].orchestration_mode == "Flexible"
- user_identity_1 in output_scaleset.vmss[0].identity.user_assigned_identities

- name: Delete VMSS
azure_rm_virtualmachinescaleset:
Expand Down Expand Up @@ -227,14 +266,24 @@
disk_size_gb: 64
caching: ReadWrite
managed_disk_type: Standard_LRS
identity:
type: SystemAssigned, UserAssigned
user_assigned_identities:
id:
- "{{ user_identity_1 }}"
register: results

- name: Debug
ansible.builtin.debug:
var: results

- name: Assert that VMSS was created using Spot Instance default values
ansible.builtin.assert:
that:
- results.ansible_facts.azure_vmss.virtual_machine_profile.priority == 'Spot'
- results.ansible_facts.azure_vmss.virtual_machine_profile.eviction_policy == 'Deallocate'
- results.ansible_facts.azure_vmss.virtual_machine_profile.billing_profile.max_price == -1.0
- user_identity_1 in results.ansible_facts.azure_vmss.identity.user_assigned_identities

- name: Delete VMSS
azure_rm_virtualmachinescaleset:
Expand Down Expand Up @@ -923,3 +972,15 @@
name: invalid-image
register: fail_missing_custom_image_dict
failed_when: fail_missing_custom_image_dict.msg != "Error could not find image with name invalid-image"

- name: Destroy User Managed Identities
azure_rm_resource:
resource_group: "{{ resource_group }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
resource_name: "{{ item }}"
api_version: "2023-01-31"
state: absent
loop:
- "ansible-test-vmss-identity"
- "ansible-test-vmss-identity-2"

0 comments on commit 7e8537d

Please sign in to comment.