From 2a8915e54f061ccd284ab9577f584be29ab85d3d Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Thu, 12 Aug 2021 02:53:20 -0500 Subject: [PATCH] New modules for webapp network access restrictions (#594) * add modules for webapp access restriction * whitespace * test coverage for webapp access restrictions * correct delete output * Apply suggestions from code review Co-authored-by: Fred-sun <37327967+Fred-sun@users.noreply.github.com> * rename module for collection consistency * correct documentation element types * correct import location and line lengths * add new module to build/test pipeline * correct typo * add tests for _info module; enhance asserts on main module tests * Apply suggestions from code review Co-authored-by: Fred-sun <37327967+Fred-sun@users.noreply.github.com> * Update version added based on code review * Update plugins/modules/azure_rm_webappaccessrestriction_info.py Co-authored-by: Fred-sun <37327967+Fred-sun@users.noreply.github.com> Co-authored-by: Fred-sun <37327967+Fred-sun@users.noreply.github.com> --- .../azure_rm_webappaccessrestriction.py | 377 ++++++++++++++++++ .../azure_rm_webappaccessrestriction_info.py | 196 +++++++++ pr-pipelines.yml | 3 +- .../azure_rm_webappaccessrestriction/aliases | 3 + .../meta/main.yml | 2 + .../tasks/main.yml | 286 +++++++++++++ 6 files changed, 866 insertions(+), 1 deletion(-) create mode 100644 plugins/modules/azure_rm_webappaccessrestriction.py create mode 100644 plugins/modules/azure_rm_webappaccessrestriction_info.py create mode 100644 tests/integration/targets/azure_rm_webappaccessrestriction/aliases create mode 100644 tests/integration/targets/azure_rm_webappaccessrestriction/meta/main.yml create mode 100644 tests/integration/targets/azure_rm_webappaccessrestriction/tasks/main.yml diff --git a/plugins/modules/azure_rm_webappaccessrestriction.py b/plugins/modules/azure_rm_webappaccessrestriction.py new file mode 100644 index 000000000..46007e899 --- /dev/null +++ b/plugins/modules/azure_rm_webappaccessrestriction.py @@ -0,0 +1,377 @@ +#!/usr/bin/python +# +# Copyright (c) 2021 Ross Bender (@l3ender) +# +# 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 + + +DOCUMENTATION = ''' +--- +module: azure_rm_webappaccessrestriction +version_added: "1.8.0" +short_description: Manage web app network access restrictions +description: + - Add, remove, or update network access restrictions for a web app. +options: + name: + description: + - Name of the web app. + required: true + type: str + resource_group: + description: + - Resource group of the web app. + required: true + type: str + state: + description: + - State of the access restrictions. Use C(present) to create or update and C(absent) to delete. + type: str + default: present + choices: + - absent + - present + ip_security_restrictions: + description: + - The web app's HTTP access restrictions. + type: list + elements: dict + suboptions: + name: + description: + - Name of the access restriction. + type: str + description: + description: + - Description of the access restriction. + type: str + action: + description: + - Traffic action for the access restriction. + type: str + default: Allow + choices: + - Allow + - Deny + priority: + description: + - Numerical priority of the access restriction. + type: int + required: true + ip_address: + description: + - IPv4 address (with subnet mask) of the access restriction. + type: str + required: true + scm_ip_security_restrictions: + description: + - >- + The web app's SCM access restrictions. If C(scm_ip_security_restrictions_use_main) is set to C(true), + the SCM restrictions will be configured but not used. + type: list + elements: dict + suboptions: + name: + description: + - Name of the access restriction. + type: str + description: + description: + - Description of the access restriction. + type: str + action: + description: + - Traffic action for the access restriction. + type: str + default: Allow + choices: + - Allow + - Deny + priority: + description: + - Numerical priority of the access restriction. + type: int + required: true + ip_address: + description: + - IPv4 address (with subnet mask) of the access restriction. + type: str + required: true + scm_ip_security_restrictions_use_main: + description: + - >- + Set to C(true) to have the HTTP access restrictions also apply to the SCM site. + If C(scm_ip_security_restrictions) are also applied, they will configured but not used. + default: false + type: bool + +extends_documentation_fragment: + - azure.azcollection.azure + +author: + - Ross Bender (@l3ender) +''' + +EXAMPLES = ''' + - name: Configure web app access restrictions. + azure.azcollection.azure_rm_webappaccessrestriction: + name: "MyWebapp" + resource_group: "MyResourceGroup" + ip_security_restrictions: + - name: "Datacenter 1" + action: "Allow" + ip_address: "1.1.1.1/24" + priority: 1 + - name: "Datacenter 2" + action: "Allow" + ip_address: "2.2.2.2/24" + priority: 2 + scm_ip_security_restrictions_use_main: true + + - name: Delete web app network access restrictions. + azure.azcollection.azure_rm_webappaccessrestriction: + name: "MyWebapp" + resource_group: "MyResourceGroup" + state: "absent" +''' + +RETURN = ''' +ip_security_restrictions: + description: + - The web app's HTTP access restrictions. + returned: always + type: list + elements: dict + contains: + name: + description: + - Name of the access restriction. + returned: always + type: str + sample: my-access-restriction + description: + description: + - Description of the access restriction. + returned: always + type: str + sample: my-access-restriction-description + action: + description: + - Traffic action of the access restriction. + returned: always + type: str + sample: Allow + priority: + description: + - Numerical priority of the access restriction. + returned: always + type: int + sample: 1 + ip_address: + description: + - IP address of the access restriction. + returned: always + type: str + sample: 1.1.1.1/32 +scm_ip_security_restrictions: + description: + - The web app's SCM access restrictions. + returned: always + type: list + elements: dict + contains: + name: + description: + - Name of the access restriction. + returned: always + type: str + sample: my-access-restriction + description: + description: + - Description of the access restriction. + returned: always + type: str + sample: my-access-restriction-description + action: + description: + - Traffic action of the access restriction. + returned: always + type: str + sample: Allow + priority: + description: + - Numerical priority of the access restriction. + returned: always + type: int + sample: 1 + ip_address: + description: + - IP address of the access restriction. + returned: always + type: str + sample: 1.1.1.1/32 +scm_ip_security_restrictions_use_main: + description: + - Whether the HTTP access restrictions are used for SCM access. + returned: always + type: bool + sample: false +''' + +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase + +try: + from azure.mgmt.web.models import IpSecurityRestriction +except Exception: + # This is handled in azure_rm_common + pass + +ip_restriction_spec = dict( + name=dict(type='str'), + description=dict(type='str'), + action=dict(type='str', default='Allow', choices=['Allow', 'Deny']), + priority=dict(type='int', required=True), + ip_address=dict(type='str', required=True), +) + + +class AzureRMWebAppAccessRestriction(AzureRMModuleBase): + + def __init__(self): + + self.module_arg_spec = dict( + name=dict(type='str', required=True), + resource_group=dict(type='str', required=True), + state=dict(type='str', default='present', choices=['present', 'absent']), + ip_security_restrictions=dict(type='list', default=[], elements='dict', options=ip_restriction_spec), + scm_ip_security_restrictions=dict(type='list', default=[], elements='dict', options=ip_restriction_spec), + scm_ip_security_restrictions_use_main=dict(type='bool', default=False), + ) + + self.results = dict( + changed=False, + ip_security_restrictions=[], + scm_ip_security_restrictions=[], + scm_ip_security_restrictions_use_main=False, + ) + + self.state = None + self.name = None + self.resource_group = None + self.ip_security_restrictions = [] + self.scm_ip_security_restrictions = [] + self.scm_ip_security_restrictions_use_main = False + + super(AzureRMWebAppAccessRestriction, self).__init__(self.module_arg_spec, + supports_check_mode=True, + supports_tags=False) + + def exec_module(self, **kwargs): + for key in self.module_arg_spec: + setattr(self, key, kwargs[key]) + + changed = False + site_config = self.get_webapp_config() + self.results.update(self.set_results(site_config)) + + if self.state == 'absent' and self.has_access_restrictions(site_config): + changed = True + if not self.check_mode: + self.log('Removing all access restrictions for webapp {0}'.format(self.name)) + site_config.ip_security_restrictions = [] + site_config.scm_ip_security_restrictions = [] + site_config.scm_ip_security_restrictions_use_main = False + self.update_webapp_config(site_config) + self.results['ip_security_restrictions'] = [] + self.results['scm_ip_security_restrictions'] = [] + self.results['scm_ip_security_restrictions_use_main'] = False + elif self.state == 'present': + if not self.has_access_restrictions(site_config) and (self.ip_security_restrictions or self.scm_ip_security_restrictions): + self.log('Adding new access restrictions for webapp {0}'.format(self.name)) + changed = True + elif self.has_updates(site_config): + self.log('Detected change in existing access restrictions for webapp {0}'.format(self.name)) + changed = True + + if changed: + site_config = self.get_updated_config(site_config) + if not self.check_mode: + self.log('Updating site config for webapp {0}'.format(self.name)) + site_config = self.update_webapp_config(site_config) + + self.results.update(self.set_results(site_config)) + + self.results['changed'] = changed + + return self.results + + def get_updated_config(self, site_config): + site_config.ip_security_restrictions = [] if not self.ip_security_restrictions else self.to_restriction_obj_list(self.ip_security_restrictions) + site_config.scm_ip_security_restrictions = [] if not self.scm_ip_security_restrictions else ( + self.to_restriction_obj_list(self.scm_ip_security_restrictions)) + site_config.scm_ip_security_restrictions_use_main = self.scm_ip_security_restrictions_use_main + return site_config + + def has_updates(self, site_config): + return (self.ip_security_restrictions != self.to_restriction_dict_list(site_config.ip_security_restrictions) + or self.scm_ip_security_restrictions != self.to_restriction_dict_list(site_config.scm_ip_security_restrictions) + or site_config.scm_ip_security_restrictions_use_main != self.scm_ip_security_restrictions_use_main) + + def has_access_restrictions(self, site_config): + return site_config.ip_security_restrictions or site_config.scm_ip_security_restrictions + + def get_webapp_config(self): + try: + return self.web_client.web_apps.get_configuration(resource_group_name=self.resource_group, name=self.name) + except Exception as exc: + self.fail("Error getting webapp config {0} (rg={1}) - {2}".format(self.name, self.resource_group, str(exc))) + + def update_webapp_config(self, param): + try: + return self.web_client.web_apps.create_or_update_configuration(resource_group_name=self.resource_group, name=self.name, site_config=param) + except Exception as exc: + self.fail("Error creating/updating webapp config {0} (rg={1}) - {2}".format(self.name, self.resource_group, str(exc))) + + def set_results(self, site_config): + output = dict() + if site_config.ip_security_restrictions: + output['ip_security_restrictions'] = self.to_restriction_dict_list(site_config.ip_security_restrictions) + if site_config.scm_ip_security_restrictions: + output['scm_ip_security_restrictions'] = self.to_restriction_dict_list(site_config.scm_ip_security_restrictions) + output['scm_ip_security_restrictions_use_main'] = site_config.scm_ip_security_restrictions_use_main + return output + + def to_restriction_obj_list(self, restriction_dict_list): + return [] if not restriction_dict_list else [self.to_restriction_obj(restriction) for restriction in restriction_dict_list] + + def to_restriction_obj(self, restriction_dict): + return IpSecurityRestriction( + name=restriction_dict['name'], + description=restriction_dict['description'], + action=restriction_dict['action'], + priority=restriction_dict['priority'], + ip_address=restriction_dict['ip_address'], + ) + + def to_restriction_dict_list(self, restriction_obj_list): + return [] if not restriction_obj_list else [self.to_restriction_dict(restriction) for restriction in restriction_obj_list] + + def to_restriction_dict(self, restriction_obj): + return dict( + name=restriction_obj.name, + description=restriction_obj.description, + action=restriction_obj.action, + priority=restriction_obj.priority, + ip_address=restriction_obj.ip_address, + ) + + +def main(): + AzureRMWebAppAccessRestriction() + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/azure_rm_webappaccessrestriction_info.py b/plugins/modules/azure_rm_webappaccessrestriction_info.py new file mode 100644 index 000000000..bdfa92b4a --- /dev/null +++ b/plugins/modules/azure_rm_webappaccessrestriction_info.py @@ -0,0 +1,196 @@ +#!/usr/bin/python +# +# Copyright (c) 2021 Ross Bender (@l3ender) +# +# 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 + + +DOCUMENTATION = ''' +--- +module: azure_rm_webappaccessrestriction_info +version_added: "1.8.0" +short_description: Retrieve web app network access restriction facts +description: + - Get facts for a web app's network access restrictions. +options: + name: + description: + - Name of the web app. + required: true + type: str + resource_group: + description: + - Resource group of the web app. + required: true + type: str + +extends_documentation_fragment: + - azure.azcollection.azure + +author: + - Ross Bender (@l3ender) +''' + +EXAMPLES = ''' + - name: View web app access restrictions. + azure.azcollection.azure_rm_webappaccessrestriction_info: + name: "MyWebapp" + resource_group: "MyResourceGroup" +''' + +RETURN = ''' +ip_security_restrictions: + description: + - The web app's HTTP access restrictions. + returned: always + type: list + elements: dict + contains: + name: + description: + - Name of the access restriction. + returned: always + type: str + sample: my-access-restriction + description: + description: + - Description of the access restriction. + returned: always + type: str + sample: my-access-restriction-description + action: + description: + - Traffic action of the access restriction. + returned: always + type: str + sample: Allow + priority: + description: + - Numerical priority of the access restriction. + returned: always + type: int + sample: 1 + ip_address: + description: + - IP address of the access restriction. + returned: always + type: str + sample: 1.1.1.1/32 +scm_ip_security_restrictions: + description: + - The web app's SCM access restrictions. + returned: always + type: list + elements: dict + contains: + name: + description: + - Name of the access restriction. + returned: always + type: str + sample: my-access-restriction + description: + description: + - Description of the access restriction. + returned: always + type: str + sample: my-access-restriction-description + action: + description: + - Traffic action of the access restriction. + returned: always + type: str + sample: Allow + priority: + description: + - Numerical priority of the access restriction. + returned: always + type: int + sample: 1 + ip_address: + description: + - IP address of the access restriction. + returned: always + type: str + sample: 1.1.1.1/32 +scm_ip_security_restrictions_use_main: + description: + - Whether the HTTP access restrictions are used for SCM access. + returned: always + type: bool + sample: false +''' + +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase + + +class AzureRMWebAppAccessRestrictionInfo(AzureRMModuleBase): + + def __init__(self): + + self.module_arg_spec = dict( + name=dict(type='str', required=True), + resource_group=dict(type='str', required=True), + ) + + self.results = dict( + changed=False, + ip_security_restrictions=[], + scm_ip_security_restrictions=[], + scm_ip_security_restrictions_use_main=False, + ) + + self.name = None + self.resource_group = None + + super(AzureRMWebAppAccessRestrictionInfo, self).__init__(self.module_arg_spec, + supports_check_mode=True, + supports_tags=False, + facts_module=True) + + def exec_module(self, **kwargs): + for key in self.module_arg_spec: + setattr(self, key, kwargs[key]) + + site_config = self.get_webapp_config() + self.results.update(self.set_results(site_config)) + + return self.results + + def get_webapp_config(self): + try: + return self.web_client.web_apps.get_configuration(resource_group_name=self.resource_group, name=self.name) + except Exception as exc: + self.fail("Error getting webapp config {0} (rg={1}) - {2}".format(self.name, self.resource_group, str(exc))) + + def set_results(self, site_config): + output = dict() + if site_config.ip_security_restrictions: + output['ip_security_restrictions'] = self.to_restriction_dict_list(site_config.ip_security_restrictions) + if site_config.scm_ip_security_restrictions: + output['scm_ip_security_restrictions'] = self.to_restriction_dict_list(site_config.scm_ip_security_restrictions) + output['scm_ip_security_restrictions_use_main'] = site_config.scm_ip_security_restrictions_use_main + return output + + def to_restriction_dict_list(self, restriction_obj_list): + return [] if not restriction_obj_list else [self.to_restriction_dict(restriction) for restriction in restriction_obj_list] + + def to_restriction_dict(self, restriction_obj): + return dict( + name=restriction_obj.name, + description=restriction_obj.description, + action=restriction_obj.action, + priority=restriction_obj.priority, + ip_address=restriction_obj.ip_address, + ) + + +def main(): + AzureRMWebAppAccessRestrictionInfo() + + +if __name__ == '__main__': + main() diff --git a/pr-pipelines.yml b/pr-pipelines.yml index 464bf0bd2..e04c32013 100644 --- a/pr-pipelines.yml +++ b/pr-pipelines.yml @@ -98,13 +98,14 @@ parameters: - "azure_rm_virtualmachinescaleset" - "azure_rm_virtualnetwork" - "azure_rm_virtualnetworkgateway" - - "azure_rm_virtualnetworkeepring" + - "azure_rm_virtualnetworkpeering" - "azure_rm_virtualwan" - "azure_rm_vpnsite" - "azure_rm_backupazurevm" - "azure_rm_recoveryservicesvault" - "azure_rm_vmbackuppolicy" - "azure_rm_webapp" + - "azure_rm_webappaccessrestriction" - "azure_rm_workspace" - "inventory_azure" - "setup_azure" diff --git a/tests/integration/targets/azure_rm_webappaccessrestriction/aliases b/tests/integration/targets/azure_rm_webappaccessrestriction/aliases new file mode 100644 index 000000000..759eafa2d --- /dev/null +++ b/tests/integration/targets/azure_rm_webappaccessrestriction/aliases @@ -0,0 +1,3 @@ +cloud/azure +shippable/azure/group3 +destructive diff --git a/tests/integration/targets/azure_rm_webappaccessrestriction/meta/main.yml b/tests/integration/targets/azure_rm_webappaccessrestriction/meta/main.yml new file mode 100644 index 000000000..95e1952f9 --- /dev/null +++ b/tests/integration/targets/azure_rm_webappaccessrestriction/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - setup_azure diff --git a/tests/integration/targets/azure_rm_webappaccessrestriction/tasks/main.yml b/tests/integration/targets/azure_rm_webappaccessrestriction/tasks/main.yml new file mode 100644 index 000000000..dcf05e334 --- /dev/null +++ b/tests/integration/targets/azure_rm_webappaccessrestriction/tasks/main.yml @@ -0,0 +1,286 @@ +- name: Prepare random number + set_fact: + rpfx: "{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}" + run_once: true + +- name: Create a web app + azure_rm_webapp: + resource_group: "{{ resource_group }}" + name: webapp{{ rpfx }} + plan: + resource_group: "{{ resource_group }}" + name: webappplan{{ rpfx }} + is_linux: false + sku: S1 + +- name: "Create webapp access restriction - check mode" + azure_rm_webappaccessrestriction: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + ip_security_restrictions: + - name: "Datacenter 1" + action: "Allow" + ip_address: "1.1.1.1/24" + priority: 1 + - name: "Datacenter 2" + action: "Allow" + ip_address: "2.2.2.2/24" + priority: 2 + scm_ip_security_restrictions_use_main: true + register: output + check_mode: true +- name: Assert the resource is well created + assert: + that: output.changed + +- name: "Check webapp access restriction facts 1" + azure_rm_webappaccessrestriction_info: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + register: output +- name: Assert no restrictions + assert: + that: + - not output.changed + - output.ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions_use_main == false + +- name: "Create webapp access restriction" + azure_rm_webappaccessrestriction: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + ip_security_restrictions: + - name: "Datacenter 1" + action: "Allow" + ip_address: "1.1.1.1/24" + priority: 1 + - name: "Datacenter 2" + action: "Allow" + ip_address: "2.2.2.2/24" + priority: 2 + scm_ip_security_restrictions_use_main: true + register: output +- name: Assert the resource is well created + assert: + that: + - output.changed + - output.ip_security_restrictions | length == 2 + - output.ip_security_restrictions[0].action == 'Allow' + - output.ip_security_restrictions[0].ip_address == '1.1.1.1/24' + - output.ip_security_restrictions[1].action == 'Allow' + - output.ip_security_restrictions[1].ip_address == '2.2.2.2/24' + - output.scm_ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions_use_main == true + +- name: "Check webapp access restriction facts 2" + azure_rm_webappaccessrestriction_info: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + register: output +- name: Assert restrictions + assert: + that: + - not output.changed + - output.ip_security_restrictions | length == 2 + - output.ip_security_restrictions[0].action == 'Allow' + - output.ip_security_restrictions[0].ip_address == '1.1.1.1/24' + - output.ip_security_restrictions[1].action == 'Allow' + - output.ip_security_restrictions[1].ip_address == '2.2.2.2/24' + - output.scm_ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions_use_main == true + +- name: "Create webapp access restriction - idempotent" + azure_rm_webappaccessrestriction: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + ip_security_restrictions: + - name: "Datacenter 1" + action: "Allow" + ip_address: "1.1.1.1/24" + priority: 1 + - name: "Datacenter 2" + action: "Allow" + ip_address: "2.2.2.2/24" + priority: 2 + scm_ip_security_restrictions_use_main: true + register: output +- name: Assert the resource is not changed + assert: + that: not output.changed + +- name: "Delete specific webapp access restriction" + azure_rm_webappaccessrestriction: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + ip_security_restrictions: + - name: "Datacenter 1" + action: "Allow" + ip_address: "1.1.1.1/24" + priority: 1 + scm_ip_security_restrictions_use_main: true + register: output +- name: Assert the resource is updated + assert: + that: + - output.changed + - output.ip_security_restrictions | length == 1 + - output.ip_security_restrictions[0].action == 'Allow' + - output.ip_security_restrictions[0].ip_address == '1.1.1.1/24' + - output.scm_ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions_use_main == true + +- name: "Update existing webapp access restriction 1" + azure_rm_webappaccessrestriction: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + ip_security_restrictions: + - name: "Datacenter 1" + action: "Deny" + ip_address: "1.2.3.4/24" + priority: 1 + scm_ip_security_restrictions_use_main: true + register: output +- name: Assert the resource is updated + assert: + that: + - output.changed + - output.ip_security_restrictions | length == 1 + - output.ip_security_restrictions[0].action == 'Deny' + - output.ip_security_restrictions[0].ip_address == '1.2.3.4/24' + - output.scm_ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions_use_main == true + +- name: "Update existing webapp access restriction 2" + azure_rm_webappaccessrestriction: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + ip_security_restrictions: + - name: "Datacenter 1" + action: "Deny" + ip_address: "1.2.3.4/24" + priority: 1 + scm_ip_security_restrictions_use_main: false + register: output +- name: Assert the resource is updated + assert: + that: + - output.changed + - output.ip_security_restrictions | length == 1 + - output.ip_security_restrictions[0].action == 'Deny' + - output.ip_security_restrictions[0].ip_address == '1.2.3.4/24' + - output.scm_ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions_use_main == false + +- name: "Update existing webapp access restriction 3" + azure_rm_webappaccessrestriction: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + ip_security_restrictions: + - name: "Datacenter 1" + action: "Deny" + ip_address: "1.2.3.4/24" + priority: 1 + scm_ip_security_restrictions: + - name: "Datacenter 1" + action: "Deny" + ip_address: "1.2.3.4/24" + priority: 1 + scm_ip_security_restrictions_use_main: false + register: output +- name: Assert the resource is updated + assert: + that: + - output.changed + - output.ip_security_restrictions | length == 1 + - output.ip_security_restrictions[0].action == 'Deny' + - output.ip_security_restrictions[0].ip_address == '1.2.3.4/24' + - output.scm_ip_security_restrictions | length == 1 + - output.ip_security_restrictions[0].action == 'Deny' + - output.ip_security_restrictions[0].ip_address == '1.2.3.4/24' + - output.scm_ip_security_restrictions_use_main == false + +- name: "Update existing webapp access restriction 4" + azure_rm_webappaccessrestriction: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + ip_security_restrictions: + - name: "Datacenter 1" + action: "Deny" + ip_address: "1.2.3.4/24" + priority: 1 + scm_ip_security_restrictions: + - name: "Datacenter 1" + action: "Deny" + ip_address: "1.2.3.4/24" + priority: 1 + - name: "Datacenter 2" + action: "Allow" + ip_address: "2.2.2.2/24" + priority: 2 + scm_ip_security_restrictions_use_main: false + register: output +- name: Assert the resource is updated + assert: + that: + - output.changed + - output.ip_security_restrictions | length == 1 + - output.ip_security_restrictions[0].action == 'Deny' + - output.ip_security_restrictions[0].ip_address == '1.2.3.4/24' + - output.scm_ip_security_restrictions | length == 2 + - output.scm_ip_security_restrictions[0].action == 'Deny' + - output.scm_ip_security_restrictions[0].ip_address == '1.2.3.4/24' + - output.scm_ip_security_restrictions[1].action == 'Allow' + - output.scm_ip_security_restrictions[1].ip_address == '2.2.2.2/24' + - output.scm_ip_security_restrictions_use_main == false + +- name: "Update existing webapp access restriction - idempotent" + azure_rm_webappaccessrestriction: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + ip_security_restrictions: + - name: "Datacenter 1" + action: "Deny" + ip_address: "1.2.3.4/24" + priority: 1 + scm_ip_security_restrictions: + - name: "Datacenter 1" + action: "Deny" + ip_address: "1.2.3.4/24" + priority: 1 + - name: "Datacenter 2" + action: "Allow" + ip_address: "2.2.2.2/24" + priority: 2 + scm_ip_security_restrictions_use_main: false + register: output +- name: Assert the resource is not changed + assert: + that: not output.changed + +- name: "Delete webapp access restrictions" + azure_rm_webappaccessrestriction: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + state: "absent" + register: output +- name: Assert the resource is deleted + assert: + that: + - output.changed + - output.ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions_use_main == false + +- name: "Check webapp access restriction facts 3" + azure_rm_webappaccessrestriction_info: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + register: output +- name: Assert no restrictions + assert: + that: + - not output.changed + - output.ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions | length == 0 + - output.scm_ip_security_restrictions_use_main == false