# Buggy code
def upload(self):
    for root, dirs, files in os.walk(self.root_dir):
        for f in files:
            blob_name = self.join(self.file_prefix, root[len(self.root_dir) :], f)
            blob_name.strip("/")
            try:
                self.blob_service.create_blob_from_path(
                    self.container, blob_name, os.path.join(root, f)
                )
            except AzureHttpError as e:
                self.log.error(
                    "Error writing output. Confirm output storage URL is correct "
                    "and that 'Storage Blob Contributor' role is assigned. \n" + str(e)
                )

            self.log.debug("%s uploaded" % blob_name)


# Traceback (msrestazure.azure_exceptions.CloudError)
(cloud-custodian) ➜  cloud-custodian git:(master) ✗ custodian-cask run -s=. policies/policy.yml
Custodian Cask (cloudcustodian/c7n:latest)
Skipped image pull - Last checked 23 minutes ago.

2019-07-08 20:57:46,374: custodian.azure.session:INFO Creating session with Azure CLI Authentication
2019-07-08 20:57:46,374: custodian.azure.session:INFO Session using Subscription ID: <my sub id>
2019-07-08 20:57:46,505: custodian.cache:WARNING Could not save cache /home/custodian/.cache/cloud-custodian.cache err: [Errno 2] No such file or directory: '/home/custodian/.cache/cloud-custodian.cache'
2019-07-08 20:57:46,506: custodian.cache:INFO Generating Cache directory: /home/custodian/.cache.
2019-07-08 20:57:49,283: custodian.policy:INFO policy:delete-empty-resource-groups resource:azure.resourcegroup region: count:1 time:2.90
2019-07-08 20:57:49,290: custodian.resources.resourcegroup:INFO Removing resource group test1
2019-07-08 20:57:49,383: custodian.output:ERROR Error while executing policy
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/c7n/policy.py", line 261, in run
results = a.process(resources)
File "/usr/local/lib/python3.7/site-packages/c7n_azure/resources/resourcegroup.py", line 93, in process
self.manager.get_client().resource_groups.delete(group['name'])
File "/usr/local/lib/python3.7/site-packages/azure/mgmt/resource/resources/v2018_05_01/operations/resource_groups_operations.py", line 231, in delete
**operation_config
File "/usr/local/lib/python3.7/site-packages/azure/mgmt/resource/resources/v2018_05_01/operations/resource_groups_operations.py", line 199, in _delete_initial
raise exp
msrestazure.azure_exceptions.CloudError: Azure Error: ScopeLocked
Message: The scope '/subscriptions/<my sub id>/resourcegroups/test1' cannot perform delete operation because following scope(s) are locked: '/subscriptions/<my sub id>/resourceGroups/test1'. Please remove the lock and try again.
2019-07-08 20:57:49,384: custodian.commands:ERROR Error while executing policy delete-empty-resource-groups, continuing
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/c7n/commands.py", line 269, in run
policy()
File "/usr/local/lib/python3.7/site-packages/c7n/policy.py", line 945, in __call__
resources = mode.run()
File "/usr/local/lib/python3.7/site-packages/c7n/policy.py", line 261, in run
results = a.process(resources)
File "/usr/local/lib/python3.7/site-packages/c7n_azure/resources/resourcegroup.py", line 93, in process
self.manager.get_client().resource_groups.delete(group['name'])
File "/usr/local/lib/python3.7/site-packages/azure/mgmt/resource/resources/v2018_05_01/operations/resource_groups_operations.py", line 231, in delete
**operation_config
File "/usr/local/lib/python3.7/site-packages/azure/mgmt/resource/resources/v2018_05_01/operations/resource_groups_operations.py", line 199, in _delete_initial
raise exp
msrestazure.azure_exceptions.CloudError: Azure Error: ScopeLocked
Message: The scope '/subscriptions/<my sub id>/resourcegroups/test1' cannot perform delete operation because following scope(s) are locked: '/subscriptions/<my sub id>/resourceGroups/test1'. Please remove the lock and try again.

# Fixed code
def upload(self):
    for root, dirs, files in os.walk(self.root_dir):
        for f in files:
            blob_name = self.join(self.file_prefix, root[len(self.root_dir) :], f)
            blob_name.strip("/")
            try:
                self.blob_service.create_blob_from_path(
                    self.container, blob_name, os.path.join(root, f)
                )
            except AzureHttpError as e:
                if e.status_code == 403:
                    self.log.error(
                        "Access Error: Storage Blob Data Contributor Role "
                        "is required to write to Azure Blob Storage."
                    )
                else:
                    self.log.error(
                        "Error writing output. "
                        "Confirm output storage URL is correct. \n" + str(e)
                    )

            self.log.debug("%s uploaded" % blob_name)