# Buggy code
def update_account(self):
    self.log("Update storage account {0}".format(self.name))
    if self.account_type:
        if self.account_type != self.account_dict["sku_name"]:
            # change the account type
            if self.account_dict["sku_name"] in [
                SkuName.premium_lrs,
                SkuName.standard_zrs,
            ]:
                self.fail(
                    "Storage accounts of type {0} and {1} cannot be changed.".format(
                        SkuName.premium_lrs, SkuName.standard_zrs
                    )
                )
            if self.account_type in [SkuName.premium_lrs, SkuName.standard_zrs]:
                self.fail(
                    "Storage account of type {0} cannot be changed to a type of {1} or {2}.".format(
                        self.account_dict["sku_name"],
                        SkuName.premium_lrs,
                        SkuName.standard_zrs,
                    )
                )

            self.results["changed"] = True
            self.account_dict["sku_name"] = self.account_type

            if self.results["changed"] and not self.check_mode:
                # Perform the update. The API only allows changing one attribute per call.
                try:
                    self.log("sku_name: %s" % self.account_dict["sku_name"])
                    self.log("sku_tier: %s" % self.account_dict["sku_tier"])
                    sku = Sku(SkuName(self.account_dict["sku_name"]))
                    sku.tier = SkuTier(self.account_dict["sku_tier"])
                    parameters = StorageAccountUpdateParameters(sku=sku)
                    self.storage_client.storage_accounts.update(
                        self.resource_group, self.name, parameters
                    )
                except Exception as exc:
                    self.fail("Failed to update account type: {0}".format(str(exc)))

    if self.custom_domain:
        if (
            not self.account_dict["custom_domain"]
            or self.account_dict["custom_domain"] != self.account_dict["custom_domain"]
        ):
            self.results["changed"] = True
            self.account_dict["custom_domain"] = self.custom_domain

        if self.results["changed"] and not self.check_mode:
            new_domain = CustomDomain(
                name=self.custom_domain["name"],
                use_sub_domain=self.custom_domain["use_sub_domain"],
            )
            parameters = StorageAccountUpdateParameters(custom_domain=new_domain)
            try:
                self.storage_client.storage_accounts.update(
                    self.resource_group, self.name, parameters
                )
            except Exception as exc:
                self.fail("Failed to update custom domain: {0}".format(str(exc)))

    update_tags, self.account_dict["tags"] = self.update_tags(self.account_dict["tags"])
    if update_tags:
        self.results["changed"] = True
        if not self.check_mode:
            parameters = StorageAccountUpdateParameters(tags=self.account_dict["tags"])
            try:
                self.storage_client.storage_accounts.update(
                    self.resource_group, self.name, parameters
                )
            except Exception as exc:
                self.fail("Failed to update tags: {0}".format(str(exc)))


# Traceback (msrestazure.azure_exceptions.CloudError)
ansible-playbook 2.4.0
config file = /ansible/ansible.cfg
configured module search path = [u'/Users/####/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible
executable location = /usr/local/bin/ansible-playbook
python version = 2.7.13 (default, Apr 23 2017, 16:50:35) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
Using /ansible/ansible.cfg as config file
setting up inventory plugins
Parsed /ansible/inventory/aq3.sh inventory source with script plugin
Set default localhost to localhost
Parsed /ansible/inventory/localhost.hosts inventory source with ini plugin
Parsed /ansible/inventory/optional.sh inventory source with script plugin
[WARNING]: Found both group and host with same name: localhost

Loading callback plugin default of type stdout, v2.0 from /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/plugins/callback/__init__.pyc
Loading callback plugin unnamed of type old, v1.0 from /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/plugins/callback/__init__.pyc
___________________________
< PLAYBOOK: copy_images.yml >
---------------------------
\   ^__^
\  (oo)\_______
(__)\       )\/\
||----w |
||     ||

1 plays in copy_images.yml
__________________
< PLAY [localhost] >
------------------
\   ^__^
\  (oo)\_______
(__)\       )\/\
||----w |
||     ||

2017-06-20T22:18:21.655381 (delta: 0.05648)         elapsed: 0.05648 **********
===============================================================================
META: ran handlers
____________________________________________________________
< TASK [Create resource group] >
------------------------------------------------------------
\   ^__^
\  (oo)\_______
(__)\       )\/\
||----w |
||     ||

task path: /ansible/copy_images.yml:21
2017-06-20T22:18:21.713703 (delta: 0.058203)         elapsed: 0.114802 ********
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/basic.py
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/azure_rm_common.py
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/_text.py
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/pycompat24.py
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/six/__init__.py
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/six/_six.py
Using module file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/modules/cloud/azure/azure_rm_resourcegroup.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: ####
<localhost> EXEC /bin/sh -c '/opt/local/bin/python &amp;&amp; sleep 0'
ok: [localhost] => {
"changed": false,
"contains_resources": true,
"failed": false,
"invocation": {
"module_args": {
"ad_user": null,
"append_tags": true,
"client_id": null,
"force": false,
"location": "southcentralus",
"name": "mygroup",
"password": null,
"profile": null,
"secret": null,
"state": "present",
"subscription_id": null,
"tags": null,
"tenant": null
}
},
"state": {
"id": "/subscriptions/###########################/resourceGroups/mygroup",
"location": "southcentralus",
"name": "mygroup",
"provisioning_state": "Succeeded",
"tags": {}
}
}
_________________________________________________
< TASK [Create standard lrs blob storage account] >
-------------------------------------------------
\   ^__^
\  (oo)\_______
(__)\       )\/\
||----w |
||     ||

task path: /ansible/copy_images.yml:30
2017-06-20T22:18:23.173263 (delta: 0.050252)         elapsed: 1.574362 ********
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/basic.py
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/azure_rm_common.py
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/_text.py
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/pycompat24.py
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/six/__init__.py
Using module_utils file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/module_utils/six/_six.py
Using module file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/modules/cloud/azure/azure_rm_storageaccount.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: ####
<localhost> EXEC /bin/sh -c '/opt/local/bin/python &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_module_azure_rm_storageaccount.py", line 447, in <module>
main()
File "/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_module_azure_rm_storageaccount.py", line 444, in main
AzureRMStorageAccount()
File "/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_module_azure_rm_storageaccount.py", line 205, in __init__
supports_check_mode=True)
File "/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_modlib.zip/ansible/module_utils/azure_rm_common.py", line 197, in __init__
File "/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_module_azure_rm_storageaccount.py", line 241, in exec_module
self.results['state'] = self.create_account()
File "/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_module_azure_rm_storageaccount.py", line 402, in create_account
self.get_poller_result(poller)
File "/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_modlib.zip/ansible/module_utils/azure_rm_common.py", line 411, in get_poller_result
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/msrestazure/azure_operation.py", line 486, in wait
raise self._exception
msrestazure.azure_exceptions.CloudError: Azure Error: InvalidAccessTier
Message: The storage account property 'accessTier' is invalid or cannot be set at this time.

fatal: [localhost]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_module_azure_rm_storageaccount.py\", line 447, in <module>\n    main()\n  File \"/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_module_azure_rm_storageaccount.py\", line 444, in main\n    AzureRMStorageAccount()\n  File \"/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_module_azure_rm_storageaccount.py\", line 205, in __init__\n    supports_check_mode=True)\n  File \"/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_modlib.zip/ansible/module_utils/azure_rm_common.py\", line 197, in __init__\n  File \"/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_module_azure_rm_storageaccount.py\", line 241, in exec_module\n    self.results['state'] = self.create_account()\n  File \"/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_module_azure_rm_storageaccount.py\", line 402, in create_account\n    self.get_poller_result(poller)\n  File \"/var/folders/mh/twpnm4s11q1d2mp23yx137t00000gp/T/ansible_vKyn6G/ansible_modlib.zip/ansible/module_utils/azure_rm_common.py\", line 411, in get_poller_result\n  File \"/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/msrestazure/azure_operation.py\", line 486, in wait\n    raise self._exception\nmsrestazure.azure_exceptions.CloudError: Azure Error: InvalidAccessTier\nMessage: The storage account property 'accessTier' is invalid or cannot be set at this time.\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 1
}
to retry, use: --limit @/ansible/copy_images.retry
____________
< PLAY RECAP >
------------
\   ^__^
\  (oo)\_______
(__)\       )\/\
||----w |
||     ||

localhost                  : ok=2    changed=0    unreachable=0    failed=1

2017-06-20T22:18:29.641144 (delta: 6.467837)         elapsed: 8.042243 ********
===============================================================================

# Fixed code
def update_account(self):
    self.log("Update storage account {0}".format(self.name))
    if self.account_type:
        if self.account_type != self.account_dict["sku_name"]:
            # change the account type
            if self.account_dict["sku_name"] in [
                SkuName.premium_lrs,
                SkuName.standard_zrs,
            ]:
                self.fail(
                    "Storage accounts of type {0} and {1} cannot be changed.".format(
                        SkuName.premium_lrs, SkuName.standard_zrs
                    )
                )
            if self.account_type in [SkuName.premium_lrs, SkuName.standard_zrs]:
                self.fail(
                    "Storage account of type {0} cannot be changed to a type of {1} or {2}.".format(
                        self.account_dict["sku_name"],
                        SkuName.premium_lrs,
                        SkuName.standard_zrs,
                    )
                )

            self.results["changed"] = True
            self.account_dict["sku_name"] = self.account_type

            if self.results["changed"] and not self.check_mode:
                # Perform the update. The API only allows changing one attribute per call.
                try:
                    self.log("sku_name: %s" % self.account_dict["sku_name"])
                    self.log("sku_tier: %s" % self.account_dict["sku_tier"])
                    sku = Sku(SkuName(self.account_dict["sku_name"]))
                    sku.tier = SkuTier(self.account_dict["sku_tier"])
                    parameters = StorageAccountUpdateParameters(sku=sku)
                    self.storage_client.storage_accounts.update(
                        self.resource_group, self.name, parameters
                    )
                except Exception as exc:
                    self.fail("Failed to update account type: {0}".format(str(exc)))

    if self.custom_domain:
        if (
            not self.account_dict["custom_domain"]
            or self.account_dict["custom_domain"] != self.custom_domain
        ):
            self.results["changed"] = True
            self.account_dict["custom_domain"] = self.custom_domain

        if self.results["changed"] and not self.check_mode:
            new_domain = CustomDomain(
                name=self.custom_domain["name"],
                use_sub_domain=self.custom_domain["use_sub_domain"],
            )
            parameters = StorageAccountUpdateParameters(custom_domain=new_domain)
            try:
                self.storage_client.storage_accounts.update(
                    self.resource_group, self.name, parameters
                )
            except Exception as exc:
                self.fail("Failed to update custom domain: {0}".format(str(exc)))

    if self.access_tier:
        if (
            not self.account_dict["access_tier"]
            or self.account_dict["access_tier"] != self.access_tier
        ):
            self.results["changed"] = True
            self.account_dict["access_tier"] = self.access_tier

        if self.results["changed"] and not self.check_mode:
            parameters = StorageAccountUpdateParameters(access_tier=self.access_tier)
            try:
                self.storage_client.storage_accounts.update(
                    self.resource_group, self.name, parameters
                )
            except Exception as exc:
                self.fail("Failed to update access tier: {0}".format(str(exc)))

    update_tags, self.account_dict["tags"] = self.update_tags(self.account_dict["tags"])
    if update_tags:
        self.results["changed"] = True
        if not self.check_mode:
            parameters = StorageAccountUpdateParameters(tags=self.account_dict["tags"])
            try:
                self.storage_client.storage_accounts.update(
                    self.resource_group, self.name, parameters
                )
            except Exception as exc:
                self.fail("Failed to update tags: {0}".format(str(exc)))