Repository: ansible/ansible

Issue:
azure_rm_resourcegroup idempotency broke when specifying location
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
<!---
Insert below this comment the name of the module, plugin, task or feature.
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path
-->
azure_rm_resourcegroup

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.5.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/tijmen/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
`
DEFAULT_ROLES_PATH(env: ANSIBLE_ROLES_PATH) = [u'/home/tijmen/ansible/roles']
`
##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
`
Ansible control node: "16.04.4 LTS (Xenial Xerus)"
Trying to create/update resource_group in Azure
`
##### SUMMARY
<!--- Explain the problem briefly -->
When running the below task it will create the resource group. However, when you run it again it will fail because the location will now be "westeurope". 

```yaml
- name: Create a resource group
  azure_rm_resourcegroup:
    name: SomeResourceGroup
    location: "West Europe"
    state: present
```
Failure message:

```
TASK [azure-vm : Create a resource group] ***********************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Resource group 'SomeResourceGroup' already exists in location 'westeurope' and cannot be moved."}
```

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: Create a resource group
  azure_rm_resourcegroup:
    name: SomeResourceGroup
    location: "West Europe"
    state: present
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->

I'd expect that if "West Europe" is a valid value for creating a resource group in West Europe idempotence will not break. 

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
The playbook fails

<!--- Paste verbatim command output between quotes below -->
```
TASK [azure-vm : Create a resource group] ***********************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Resource group 'SomeResourceGroup' already exists in location 'westeurope' and cannot be moved."}
```



Discussion:
Files identified in the description:
* [lib/ansible/modules/cloud/azure/azure_rm_resourcegroup.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/azure/azure_rm_resourcegroup.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @haroldwongms @nitzmahone @trstringer @xscript @yuwzho @zikalino
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Thanks for your reporting, I add it to my backlog and will look into this issue in May. Seems this is caused by the conditional check, I guess it can get the abbr and full name of location via API result and then make the comparison.

https://github.com/ansible/ansible/blob/1d972f519ce26bd26c60adfa4d8324b93d1ff93a/lib/ansible/modules/cloud/azure/azure_rm_resourcegroup.py#L165-L167

+label easyfix

I add easyfix label to see if somebody is interested in fixing this issue.

Resolving patch:
diff --git a/lib/ansible/module_utils/azure_rm_common.py b/lib/ansible/module_utils/azure_rm_common.py
--- a/lib/ansible/module_utils/azure_rm_common.py
+++ b/lib/ansible/module_utils/azure_rm_common.py
@@ -176,6 +176,11 @@ def format_resource_id(val, subscription_id, namespace, types, resource_group):
                        type=types,
                        subscription=subscription_id) if not is_valid_resource_id(val) else val
 
+
+def normalize_location_name(name):
+    return name.replace(' ', '').lower()
+
+
 # FUTURE: either get this from the requirements file (if we can be sure it's always available at runtime)
 # or generate the requirements files from this so we only have one source of truth to maintain...
 AZURE_PKG_VERSIONS = {
diff --git a/lib/ansible/modules/cloud/azure/azure_rm_resourcegroup.py b/lib/ansible/modules/cloud/azure/azure_rm_resourcegroup.py
--- a/lib/ansible/modules/cloud/azure/azure_rm_resourcegroup.py
+++ b/lib/ansible/modules/cloud/azure/azure_rm_resourcegroup.py
@@ -96,7 +96,7 @@
 except ImportError:
     pass
 
-from ansible.module_utils.azure_rm_common import AzureRMModuleBase
+from ansible.module_utils.azure_rm_common import AzureRMModuleBase, normalize_location_name
 
 
 def resource_group_to_dict(rg):
@@ -162,7 +162,7 @@ def exec_module(self, **kwargs):
                 if update_tags:
                     changed = True
 
-                if self.location and self.location != results['location']:
+                if self.location and normalize_location_name(self.location) != results['location']:
                     self.fail("Resource group '{0}' already exists in location '{1}' and cannot be "
                               "moved.".format(self.name, results['location']))
         except CloudError:


Test patch: