From 177e7f98a06d82ea1d62fec6389f5d81ffedddac Mon Sep 17 00:00:00 2001 From: Fred-sun Date: Fri, 11 Dec 2020 16:21:30 +0800 Subject: [PATCH 1/8] Add Azure lighthouse modules --- .../azure_rm_registrationassignment.py | 279 +++++++++++ .../azure_rm_registrationassignment_info.py | 193 ++++++++ .../azure_rm_registrationdefinition.py | 434 ++++++++++++++++++ .../azure_rm_registrationdefinition_info.py | 241 ++++++++++ pr-pipelines.yml | 5 + requirements-azure.txt | 1 + .../azure_rm_registrationassignment/aliases | 3 + .../meta/main.yml | 2 + .../tasks/main.yml | 79 ++++ .../azure_rm_registrationdefinition/aliases | 3 + .../meta/main.yml | 2 + .../tasks/main.yml | 108 +++++ tests/sanity/ignore-2.10.txt | 11 + tests/sanity/ignore-2.11.txt | 11 + tests/utils/ado/ado.sh | 3 + 15 files changed, 1375 insertions(+) create mode 100644 plugins/modules/azure_rm_registrationassignment.py create mode 100644 plugins/modules/azure_rm_registrationassignment_info.py create mode 100644 plugins/modules/azure_rm_registrationdefinition.py create mode 100644 plugins/modules/azure_rm_registrationdefinition_info.py create mode 100644 tests/integration/targets/azure_rm_registrationassignment/aliases create mode 100644 tests/integration/targets/azure_rm_registrationassignment/meta/main.yml create mode 100644 tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml create mode 100644 tests/integration/targets/azure_rm_registrationdefinition/aliases create mode 100644 tests/integration/targets/azure_rm_registrationdefinition/meta/main.yml create mode 100644 tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml diff --git a/plugins/modules/azure_rm_registrationassignment.py b/plugins/modules/azure_rm_registrationassignment.py new file mode 100644 index 000000000..f8bd14321 --- /dev/null +++ b/plugins/modules/azure_rm_registrationassignment.py @@ -0,0 +1,279 @@ +#!/usr/bin/python +# +# Copyright (c) 2020 Fred-Sun, (@Fred-Sun) +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: azure_rm_registrationassignment +version_added: '1.3.0' +short_description: Manage Azure RegistrationAssignment instance +description: + - Create and delete instance of Azure RegistrationAssignment. +options: + scope: + description: + - Scope of the registration assignment.. + required: true + type: str + registration_assignment_id: + description: + - ID of the registration assignment. + type: str + properties: + description: + - Properties of a registration assignment. + type: dict + suboptions: + registration_definition_id: + description: + - Fully qualified path of the registration definition. + required: true + type: str + state: + description: + - Assert the state of the RegistrationAssignment. + - Use C(present) to create or update an RegistrationAssignment and C(absent) to delete it. + default: present + type: str + choices: + - absent + - present +extends_documentation_fragment: + - azure.azcollection.azure + - azure.azcollection.azure_tags +author: + - Fred-Sun (@Fred-Sun) + +''' + +EXAMPLES = ''' + - name: Delete Registration Assignment + azure_rm_registrationassignment: + scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + registration_assignment_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + state: absent + + + - name: Create Registration Assignment in subscription level + azure_rm_registrationassignment: + scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + registration_assignment_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + properties: + registration_definition_id: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationDefinitions/xxx-xxx + + + - name: Create Registration Assignment in resourcegroup level + azure_rm_registrationassignment: + scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup + registration_assignment_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + properties: + registration_definition_id: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationDefinitions/xxx-xxx + +''' + +RETURN = ''' +state: + description: + - The state info of the registration assignment. + type: complex + returned: always + contains: + properties: + description: + - Properties of a registration assignment. + returned: always + type: complex + contains: + registration_definition_id: + description: + - Fully qualified path of the registration definition. + returned: always + type: str + sample: null + id: + description: + - The fully qualified path of the registration assignment. + returned: always + type: str + sample: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationAssignments/xxx-xxx + type: + description: + - Type of the resource. + returned: always + type: str + sample: Microsoft.ManagedServices/registrationAssignments + name: + description: + - Name of the registration assignment. + returned: always + type: str + sample: 9b2895ec-fb1e-4a1e-a978-abd9933d6b20 + +''' +import uuid +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt +try: + from msrestazure.azure_exceptions import CloudError + from azure.mgmt.managedservices import ManagedServicesClient + from msrestazure.azure_operation import AzureOperationPoller + from msrest.polling import LROPoller +except ImportError: + # This is handled in azure_rm_common + pass + + +class Actions: + NoAction, Create, Update, Delete = range(4) + + +class AzureRMRegistrationAssignment(AzureRMModuleBaseExt): + def __init__(self): + self.module_arg_spec = dict( + scope=dict( + type='str', + required=True + ), + registration_assignment_id=dict( + type='str', + ), + properties=dict( + type='dict', + disposition='/properties', + options=dict( + registration_definition_id=dict( + type='str', + disposition='registration_definition_id', + required=True + ) + ) + ), + state=dict( + type='str', + default='present', + choices=['present', 'absent'] + ) + ) + + self.scope = None + self.registration_assignment_id = None + self.expand_registration_definition = False + self.body = {} + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.to_do = Actions.NoAction + + super(AzureRMRegistrationAssignment, self).__init__(derived_arg_spec=self.module_arg_spec, + supports_check_mode=True, + supports_tags=True) + + def exec_module(self, **kwargs): + for key in list(self.module_arg_spec.keys()): + if hasattr(self, key): + setattr(self, key, kwargs[key]) + elif kwargs[key] is not None: + self.body[key] = kwargs[key] + + self.inflate_parameters(self.module_arg_spec, self.body, 0) + + old_response = None + response = None + if self.registration_assignment_id is None: + self.registration_assignment_id = str(uuid.uuid4()) + + self.mgmt_client = self.get_mgmt_svc_client(ManagedServicesClient, + base_url=self._cloud_environment.endpoints.resource_manager, + api_version='2019-09-01', + suppress_subscription_id=True) + + old_response = self.get_resource() + + if not old_response: + if self.state == 'present': + self.to_do = Actions.Create + else: + if self.state == 'absent': + self.to_do = Actions.Delete + else: + modifiers = {} + self.create_compare_modifiers(self.module_arg_spec, '', modifiers) + self.results['modifiers'] = modifiers + self.results['compare'] = [] + if not self.default_compare(modifiers, self.body, old_response, '', self.results): + self.to_do = Actions.Update + + if (self.to_do == Actions.Create) or (self.to_do == Actions.Update): + self.results['changed'] = True + if self.check_mode: + return self.results + response = self.create_update_resource() + self.results['state'] = response + elif self.to_do == Actions.Delete: + self.results['changed'] = True + if self.check_mode: + return self.results + self.delete_resource() + else: + self.results['changed'] = False + response = old_response + self.results['state'] = response + + if self.state is 'present': + if self.results['state'].get('properties', None) is not None: + registration_definition_id = self.results['state']['properties']['registration_definition_id'] + self.results['state']['properties'].clear() + self.results['state']['properties']['registration_definition_id'] = registration_definition_id + + return self.results + + def create_update_resource(self): + try: + response = self.mgmt_client.registration_assignments.create_or_update(scope=self.scope, + registration_assignment_id=self.registration_assignment_id, + properties=self.body.get('properties', None), + request_body=self.body) + if isinstance(response, AzureOperationPoller) or isinstance(response, LROPoller): + response = self.get_poller_result(response) + except CloudError as exc: + self.log('Error attempting to create the RegistrationAssignment instance.') + self.fail('Error creating the RegistrationAssignment instance: {0}'.format(str(exc))) + return response.as_dict() + + def delete_resource(self): + try: + response = self.mgmt_client.registration_assignments.delete(scope=self.scope, + registration_assignment_id=self.registration_assignment_id) + except CloudError as e: + self.log('Error attempting to delete the RegistrationAssignment instance.') + self.fail('Error deleting the RegistrationAssignment instance: {0}'.format(str(e))) + + return True + + def get_resource(self): + try: + response = self.mgmt_client.registration_assignments.get(scope=self.scope, + registration_assignment_id=self.registration_assignment_id, + expand_registration_definition=self.expand_registration_definition) + except Exception as e: + return False + return response.as_dict() + + +def main(): + AzureRMRegistrationAssignment() + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/azure_rm_registrationassignment_info.py b/plugins/modules/azure_rm_registrationassignment_info.py new file mode 100644 index 000000000..0c6b1af4b --- /dev/null +++ b/plugins/modules/azure_rm_registrationassignment_info.py @@ -0,0 +1,193 @@ +#!/usr/bin/python +# +# Copyright (c) 2020 Fred-Sun, (@Fred-Sun) +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: azure_rm_registrationassignment_info +version_added: '1.3.0' +short_description: Get RegistrationAssignment info +description: + - Get info of RegistrationAssignment. +options: + scope: + description: + - Scope of the registration assignment. + required: true + type: str + registration_assignment_id: + description: + - ID of the registration assignment. + type: str +extends_documentation_fragment: + - azure.azcollection.azure + - azure.azcollection.azure_tags +author: + - Fred-Sun (@Fred-Sun) + +''' + +EXAMPLES = ''' + - name: Get Registration Assignment + azure_rm_registrationassignment_info: + registration_assignment_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + scope: subscription/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup + + + - name: Get All Registration Assignments in scope(subscription) + azure_rm_registrationassignment_info: + scope: subscription/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + + +''' + +RETURN = ''' +registration_assignments: + description: + - A list of dict results where the key is the name of the RegistrationAssignment. + - The values are the facts for that RegistrationAssignment. + returned: always + type: complex + contains: + properties: + description: + - Properties of a registration assignment. + returned: always + type: complex + contains: + registration_definition_id: + description: + - Fully qualified path of the registration definition. + returned: always + type: str + sample: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationDefinitions/xxx-xxx + id: + description: + - The fully qualified path of the registration assignment. + returned: always + type: str + sample: /subscriptions/xxx-xxxf/providers/Microsoft.ManagedServices/registrationAssignments/xxx-xxx + type: + description: + - Type of the resource. + returned: always + type: str + sample: Microsoft.ManagedServices/registrationAssignment + name: + description: + - Name of the registration assignment. + returned: always + type: str + sample: 9b2895ec-fb1e-4a1e-a978-abd9933d6b20 +''' + +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBase +try: + from msrestazure.azure_exceptions import CloudError + from azure.mgmt.managedservices import ManagedServicesClient + from msrestazure.azure_operation import AzureOperationPoller + from msrest.polling import LROPoller +except ImportError: + # This is handled in azure_rm_common + pass + + +class AzureRMRegistrationAssignmentInfo(AzureRMModuleBase): + def __init__(self): + self.module_arg_spec = dict( + scope=dict( + type='str', + required=True + ), + registration_assignment_id=dict( + type='str' + ) + ) + + self.scope = None + self.registration_assignment_id = None + self.expand_registration_definition = False + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.url = None + self.status_code = [200] + + self.mgmt_client = None + super(AzureRMRegistrationAssignmentInfo, self).__init__(self.module_arg_spec, supports_tags=True) + + def exec_module(self, **kwargs): + + for key in self.module_arg_spec: + setattr(self, key, kwargs[key]) + + self.mgmt_client = self.get_mgmt_svc_client(ManagedServicesClient, + base_url=self._cloud_environment.endpoints.resource_manager, + api_version='2020-09-01', + suppress_subscription_id=True) + + if (self.scope is not None and self.registration_assignment_id is not None): + self.results['registration_assignments'] = self.format_item(self.get()) + elif (self.scope is not None): + self.results['registration_assignments'] = self.format_item(self.list()) + + if len(self.results['registration_assignments']) > 0: + for item in self.results['registration_assignments']: + if item.get('properties', None) is not None: + registration_definition_id = item['properties']['registration_definition_id'] + item['properties'].clear() + item['properties']['registration_definition_id'] = registration_definition_id + return self.results + + def get(self): + response = None + + try: + response = self.mgmt_client.registration_assignments.get(scope=self.scope, + registration_assignment_id=self.registration_assignment_id, + expand_registration_definition=self.expand_registration_definition) + except Exception as e: + self.log('Could not get info for @(Model.ModuleOperationNameUpper).') + + return response + + def list(self): + response = None + + try: + response = self.mgmt_client.registration_assignments.list(scope=self.scope, + expand_registration_definition=self.expand_registration_definition) + except Exception as e: + self.log('Could not get info for @(Model.ModuleOperationNameUpper).') + + return response + + def format_item(self, item): + if hasattr(item, 'as_dict'): + return [item.as_dict()] + else: + result = [] + items = list(item) + for tmp in items: + result.append(tmp.as_dict()) + return result + + +def main(): + AzureRMRegistrationAssignmentInfo() + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/azure_rm_registrationdefinition.py b/plugins/modules/azure_rm_registrationdefinition.py new file mode 100644 index 000000000..05bfc476f --- /dev/null +++ b/plugins/modules/azure_rm_registrationdefinition.py @@ -0,0 +1,434 @@ +#!/usr/bin/python +# +# Copyright (c) 2020 Fred-Sun, (@Fred-Sun) +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: azure_rm_registrationdefinition +version_added: '1.3.0' +short_description: Manage Azure RegistrationDefinition instance +description: + - Create, update and delete instance of Azure RegistrationDefinition. +options: + scope: + description: + - Scope of the resource. + required: true + type: str + registration_definition_id: + description: + - Guid of the registration definition. + type: str + properties: + description: + - Properties of a registration definition. + type: dict + suboptions: + description: + description: + - Description of the registration definition. + type: str + authorizations: + description: + - Authorization tuple containing principal id of the user/security group or service principal and id of the build-in role. + required: true + type: list + suboptions: + principal_id: + description: + - Principal Id of the security group/service principal/user that would be assigned permissions to the projected subscription + required: true + type: str + role_definition_id: + description: + - The role definition identifier. + - This role will define all the permissions that the security group/service principal/user must have on the projected subscription. + - This role cannot be an owner role. + required: true + type: str + registration_definition_name: + description: + - Name of the registration definition. + type: str + managed_by_tenant_id: + description: + - Id of the managedBy tenant. + required: true + type: str + plan: + description: + - Plan details for the managed services. + type: dict + suboptions: + name: + description: + - The plan name. + required: true + type: str + publisher: + description: + - The publisher ID. + required: true + type: str + product: + description: + - The product code. + required: true + type: str + version: + description: + - The plan's version. + required: true + type: str + state: + description: + - Assert the state of the RegistrationDefinition. + - Use C(present) to create or update an RegistrationDefinition and C(absent) to delete it. + default: present + type: str + choices: + - absent + - present +extends_documentation_fragment: + - azure.azcollection.azure + - azure.azcollection.azure_tags +author: + - Fred-Sun (@Fred-Sun) + +''' + +EXAMPLES = ''' + - name: Delete Registration Definition + azure_rm_registrationdefinition: + registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + state: absent + + - name: Create Registration Definition + azure_rm_registrationdefinition: + registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + properties: + description: test + authorizations: + - principal_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + role_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + managed_by_tenant_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + registration_definition_name: def4 + +''' + +RETURN = ''' +state: + description: + - The state info of the registration assignment. + type: complex + returned: always + contains: + properties: + description: + - Properties of a registration definition. + returned: always + type: complex + contains: + description: + description: + - Description of the registration definition. + returned: always + type: str + sample: test + authorizations: + description: + - Authorization tuple containing principal ID of the user/security group or service principal and ID of the build-in role. + returned: always + type: complex + contains: + principal_id: + description: + - Principal ID of the security group/service principal/user that would be assigned permissions to the projected subscription + returned: always + type: str + sample: 99e3227f-8701-4099-869f-bc3efc7f1e64 + role_definition_id: + description: + - The role definition identifier. + - This role will define all the permissions that the security group/service principal/user must have on the subscription. + - This role cannot be an owner role. + returned: always + type: str + sample: b24988ac-6180-42a0-ab88-20f7382dd24c + registration_definition_name: + description: + - Name of the registration definition. + returned: always + type: str + sample: null + managed_by_tenant_id: + description: + - ID of the managedBy tenant. + returned: always + type: str + sample: null + plan: + description: + - Plan details for the managed services. + returned: always + type: complex + contains: + name: + description: + - The plan name. + returned: always + type: str + sample: null + publisher: + description: + - The publisher ID. + returned: always + type: str + sample: null + product: + description: + - The product code. + returned: always + type: str + sample: null + version: + description: + - The plan's version. + returned: always + type: str + sample: null + id: + description: + - Fully qualified path of the registration definition. + returned: always + type: str + sample: null + type: + description: + - Type of the resource. + returned: always + type: str + sample: Microsoft.ManagedServices/registrationDefinitions + name: + description: + - Name of the registration definition. + returned: always + type: str + sample: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationDefinitions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + +''' +import uuid +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt +try: + from msrestazure.azure_exceptions import CloudError + from azure.mgmt.managedservices import ManagedServicesClient + from msrestazure.azure_operation import AzureOperationPoller + from msrest.polling import LROPoller +except ImportError: + # This is handled in azure_rm_common + pass + + +class Actions: + NoAction, Create, Update, Delete = range(4) + + +class AzureRMRegistrationDefinition(AzureRMModuleBaseExt): + def __init__(self): + self.module_arg_spec = dict( + scope=dict( + type='str', + required=True + ), + registration_definition_id=dict( + type='str', + ), + properties=dict( + type='dict', + disposition='/properties', + options=dict( + description=dict( + type='str', + disposition='description' + ), + authorizations=dict( + type='list', + disposition='authorizations', + required=True, + elements='dict', + options=dict( + principal_id=dict( + type='str', + disposition='principal_id', + required=True + ), + role_definition_id=dict( + type='str', + disposition='role_definition_id', + required=True + ) + ) + ), + registration_definition_name=dict( + type='str', + disposition='registration_definition_name' + ), + managed_by_tenant_id=dict( + type='str', + disposition='managed_by_tenant_id', + required=True + ) + ) + ), + plan=dict( + type='dict', + disposition='/plan', + options=dict( + name=dict( + type='str', + disposition='name', + required=True + ), + publisher=dict( + type='str', + disposition='publisher', + required=True + ), + product=dict( + type='str', + disposition='product', + required=True + ), + version=dict( + type='str', + disposition='version', + required=True + ) + ) + ), + state=dict( + type='str', + default='present', + choices=['present', 'absent'] + ) + ) + + self.scope = None + self.registration_definition_id = None + self.body = {} + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.to_do = Actions.NoAction + + super(AzureRMRegistrationDefinition, self).__init__(derived_arg_spec=self.module_arg_spec, + supports_check_mode=True, + supports_tags=True) + + def exec_module(self, **kwargs): + for key in list(self.module_arg_spec.keys()): + if hasattr(self, key): + setattr(self, key, kwargs[key]) + elif kwargs[key] is not None: + self.body[key] = kwargs[key] + + self.inflate_parameters(self.module_arg_spec, self.body, 0) + + if self.registration_definition_id is None: + self.registration_definition_id = str(uuid.uuid4()) + + old_response = None + response = None + + self.mgmt_client = self.get_mgmt_svc_client(ManagedServicesClient, + base_url=self._cloud_environment.endpoints.resource_manager, + api_version='2019-09-01', + suppress_subscription_id=True) + + old_response = self.get_resource() + + if not old_response: + if self.state == 'present': + self.to_do = Actions.Create + else: + if self.state == 'absent': + self.to_do = Actions.Delete + else: + modifiers = {} + self.create_compare_modifiers(self.module_arg_spec, '', modifiers) + self.results['modifiers'] = modifiers + self.results['compare'] = [] + if not self.default_compare(modifiers, self.body, old_response, '', self.results): + self.to_do = Actions.Update + + if (self.to_do == Actions.Create) or (self.to_do == Actions.Update): + self.results['changed'] = True + if self.check_mode: + return self.results + response = self.create_update_resource() + self.results['state'] = response + elif self.to_do == Actions.Delete: + self.results['changed'] = True + if self.check_mode: + return self.results + self.delete_resource() + else: + self.results['changed'] = False + response = old_response + + return self.results + + def create_update_resource(self): + + try: + response = self.mgmt_client.registration_definitions.create_or_update(registration_definition_id=self.registration_definition_id, + scope=self.scope, + plan=self.body.get('plan', None), + properties=self.body.get('properties', None), + request_body=self.body) + if isinstance(response, AzureOperationPoller) or isinstance(response, LROPoller): + response = self.get_poller_result(response) + except CloudError as exc: + self.log('Error attempting to create the RegistrationDefinition instance.') + self.fail('Error creating the RegistrationDefinition instance: {0}'.format(str(exc))) + return response.as_dict() + + def delete_resource(self): + try: + response = self.mgmt_client.registration_definitions.delete(registration_definition_id=self.registration_definition_id, + scope=self.scope) + except CloudError as e: + self.log('Error attempting to delete the RegistrationDefinition instance.') + self.fail('Error deleting the RegistrationDefinition instance: {0}'.format(str(e))) + + return True + + def get_resource(self): + try: + response = self.mgmt_client.registration_definitions.get(scope=self.scope, + registration_definition_id=self.registration_definition_id) + except Exception as e: + return False + return response.as_dict() + + +def main(): + AzureRMRegistrationDefinition() + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/azure_rm_registrationdefinition_info.py b/plugins/modules/azure_rm_registrationdefinition_info.py new file mode 100644 index 000000000..c0939b1ba --- /dev/null +++ b/plugins/modules/azure_rm_registrationdefinition_info.py @@ -0,0 +1,241 @@ +#!/usr/bin/python +# +# Copyright (c) 2020 Fred-Sun, (@Fred-Sun) +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: azure_rm_registrationdefinition_info +version_added: '1.3.0' +short_description: Get RegistrationDefinition info +description: + - Get info of RegistrationDefinition. +options: + scope: + description: + - Scope of the resource. + required: true + type: str + registration_definition_id: + description: + - Guid of the registration definition. + type: str +extends_documentation_fragment: + - azure.azcollection.azure + - azure.azcollection.azure_tags +author: + - Fred-Sun (@Fred-Sun) +''' + +EXAMPLES = ''' + - name: Get Registration Definition + azure_rm_registrationdefinition_info: + registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + scope: subscription/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + + - name: Get Registration Definitions + azure_rm_registrationdefinition_info: + scope: subscription/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + +''' + +RETURN = ''' +registration_definitions: + description: + - A list of dict results where the key is the name of the RegistrationDefinition and the values are the facts for that RegistrationDefinition. + returned: always + type: complex + contains: + properties: + description: + - Properties of a registration definition. + returned: always + type: complex + contains: + description: + description: + - Description of the registration definition. + returned: always + type: str + sample: null + authorizations: + description: + - Authorization tuple containing principal ID of the user/security group or service principal and id of the build-in role. + returned: always + type: complex + contains: + principal_id: + description: + - Principal ID of the security group/service principal/user that would be assigned permissions to the projected subscription. + returned: always + type: str + sample: null + role_definition_id: + description: + - The role definition identifier. + - The role will define all the permissions that the security group/service principal/user must have on the subscription. + - The role cannot be an owner role. + returned: always + type: str + sample: null + registration_definition_name: + description: + - Name of the registration definition. + returned: always + type: str + sample: null + managed_by_tenant_id: + description: + - ID of the managedBy tenant. + returned: always + type: str + sample: null + plan: + description: + - Plan details for the managed services. + returned: always + type: complex + contains: + name: + description: + - The plan name. + returned: always + type: str + sample: null + publisher: + description: + - The publisher ID. + returned: always + type: str + sample: null + product: + description: + - The product code. + returned: always + type: str + sample: null + version: + description: + - The plan's version. + returned: always + type: str + sample: null + id: + description: + - Fully qualified path of the registration definition. + returned: always + type: str + sample: null + type: + description: + - Type of the resource. + returned: always + type: str + sample: null + name: + description: + - Name of the registration definition. + returned: always + type: str + sample: null +''' + +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBase +try: + from msrestazure.azure_exceptions import CloudError + from azure.mgmt.managedservices import ManagedServicesClient + from msrestazure.azure_operation import AzureOperationPoller + from msrest.polling import LROPoller +except ImportError: + # This is handled in azure_rm_common + pass + + +class AzureRMRegistrationDefinitionInfo(AzureRMModuleBase): + def __init__(self): + self.module_arg_spec = dict( + scope=dict( + type='str', + required=True + ), + registration_definition_id=dict( + type='str' + ) + ) + + self.scope = None + self.registration_definition_id = None + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.url = None + self.status_code = [200] + + self.mgmt_client = None + super(AzureRMRegistrationDefinitionInfo, self).__init__(self.module_arg_spec, supports_tags=True) + + def exec_module(self, **kwargs): + + for key in self.module_arg_spec: + setattr(self, key, kwargs[key]) + + self.mgmt_client = self.get_mgmt_svc_client(ManagedServicesClient, + base_url=self._cloud_environment.endpoints.resource_manager, + api_version='2019-09-01', + suppress_subscription_id=True) + + if (self.scope is not None and self.registration_definition_id is not None): + self.results['registration_definitions'] = self.format_item(self.get()) + elif (self.scope is not None): + self.results['registration_definitions'] = self.format_item(self.list()) + return self.results + + def get(self): + response = None + + try: + response = self.mgmt_client.registration_definitions.get(scope=self.scope, + registration_definition_id=self.registration_definition_id) + except Exception as e: + self.log('Could not get info for @(Model.ModuleOperationNameUpper).') + + return response + + def list(self): + response = None + + try: + response = self.mgmt_client.registration_definitions.list(scope=self.scope) + except Exception as e: + self.log('Could not get info for @(Model.ModuleOperationNameUpper).') + + return response + + def format_item(self, item): + if hasattr(item, 'as_dict'): + return [item.as_dict()] + else: + result = [] + items = list(item) + for tmp in items: + result.append(tmp.as_dict()) + return result + + +def main(): + AzureRMRegistrationDefinitionInfo() + + +if __name__ == '__main__': + main() diff --git a/pr-pipelines.yml b/pr-pipelines.yml index c8f052d77..a16391454 100644 --- a/pr-pipelines.yml +++ b/pr-pipelines.yml @@ -62,6 +62,8 @@ parameters: - "azure_rm_resourcegroup" - "azure_rm_routetable" - "azure_rm_roleassignment" + - "azure_rm_registrationassignment" + - "azure_rm_registrationdefinition" - "azure_rm_securitygroup" - "azure_rm_servicebus" - "azure_rm_sqlserver" @@ -174,6 +176,9 @@ jobs: AZURE_SECRET: $(AZURE_SECRET) AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID) AZURE_TENANT: $(AZURE_TENANT) + AZURE_PRINCIPAL_ID: $(AZURE_PRINCIPAL_ID) + AZURE_MANAGED_BY_TENANT_ID: $(AZURE_MANAGED_BY_TENANT_ID) + AZURE_ROLE_DEFINITION_ID: $(AZURE_ROLE_DEFINITION_ID) RESOURCE_GROUP: $(TEST_RESOURCE_GROUP) RESOURCE_GROUP_SECONDARY: $(TEST_RESOURCE_GROUP_SECONDARY) displayName: 'Running Tests' diff --git a/requirements-azure.txt b/requirements-azure.txt index 50858a028..d0b84379e 100644 --- a/requirements-azure.txt +++ b/requirements-azure.txt @@ -15,6 +15,7 @@ azure-mgmt-dns==2.1.0 azure-mgmt-keyvault==1.1.0 azure-mgmt-marketplaceordering==0.1.0 azure-mgmt-monitor==0.5.2 +azure-mgmt-managedservices==1.0.0 azure-mgmt-network==10.2.0 azure-mgmt-nspkg==2.0.0 azure-mgmt-privatedns==0.1.0 diff --git a/tests/integration/targets/azure_rm_registrationassignment/aliases b/tests/integration/targets/azure_rm_registrationassignment/aliases new file mode 100644 index 000000000..759eafa2d --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationassignment/aliases @@ -0,0 +1,3 @@ +cloud/azure +shippable/azure/group3 +destructive diff --git a/tests/integration/targets/azure_rm_registrationassignment/meta/main.yml b/tests/integration/targets/azure_rm_registrationassignment/meta/main.yml new file mode 100644 index 000000000..95e1952f9 --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationassignment/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - setup_azure diff --git a/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml new file mode 100644 index 000000000..ad3a2a7b6 --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml @@ -0,0 +1,79 @@ +- name: set guid for registration assignment id + set_fact: + subscription_id: "{{ azure_subscription_id }}" + managed_by_tenant_id: "{{ azure_managed_by_tenant_id }}" + principal_id: "{{ azure_principal_id }}" + role_definition_id: "{{ azure_role_definition_id }}" + run_once: yes + +- name: Create a RegistrationDefinition + azure_rm_registrationdefinition: + scope: subscriptions/{{ subscription_id }} + properties: + description: first_test + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: test_def + register: def_output + +- name: Create a RegistrationAssignment ---check mode + azure_rm_registrationassignment: + scope: subscriptions/{{ subscription_id }} + properties: + registration_definition_id: "{{ def_output.state.id }}" + register: output + check_mode: yes + +- assert: + that: + - output.changed + +- name: Create a RegistrationAssignment + azure_rm_registrationassignment: + scope: subscriptions/{{ subscription_id }} + properties: + registration_definition_id: "{{ def_output.state.id }}" + expand_registration_definition: true + register: ass_output + +- assert: + that: + - ass_output.changed + +- name: Create a RegistrationAssignment -- idempotent + azure_rm_registrationassignment: + scope: subscriptions/{{ subscription_id }} + registration_assignment_id: "{{ ass_output.state.name }}" + properties: + registration_definition_id: "{{ def_output.state.id }}" + expand_registration_definition: true + register: output + +- assert: + that: + - not output.changed + +- name: Get a RegistrationAssignment + azure_rm_registrationassignment_info: + scope: subscriptions/{{ subscription_id }} + registration_assignment_id: "{{ ass_output.state.name }}" + expand_registration_definition: true + register: output + +- assert: + that: + - output.registration_assignments[0].properties.registration_definition_id == "{{ def_output.state.id }}" + +- name: Delete the RegistrationAssignment + azure_rm_registrationassignment: + scope: subscriptions/{{ subscription_id }} + registration_assignment_id: "{{ ass_output.state.name }}" + state: absent + +#- name: Delete the registration definition +# azure_rm_registrationdefinition: +# registration_definition_id: "{{ def_output.state.name }}" +# scope: subscriptions//{{ subscription_id }} +# state: absent diff --git a/tests/integration/targets/azure_rm_registrationdefinition/aliases b/tests/integration/targets/azure_rm_registrationdefinition/aliases new file mode 100644 index 000000000..759eafa2d --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationdefinition/aliases @@ -0,0 +1,3 @@ +cloud/azure +shippable/azure/group3 +destructive diff --git a/tests/integration/targets/azure_rm_registrationdefinition/meta/main.yml b/tests/integration/targets/azure_rm_registrationdefinition/meta/main.yml new file mode 100644 index 000000000..95e1952f9 --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationdefinition/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - setup_azure diff --git a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml new file mode 100644 index 000000000..4d42a8a8e --- /dev/null +++ b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml @@ -0,0 +1,108 @@ +- name: set guid for registration definition id + set_fact: + subscription_id: "{{ azure_subscription_id }}" + managed_by_tenant_id: "{{ azure_managed_by_tenant_id }}" + principal_id: "{{ azure_principal_id }}" + role_definition_id: "{{ azure_role_definition_id }}" + reg_def_name: test_name + run_once: yes + +- name: Create a RegistrationDefinition -- check mode + azure_rm_registrationdefinition: + scope: subscriptions/{{ subscription_id }} + properties: + description: first_test + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: "{{ reg_def_name }}" + check_mode: yes + register: output + +- name: Assert creating registration definition check mode + assert: + that: + - output.changed + +- name: Create a RegistrationDefinition + azure_rm_registrationdefinition: + scope: subscriptions/{{ subscription_id }} + properties: + description: first_test + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: "{{ reg_def_name }}" + register: def_output + tags: fred + +- name: Assert creating registration definition + assert: + that: + - output.changed + +- name: Create a RegistrationDefinition (idempotent) + azure_rm_registrationdefinition: + registration_definition_id: "{{ def_output.state.name }}" + scope: subscriptions/{{ subscription_id }} + properties: + description: first_test + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: "{{ reg_def_name }}" + register: output + +- name: Assert creating registration definition + assert: + that: + - not output.changed + +- name: Update the RegistrationDefinition properties description and name + azure_rm_registrationdefinition: + registration_definition_id: "{{ def_output.state.name }}" + scope: subscriptions/{{ subscription_id }} + properties: + description: second_test + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: "{{ reg_def_name }}02" + register: output + +- name: Assert creating registration definition + assert: + that: + - output.changed + +- name: Get the Registration Definition info + azure_rm_registrationdefinition_info: + registration_definition_id: "{{ def_output.state.name }}" + scope: subscriptions/{{ subscription_id }} + register: output + +- name: Assert the registration definition info + assert: + that: + - output.registration_definitions[0].name == "{{ def_output.state.name }}" + - output.registration_definitions[0].properties.authorizations[0].principal_id == "{{ principal_id }}" + - output.registration_definitions[0].properties.authorizations[0].role_definition_id == "{{ role_definition_id }}" + - output.registration_definitions[0].properties.provisioning_state == "Succeeded" + - output.registration_definitions[0].properties.description == "second_test" + - output.registration_definitions[0].properties.registration_definition_name == "test_name02" + +- name: Delete the registration definition + azure_rm_registrationdefinition: + registration_definition_id: "{{ def_output.state.name }}" + scope: subscriptions/{{ subscription_id }} + state: absent + register: output + +- name: Assert delete registration definition success + assert: + that: + - output.changed diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index 1b4c0fdf5..e8d94a92b 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -241,6 +241,17 @@ plugins/modules/azure_rm_resourcegroup_info.py validate-modules:parameter-type-n plugins/modules/azure_rm_resourcegroup_info.py validate-modules:parameter-list-no-elements plugins/modules/azure_rm_resourcegroup_info.py validate-modules:required_if-requirements-unknown plugins/modules/azure_rm_resourcegroup_info.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationdefinition.py validate-modules:doc-elements-mismatch +plugins/modules/azure_rm_registrationdefinition.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/azure_rm_registrationdefinition.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationdefinition.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationdefinition_info.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationdefinition_info.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationassignment.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationassignment.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationassignment.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/azure_rm_registrationassignment_info.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationassignment_info.py validate-modules:required_if-unknown-key plugins/modules/azure_rm_securitygroup.py validate-modules:doc-choices-do-not-match-spec plugins/modules/azure_rm_securitygroup.py validate-modules:doc-default-does-not-match-spec plugins/modules/azure_rm_securitygroup.py validate-modules:missing-suboption-docs diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 1168ac357..c4358e5ca 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -241,6 +241,17 @@ plugins/modules/azure_rm_resourcegroup_info.py validate-modules:parameter-type-n plugins/modules/azure_rm_resourcegroup_info.py validate-modules:parameter-list-no-elements plugins/modules/azure_rm_resourcegroup_info.py validate-modules:required_if-requirements-unknown plugins/modules/azure_rm_resourcegroup_info.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationassignment.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationassignment.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationassignment.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/azure_rm_registrationassignment_info.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationassignment_info.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationdefinition.py validate-modules:doc-elements-mismatch +plugins/modules/azure_rm_registrationdefinition.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/azure_rm_registrationdefinition.py validate-modules:required_if-unknown-key +plugins/modules/azure_rm_registrationdefinition.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationdefinition_info.py validate-modules:required_if-requirements-unknown +plugins/modules/azure_rm_registrationdefinition_info.py validate-modules:required_if-unknown-key plugins/modules/azure_rm_securitygroup.py validate-modules:doc-choices-do-not-match-spec plugins/modules/azure_rm_securitygroup.py validate-modules:doc-default-does-not-match-spec plugins/modules/azure_rm_securitygroup.py validate-modules:missing-suboption-docs diff --git a/tests/utils/ado/ado.sh b/tests/utils/ado/ado.sh index 7b9b2fcb1..f2f9c2498 100755 --- a/tests/utils/ado/ado.sh +++ b/tests/utils/ado/ado.sh @@ -122,6 +122,9 @@ AZURE_SECRET:${AZURE_SECRET} AZURE_SUBSCRIPTION_ID:${AZURE_SUBSCRIPTION_ID} AZURE_TENANT:${AZURE_TENANT} RESOURCE_GROUP:${RESOURCE_GROUP} +AZURE_PRINCIPAL_ID:${AZURE_PRINCIPAL_ID} +AZURE_MANAGED_BY_TENANT_ID:${AZURE_MANAGED_BY_TENANT_ID} +AZURE_ROLE_DEFINITION_ID:${AZURE_ROLE_DEFINITION_ID} RESOURCE_GROUP_SECONDARY:${RESOURCE_GROUP_SECONDARY} EOF From 6af9185261aa91ac0e20f78a31a2001f44c86f94 Mon Sep 17 00:00:00 2001 From: Fred-sun Date: Fri, 11 Dec 2020 18:52:04 +0800 Subject: [PATCH 2/8] Adjust the parameters of the module --- .../modules/azure_rm_registrationassignment.py | 6 +++--- .../modules/azure_rm_registrationdefinition.py | 16 ++++------------ .../azure_rm_registrationdefinition_info.py | 17 ++++------------- .../tasks/main.yml | 5 +---- .../tasks/main.yml | 8 +------- 5 files changed, 13 insertions(+), 39 deletions(-) diff --git a/plugins/modules/azure_rm_registrationassignment.py b/plugins/modules/azure_rm_registrationassignment.py index f8bd14321..f60cd57ed 100644 --- a/plugins/modules/azure_rm_registrationassignment.py +++ b/plugins/modules/azure_rm_registrationassignment.py @@ -23,12 +23,13 @@ options: scope: description: - - Scope of the registration assignment.. + - Scope of the registration assignment. Can be in subscription or group level. required: true type: str registration_assignment_id: description: - ID of the registration assignment. + - If is not specified, an UUID will be generated for it. type: str properties: description: @@ -73,10 +74,9 @@ registration_definition_id: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationDefinitions/xxx-xxx - - name: Create Registration Assignment in resourcegroup level + - name: Create Registration Assignment in resourcegroup level with randomly generating registration_assignment_id azure_rm_registrationassignment: scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup - registration_assignment_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx properties: registration_definition_id: /subscriptions/xxx-xxx/providers/Microsoft.ManagedServices/registrationDefinitions/xxx-xxx diff --git a/plugins/modules/azure_rm_registrationdefinition.py b/plugins/modules/azure_rm_registrationdefinition.py index 05bfc476f..74d1276a6 100644 --- a/plugins/modules/azure_rm_registrationdefinition.py +++ b/plugins/modules/azure_rm_registrationdefinition.py @@ -21,14 +21,10 @@ description: - Create, update and delete instance of Azure RegistrationDefinition. options: - scope: - description: - - Scope of the resource. - required: true - type: str registration_definition_id: description: - - Guid of the registration definition. + - ID of the registration definition. + - If is not specified, an UUID will be generated for it. type: str properties: description: @@ -112,13 +108,11 @@ - name: Delete Registration Definition azure_rm_registrationdefinition: registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx state: absent - name: Create Registration Definition azure_rm_registrationdefinition: registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - scope: subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx properties: description: test authorizations: @@ -249,10 +243,6 @@ class Actions: class AzureRMRegistrationDefinition(AzureRMModuleBaseExt): def __init__(self): self.module_arg_spec = dict( - scope=dict( - type='str', - required=True - ), registration_definition_id=dict( type='str', ), @@ -351,6 +341,8 @@ def exec_module(self, **kwargs): if self.registration_definition_id is None: self.registration_definition_id = str(uuid.uuid4()) + self.scope = "/subscriptions/" + self.subscription_id + old_response = None response = None diff --git a/plugins/modules/azure_rm_registrationdefinition_info.py b/plugins/modules/azure_rm_registrationdefinition_info.py index c0939b1ba..185592fea 100644 --- a/plugins/modules/azure_rm_registrationdefinition_info.py +++ b/plugins/modules/azure_rm_registrationdefinition_info.py @@ -21,14 +21,9 @@ description: - Get info of RegistrationDefinition. options: - scope: - description: - - Scope of the resource. - required: true - type: str registration_definition_id: description: - - Guid of the registration definition. + - ID of the registration definition. type: str extends_documentation_fragment: - azure.azcollection.azure @@ -41,11 +36,9 @@ - name: Get Registration Definition azure_rm_registrationdefinition_info: registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - scope: subscription/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - - name: Get Registration Definitions + - name: Get All Registration Definitions in subscription level azure_rm_registrationdefinition_info: - scope: subscription/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ''' @@ -164,10 +157,6 @@ class AzureRMRegistrationDefinitionInfo(AzureRMModuleBase): def __init__(self): self.module_arg_spec = dict( - scope=dict( - type='str', - required=True - ), registration_definition_id=dict( type='str' ) @@ -190,6 +179,8 @@ def exec_module(self, **kwargs): for key in self.module_arg_spec: setattr(self, key, kwargs[key]) + self.scope = "/subscriptions/" + self.subscription_id + self.mgmt_client = self.get_mgmt_svc_client(ManagedServicesClient, base_url=self._cloud_environment.endpoints.resource_manager, api_version='2019-09-01', diff --git a/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml index ad3a2a7b6..034854a1c 100644 --- a/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml +++ b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml @@ -1,4 +1,4 @@ -- name: set guid for registration assignment id +- name: set facts set_fact: subscription_id: "{{ azure_subscription_id }}" managed_by_tenant_id: "{{ azure_managed_by_tenant_id }}" @@ -35,7 +35,6 @@ scope: subscriptions/{{ subscription_id }} properties: registration_definition_id: "{{ def_output.state.id }}" - expand_registration_definition: true register: ass_output - assert: @@ -48,7 +47,6 @@ registration_assignment_id: "{{ ass_output.state.name }}" properties: registration_definition_id: "{{ def_output.state.id }}" - expand_registration_definition: true register: output - assert: @@ -59,7 +57,6 @@ azure_rm_registrationassignment_info: scope: subscriptions/{{ subscription_id }} registration_assignment_id: "{{ ass_output.state.name }}" - expand_registration_definition: true register: output - assert: diff --git a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml index 4d42a8a8e..5ca25e73e 100644 --- a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml +++ b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml @@ -1,4 +1,4 @@ -- name: set guid for registration definition id +- name: set facts set_fact: subscription_id: "{{ azure_subscription_id }}" managed_by_tenant_id: "{{ azure_managed_by_tenant_id }}" @@ -9,7 +9,6 @@ - name: Create a RegistrationDefinition -- check mode azure_rm_registrationdefinition: - scope: subscriptions/{{ subscription_id }} properties: description: first_test authorizations: @@ -27,7 +26,6 @@ - name: Create a RegistrationDefinition azure_rm_registrationdefinition: - scope: subscriptions/{{ subscription_id }} properties: description: first_test authorizations: @@ -46,7 +44,6 @@ - name: Create a RegistrationDefinition (idempotent) azure_rm_registrationdefinition: registration_definition_id: "{{ def_output.state.name }}" - scope: subscriptions/{{ subscription_id }} properties: description: first_test authorizations: @@ -64,7 +61,6 @@ - name: Update the RegistrationDefinition properties description and name azure_rm_registrationdefinition: registration_definition_id: "{{ def_output.state.name }}" - scope: subscriptions/{{ subscription_id }} properties: description: second_test authorizations: @@ -82,7 +78,6 @@ - name: Get the Registration Definition info azure_rm_registrationdefinition_info: registration_definition_id: "{{ def_output.state.name }}" - scope: subscriptions/{{ subscription_id }} register: output - name: Assert the registration definition info @@ -98,7 +93,6 @@ - name: Delete the registration definition azure_rm_registrationdefinition: registration_definition_id: "{{ def_output.state.name }}" - scope: subscriptions/{{ subscription_id }} state: absent register: output From 44c8b2998c3d31b3462f2edad8069c5d1f035d59 Mon Sep 17 00:00:00 2001 From: Fred-sun Date: Fri, 11 Dec 2020 19:05:56 +0800 Subject: [PATCH 3/8] fix test playbook --- .../targets/azure_rm_registrationassignment/tasks/main.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml index 034854a1c..147cd4de7 100644 --- a/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml +++ b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml @@ -8,7 +8,6 @@ - name: Create a RegistrationDefinition azure_rm_registrationdefinition: - scope: subscriptions/{{ subscription_id }} properties: description: first_test authorizations: @@ -68,9 +67,3 @@ scope: subscriptions/{{ subscription_id }} registration_assignment_id: "{{ ass_output.state.name }}" state: absent - -#- name: Delete the registration definition -# azure_rm_registrationdefinition: -# registration_definition_id: "{{ def_output.state.name }}" -# scope: subscriptions//{{ subscription_id }} -# state: absent From 3563921920aedf24a79d49994890d8d909914e25 Mon Sep 17 00:00:00 2001 From: Fred-sun Date: Fri, 11 Dec 2020 19:28:36 +0800 Subject: [PATCH 4/8] Add test case --- plugins/modules/azure_rm_registrationdefinition_info.py | 4 ++-- .../azure_rm_registrationassignment/tasks/main.yml | 9 +++++++++ .../azure_rm_registrationdefinition/tasks/main.yml | 9 +++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/plugins/modules/azure_rm_registrationdefinition_info.py b/plugins/modules/azure_rm_registrationdefinition_info.py index 185592fea..26c848be0 100644 --- a/plugins/modules/azure_rm_registrationdefinition_info.py +++ b/plugins/modules/azure_rm_registrationdefinition_info.py @@ -186,9 +186,9 @@ def exec_module(self, **kwargs): api_version='2019-09-01', suppress_subscription_id=True) - if (self.scope is not None and self.registration_definition_id is not None): + if self.registration_definition_id is not None: self.results['registration_definitions'] = self.format_item(self.get()) - elif (self.scope is not None): + else: self.results['registration_definitions'] = self.format_item(self.list()) return self.results diff --git a/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml index 147cd4de7..b2f16f6c7 100644 --- a/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml +++ b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml @@ -62,6 +62,15 @@ that: - output.registration_assignments[0].properties.registration_definition_id == "{{ def_output.state.id }}" +- name: Get all RegistrationAssignment + azure_rm_registrationassignment_info: + scope: subscriptions/{{ subscription_id }} + register: output + +- assert: + that: + - output.registration_assignments | length >= 1 + - name: Delete the RegistrationAssignment azure_rm_registrationassignment: scope: subscriptions/{{ subscription_id }} diff --git a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml index 5ca25e73e..6e8bf7dad 100644 --- a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml +++ b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml @@ -90,6 +90,15 @@ - output.registration_definitions[0].properties.description == "second_test" - output.registration_definitions[0].properties.registration_definition_name == "test_name02" +- name: Get All Registration Definition info in the subscription + azure_rm_registrationdefinition_info: + register: output + +- name: Assert all the registration definition info + assert: + that: + - output.registration_definitions | length >=1 + - name: Delete the registration definition azure_rm_registrationdefinition: registration_definition_id: "{{ def_output.state.name }}" From 048fe93a7a1d1029a18cacddf78f61a54de4aac2 Mon Sep 17 00:00:00 2001 From: Fred-sun Date: Mon, 14 Dec 2020 14:58:14 +0800 Subject: [PATCH 5/8] add new parameter scope for azure_rm_registrationdefinition --- .../azure_rm_registrationdefinition.py | 19 +++++++--- .../tasks/main.yml | 36 +++++++++++++++---- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/plugins/modules/azure_rm_registrationdefinition.py b/plugins/modules/azure_rm_registrationdefinition.py index 74d1276a6..8e0d9213a 100644 --- a/plugins/modules/azure_rm_registrationdefinition.py +++ b/plugins/modules/azure_rm_registrationdefinition.py @@ -26,6 +26,11 @@ - ID of the registration definition. - If is not specified, an UUID will be generated for it. type: str + scope: + description: + - The subscription ID defines the subscription in which the registration definition will be created. + - If not specified, will use the subscription derived from AzureRMAuth. + type: str properties: description: - Properties of a registration definition. @@ -37,13 +42,13 @@ type: str authorizations: description: - - Authorization tuple containing principal id of the user/security group or service principal and id of the build-in role. + - Authorization tuple containing principal ID of the user/security group or service principal and ID of the build-in role. required: true type: list suboptions: principal_id: description: - - Principal Id of the security group/service principal/user that would be assigned permissions to the projected subscription + - Principal ID of the security group/service principal/user that would be assigned permissions to the projected subscription. required: true type: str role_definition_id: @@ -59,7 +64,7 @@ type: str managed_by_tenant_id: description: - - Id of the managedBy tenant. + - ID of the managedBy tenant. required: true type: str plan: @@ -243,6 +248,9 @@ class Actions: class AzureRMRegistrationDefinition(AzureRMModuleBaseExt): def __init__(self): self.module_arg_spec = dict( + scope=dict( + type='str' + ), registration_definition_id=dict( type='str', ), @@ -341,7 +349,10 @@ def exec_module(self, **kwargs): if self.registration_definition_id is None: self.registration_definition_id = str(uuid.uuid4()) - self.scope = "/subscriptions/" + self.subscription_id + if not self.scope: + self.scope = "/subscriptions/" + self.subscription_id + else: + self.scope = "/subscriptions/" + self.scope old_response = None response = None diff --git a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml index 6e8bf7dad..1274d0bf6 100644 --- a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml +++ b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml @@ -1,6 +1,7 @@ - name: set facts set_fact: subscription_id: "{{ azure_subscription_id }}" + subscription_sec_id: "{{ azure_subscription_sec_id }}" managed_by_tenant_id: "{{ azure_managed_by_tenant_id }}" principal_id: "{{ azure_principal_id }}" role_definition_id: "{{ azure_role_definition_id }}" @@ -24,6 +25,23 @@ that: - output.changed +- name: Create a RegistrationDefinition with scope + azure_rm_registrationdefinition: + scope: "{{ subscription_sec_id }}" + properties: + description: test definition with scope + authorizations: + - principal_id: "{{ principal_id }}" + role_definition_id: "{{ role_definition_id }}" + managed_by_tenant_id: "{{ managed_by_tenant_id }}" + registration_definition_name: "{{ reg_def_name }}" + register: output2 + +- name: Assert creating registration definition + assert: + that: + - output2.changed + - name: Create a RegistrationDefinition azure_rm_registrationdefinition: properties: @@ -33,17 +51,16 @@ role_definition_id: "{{ role_definition_id }}" managed_by_tenant_id: "{{ managed_by_tenant_id }}" registration_definition_name: "{{ reg_def_name }}" - register: def_output - tags: fred + register: output1 - name: Assert creating registration definition assert: that: - - output.changed + - output1.changed - name: Create a RegistrationDefinition (idempotent) azure_rm_registrationdefinition: - registration_definition_id: "{{ def_output.state.name }}" + registration_definition_id: "{{ output1.state.name }}" properties: description: first_test authorizations: @@ -77,13 +94,13 @@ - name: Get the Registration Definition info azure_rm_registrationdefinition_info: - registration_definition_id: "{{ def_output.state.name }}" + registration_definition_id: "{{ output1.state.name }}" register: output - name: Assert the registration definition info assert: that: - - output.registration_definitions[0].name == "{{ def_output.state.name }}" + - output.registration_definitions[0].name == "{{ output1.state.name }}" - output.registration_definitions[0].properties.authorizations[0].principal_id == "{{ principal_id }}" - output.registration_definitions[0].properties.authorizations[0].role_definition_id == "{{ role_definition_id }}" - output.registration_definitions[0].properties.provisioning_state == "Succeeded" @@ -101,7 +118,7 @@ - name: Delete the registration definition azure_rm_registrationdefinition: - registration_definition_id: "{{ def_output.state.name }}" + registration_definition_id: "{{ output1.state.name }}" state: absent register: output @@ -109,3 +126,8 @@ assert: that: - output.changed + +- name: Delete the registration definition + azure_rm_registrationdefinition: + registration_definition_id: "{{ output2.state.name }}" + state: absent From 32c795611601c74d3bb61073eb5cf5121e433a28 Mon Sep 17 00:00:00 2001 From: Fred-sun Date: Mon, 14 Dec 2020 16:39:09 +0800 Subject: [PATCH 6/8] add new parameter scope for azure_rm_registrationdefinition_info --- .../azure_rm_registrationdefinition_info.py | 19 +++++++++++++++++-- pr-pipelines.yml | 1 + .../tasks/main.yml | 1 + tests/utils/ado/ado.sh | 1 + 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/plugins/modules/azure_rm_registrationdefinition_info.py b/plugins/modules/azure_rm_registrationdefinition_info.py index 26c848be0..53a62315e 100644 --- a/plugins/modules/azure_rm_registrationdefinition_info.py +++ b/plugins/modules/azure_rm_registrationdefinition_info.py @@ -21,6 +21,11 @@ description: - Get info of RegistrationDefinition. options: + scope: + description: + - The subscription ID defines the subscription in which the registration definition will be got. + - If not specified, will use the subscription derived from AzureRMAuth. + type: str registration_definition_id: description: - ID of the registration definition. @@ -37,8 +42,12 @@ azure_rm_registrationdefinition_info: registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - - name: Get All Registration Definitions in subscription level + - name: Get All Registration Definitions from AzureRMAuth's subscription + azure_rm_registrationdefinition_info: + + - name: Get All Registration Definitions in the subscription levle azure_rm_registrationdefinition_info: + scope: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ''' @@ -157,6 +166,9 @@ class AzureRMRegistrationDefinitionInfo(AzureRMModuleBase): def __init__(self): self.module_arg_spec = dict( + scope=dict( + type='str' + ), registration_definition_id=dict( type='str' ) @@ -179,7 +191,10 @@ def exec_module(self, **kwargs): for key in self.module_arg_spec: setattr(self, key, kwargs[key]) - self.scope = "/subscriptions/" + self.subscription_id + if not self.scope: + self.scope = "/subscriptions/" + self.subscription_id + else: + self.scope = "/subscriptions/" + self.scope self.mgmt_client = self.get_mgmt_svc_client(ManagedServicesClient, base_url=self._cloud_environment.endpoints.resource_manager, diff --git a/pr-pipelines.yml b/pr-pipelines.yml index a16391454..54cd96263 100644 --- a/pr-pipelines.yml +++ b/pr-pipelines.yml @@ -175,6 +175,7 @@ jobs: AZURE_CLIENT_ID: $(AZURE_CLIENT_ID) AZURE_SECRET: $(AZURE_SECRET) AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID) + AZURE_SUBSCRIPTION_SEC_ID: $(AZURE_SUBSCRIPTION_SEC_ID) AZURE_TENANT: $(AZURE_TENANT) AZURE_PRINCIPAL_ID: $(AZURE_PRINCIPAL_ID) AZURE_MANAGED_BY_TENANT_ID: $(AZURE_MANAGED_BY_TENANT_ID) diff --git a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml index 1274d0bf6..522eace10 100644 --- a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml +++ b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml @@ -109,6 +109,7 @@ - name: Get All Registration Definition info in the subscription azure_rm_registrationdefinition_info: + scope: "{{ subscription_id }}" register: output - name: Assert all the registration definition info diff --git a/tests/utils/ado/ado.sh b/tests/utils/ado/ado.sh index f2f9c2498..9638318fd 100755 --- a/tests/utils/ado/ado.sh +++ b/tests/utils/ado/ado.sh @@ -120,6 +120,7 @@ cat <> "${TEST_DIR}"/tests/integration/cloud-config-azure.ini AZURE_CLIENT_ID:${AZURE_CLIENT_ID} AZURE_SECRET:${AZURE_SECRET} AZURE_SUBSCRIPTION_ID:${AZURE_SUBSCRIPTION_ID} +AZURE_SUBSCRIPTION_SEC_ID:${AZURE_SUBSCRIPTION_SEC_ID} AZURE_TENANT:${AZURE_TENANT} RESOURCE_GROUP:${RESOURCE_GROUP} AZURE_PRINCIPAL_ID:${AZURE_PRINCIPAL_ID} From 420cbb048708d9255745b4728892c4933e21e977 Mon Sep 17 00:00:00 2001 From: Fred-sun Date: Mon, 14 Dec 2020 16:54:20 +0800 Subject: [PATCH 7/8] fix sanity error --- .../targets/azure_rm_registrationdefinition/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml index 522eace10..2e95f576e 100644 --- a/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml +++ b/tests/integration/targets/azure_rm_registrationdefinition/tasks/main.yml @@ -77,7 +77,7 @@ - name: Update the RegistrationDefinition properties description and name azure_rm_registrationdefinition: - registration_definition_id: "{{ def_output.state.name }}" + registration_definition_id: "{{ output1.state.name }}" properties: description: second_test authorizations: From f3809ed876f90ce85307c83975b8f803fe2f33b1 Mon Sep 17 00:00:00 2001 From: Fred-sun Date: Tue, 15 Dec 2020 11:28:11 +0800 Subject: [PATCH 8/8] Adjust the test sequence --- .../azure_rm_registrationdefinition.py | 20 +++++++++++++++---- .../azure_rm_registrationdefinition_info.py | 2 +- .../tasks/main.yml | 20 +++++++++---------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/plugins/modules/azure_rm_registrationdefinition.py b/plugins/modules/azure_rm_registrationdefinition.py index 8e0d9213a..f6dc37134 100644 --- a/plugins/modules/azure_rm_registrationdefinition.py +++ b/plugins/modules/azure_rm_registrationdefinition.py @@ -110,13 +110,20 @@ ''' EXAMPLES = ''' - - name: Delete Registration Definition + - name: Create Registration Definition without scope azure_rm_registrationdefinition: registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - state: absent + properties: + description: test + authorizations: + - principal_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + role_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + managed_by_tenant_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + registration_definition_name: def4 - - name: Create Registration Definition + - name: Create Registration Definition with scope azure_rm_registrationdefinition: + scope: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx properties: description: test @@ -124,7 +131,12 @@ - principal_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx role_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx managed_by_tenant_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - registration_definition_name: def4 + registration_definition_name: def5 + + - name: Delete Registration Definition + azure_rm_registrationdefinition: + registration_definition_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + state: absent ''' diff --git a/plugins/modules/azure_rm_registrationdefinition_info.py b/plugins/modules/azure_rm_registrationdefinition_info.py index 53a62315e..616b1c562 100644 --- a/plugins/modules/azure_rm_registrationdefinition_info.py +++ b/plugins/modules/azure_rm_registrationdefinition_info.py @@ -23,7 +23,7 @@ options: scope: description: - - The subscription ID defines the subscription in which the registration definition will be got. + - The subscription ID defines the subscription in which the registration definition will be retrieved. - If not specified, will use the subscription derived from AzureRMAuth. type: str registration_definition_id: diff --git a/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml index b2f16f6c7..055524705 100644 --- a/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml +++ b/tests/integration/targets/azure_rm_registrationassignment/tasks/main.yml @@ -15,13 +15,13 @@ role_definition_id: "{{ role_definition_id }}" managed_by_tenant_id: "{{ managed_by_tenant_id }}" registration_definition_name: test_def - register: def_output + register: output1 - name: Create a RegistrationAssignment ---check mode azure_rm_registrationassignment: scope: subscriptions/{{ subscription_id }} properties: - registration_definition_id: "{{ def_output.state.id }}" + registration_definition_id: "{{ output1.state.id }}" register: output check_mode: yes @@ -33,19 +33,19 @@ azure_rm_registrationassignment: scope: subscriptions/{{ subscription_id }} properties: - registration_definition_id: "{{ def_output.state.id }}" - register: ass_output + registration_definition_id: "{{ output1.state.id }}" + register: output2 - assert: that: - - ass_output.changed + - output2.changed - name: Create a RegistrationAssignment -- idempotent azure_rm_registrationassignment: scope: subscriptions/{{ subscription_id }} - registration_assignment_id: "{{ ass_output.state.name }}" + registration_assignment_id: "{{ output2.state.name }}" properties: - registration_definition_id: "{{ def_output.state.id }}" + registration_definition_id: "{{ output1.state.id }}" register: output - assert: @@ -55,12 +55,12 @@ - name: Get a RegistrationAssignment azure_rm_registrationassignment_info: scope: subscriptions/{{ subscription_id }} - registration_assignment_id: "{{ ass_output.state.name }}" + registration_assignment_id: "{{ output2.state.name }}" register: output - assert: that: - - output.registration_assignments[0].properties.registration_definition_id == "{{ def_output.state.id }}" + - output.registration_assignments[0].properties.registration_definition_id == "{{ output1.state.id }}" - name: Get all RegistrationAssignment azure_rm_registrationassignment_info: @@ -74,5 +74,5 @@ - name: Delete the RegistrationAssignment azure_rm_registrationassignment: scope: subscriptions/{{ subscription_id }} - registration_assignment_id: "{{ ass_output.state.name }}" + registration_assignment_id: "{{ output2.state.name }}" state: absent