Repository: cloud-custodian/cloud-custodian

Issue:
Delete IAM User does not work
Creating a simple (lambda published) iam-user resource policy with the delete action causes DeleteConflict exception.

Sample policy:
```
policies:
  - name: rm-non-service-users
    mode:
      type: periodic
      schedule: "rate(6 hours)"
      role: <arn.........>
    resource: iam-user
    comments: |
      delete all IAM users that do not have -service- in the name
    filters:
      - and:
        - not:
          - type: credential
            key: user
            op: contains
            value: -service-
    actions:
      - delete
```

Execution log reports this exception:
[ERROR]	2017-10-17T14:55:53.2Z	1e106745-b34b-11e7-a58a-9f0a45d857a8	Error while executing policy
Traceback (most recent call last):
File "/var/task/c7n/policy.py", line 337, in run
results = a.process(resources)
File "/var/task/c7n/resources/iam.py", line 888, in process
client.delete_user(UserName=r['UserName'])
File "/var/runtime/botocore/client.py", line 312, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/runtime/botocore/client.py", line 601, in _make_api_call
raise error_class(parsed_response, operation_name)
DeleteConflictException: An error occurred (DeleteConflict) when calling the DeleteUser operation: Cannot delete entity, must delete login profile first.


Discussion:

Resolving patch:
diff --git a/c7n/resources/iam.py b/c7n/resources/iam.py
--- a/c7n/resources/iam.py
+++ b/c7n/resources/iam.py
@@ -880,13 +880,81 @@ class UserDelete(BaseAction):
 
     """
     schema = type_schema('delete')
-    permissions = ('iam:DeleteUser',)
+    permissions = (
+        'iam:ListAttachedUserPolicies',
+        'iam:ListAccessKeys',
+        'iam:ListGroupsForUser',
+        'iam:ListMFADevices',
+        'iam:ListServiceSpecificCredentials',
+        'iam:ListSigningCertificates',
+        'iam:ListSSHPublicKeys',
+        'iam:DeactivateMFADevice',
+        'iam:DeleteAccessKey',
+        'iam:DeleteLoginProfile',
+        'iam:DeleteSigningCertificate',
+        'iam:DeleteSSHPublicKey',
+        'iam:DeleteUser',
+        'iam:DetachUserPolicy',
+        'iam:RemoveUserFromGroup')
 
     def process(self, resources):
         client = local_session(self.manager.session_factory).client('iam')
         for r in resources:
-            client.delete_user(UserName=r['UserName'])
-        self.log.debug('Deleted user "%s"' % (r['UserName']))
+            self.log.debug('Deleting user %s' % r['UserName'])
+            self.process_user(client, r)
+
+    def process_user(self, client, r):
+        try:
+            client.delete_login_profile(
+                UserName=r['UserName'])
+        except ClientError as e:
+            if e.response['Error']['Code'] not in ('NoSuchEntity',):
+                raise
+
+        # Access Keys
+        response = client.list_access_keys(UserName=r['UserName'])
+        for access_key in response['AccessKeyMetadata']:
+            client.delete_access_key(UserName=r['UserName'],
+                                     AccessKeyId=access_key['AccessKeyId'])
+
+        # User Policies
+        response = client.list_attached_user_policies(UserName=r['UserName'])
+        for user_policy in response['AttachedPolicies']:
+            client.detach_user_policy(
+                UserName=r['UserName'], PolicyArn=user_policy['PolicyArn'])
+
+        # HW MFA Devices
+        response = client.list_mfa_devices(UserName=r['UserName'])
+        for mfa_device in response['MFADevices']:
+            client.deactivate_mfa_device(
+                UserName=r['UserName'], SerialNumber=mfa_device['SerialNumber'])
+
+        # Groups
+        response = client.list_groups_for_user(UserName=r['UserName'])
+        for user_group in response['Groups']:
+            client.remove_user_from_group(
+                UserName=r['UserName'], GroupName=user_group['GroupName'])
+
+        # SSH Keys
+        response = client.list_ssh_public_keys(UserName=r['UserName'])
+        for key in response.get('SSHPublicKeys', ()):
+            client.delete_ssh_public_key(
+                UserName=r['UserName'], SSHPublicKeyId=key['SSHPublicKeyId'])
+
+        # Signing Certificates
+        response = client.list_signing_certificates(UserName=r['UserName'])
+        for cert in response.get('Certificates', ()):
+            client.delete_signing_certificate(
+                UserName=r['UserName'], CertificateId=cert['CertificateId'])
+
+        # Service specific user credentials (codecommit)
+        response = client.list_service_specific_credentials(UserName=r['UserName'])
+        for screds in response.get('ServiceSpecificCredentials', ()):
+            client.delete_service_specific_credential(
+                UserName=r['UserName'],
+                ServiceSpecificCredentialId=screds['ServiceSpecificCredentialId'])
+
+        client.delete_user(UserName=r['UserName'])
 
 
 @User.action_registry.register('remove-keys')
diff --git a/c7n/resources/s3.py b/c7n/resources/s3.py
--- a/c7n/resources/s3.py
+++ b/c7n/resources/s3.py
@@ -730,22 +730,16 @@ def process_bucket(self, b):
         if p is None:
             return b
         p = json.loads(p)
-        encryption_statement = ENCRYPTION_STATEMENT_GLOB
+        encryption_statement = dict(ENCRYPTION_STATEMENT_GLOB)
 
         statements = p.get('Statement', [])
         check = False
         for s in list(statements):
-            try:
+            if 'Sid' in s:
                 encryption_statement["Sid"] = s["Sid"]
-            except:
-                log.info("Bucket:%s doesn't have Sid" % b['Name'])
-            try:
+            if 'Resource' in s:
                 encryption_statement["Resource"] = s["Resource"]
-            except:
-                log.info("Bucket:%s doesn't have Resource" % b['Name'])
             if s == encryption_statement:
-                log.info(
-                    "Bucket:%s contains correct encryption policy", b['Name'])
                 check = True
                 break
         if check:


Test patch:
diff --git a/tests/data/placebo/test_iam_user_delete/iam.CreateUser_1.json b/tests/data/placebo/test_iam_user_delete/iam.CreateUser_1.json
--- a/tests/data/placebo/test_iam_user_delete/iam.CreateUser_1.json
+++ b/tests/data/placebo/test_iam_user_delete/iam.CreateUser_1.json
@@ -5,25 +5,25 @@
             "UserName": "alice", 
             "Path": "/test/", 
             "CreateDate": {
-                "hour": 0, 
+                "hour": 14, 
                 "__class__": "datetime", 
-                "month": 9, 
-                "second": 15, 
-                "microsecond": 702000, 
+                "month": 10, 
+                "second": 32, 
+                "microsecond": 679000, 
                 "year": 2017, 
-                "day": 7, 
-                "minute": 13
+                "day": 18, 
+                "minute": 56
             }, 
-            "UserId": "AIDAIYG6HNINF36JQFECS", 
-            "Arn": "arn:aws:iam::619193117841:user/test/alice"
+            "UserId": "AIDAIAKM2IUZB4CV6NFGO", 
+            "Arn": "arn:aws:iam::644160558196:user/test/alice"
         }, 
         "ResponseMetadata": {
             "RetryAttempts": 0, 
             "HTTPStatusCode": 200, 
-            "RequestId": "5811c651-9361-11e7-881f-ed8b48e363fa", 
+            "RequestId": "87a9ff7c-b414-11e7-bd64-7d523ade9cf4", 
             "HTTPHeaders": {
-                "x-amzn-requestid": "5811c651-9361-11e7-881f-ed8b48e363fa", 
-                "date": "Thu, 07 Sep 2017 00:13:15 GMT", 
+                "x-amzn-requestid": "87a9ff7c-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:32 GMT", 
                 "content-length": "485", 
                 "content-type": "text/xml"
             }
diff --git a/tests/data/placebo/test_iam_user_delete/iam.DeleteLoginProfile_1.json b/tests/data/placebo/test_iam_user_delete/iam.DeleteLoginProfile_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_iam_user_delete/iam.DeleteLoginProfile_1.json
@@ -0,0 +1,21 @@
+{
+    "status_code": 404, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 404, 
+            "RequestId": "88268283-b414-11e7-bd64-7d523ade9cf4", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "88268283-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:32 GMT", 
+                "content-length": "284", 
+                "content-type": "text/xml"
+            }
+        }, 
+        "Error": {
+            "Message": "Cannot find Login Profile for User alice", 
+            "Code": "NoSuchEntity", 
+            "Type": "Sender"
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_iam_user_delete/iam.DeleteUser_1.json b/tests/data/placebo/test_iam_user_delete/iam.DeleteUser_1.json
--- a/tests/data/placebo/test_iam_user_delete/iam.DeleteUser_1.json
+++ b/tests/data/placebo/test_iam_user_delete/iam.DeleteUser_1.json
@@ -4,10 +4,10 @@
         "ResponseMetadata": {
             "RetryAttempts": 0, 
             "HTTPStatusCode": 200, 
-            "RequestId": "58642c13-9361-11e7-9bb0-8b8eb22708c5", 
+            "RequestId": "88991a42-b414-11e7-bd64-7d523ade9cf4", 
             "HTTPHeaders": {
-                "x-amzn-requestid": "58642c13-9361-11e7-9bb0-8b8eb22708c5", 
-                "date": "Thu, 07 Sep 2017 00:13:16 GMT", 
+                "x-amzn-requestid": "88991a42-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:33 GMT", 
                 "content-length": "200", 
                 "content-type": "text/xml"
             }
diff --git a/tests/data/placebo/test_iam_user_delete/iam.ListAccessKeys_1.json b/tests/data/placebo/test_iam_user_delete/iam.ListAccessKeys_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_iam_user_delete/iam.ListAccessKeys_1.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200, 
+    "data": {
+        "AccessKeyMetadata": [], 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "8835018e-b414-11e7-bd64-7d523ade9cf4", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "8835018e-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:32 GMT", 
+                "content-length": "321", 
+                "content-type": "text/xml"
+            }
+        }, 
+        "IsTruncated": false
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_iam_user_delete/iam.ListAttachedUserPolicies_1.json b/tests/data/placebo/test_iam_user_delete/iam.ListAttachedUserPolicies_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_iam_user_delete/iam.ListAttachedUserPolicies_1.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200, 
+    "data": {
+        "AttachedPolicies": [], 
+        "IsTruncated": false, 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "8845c98a-b414-11e7-bd64-7d523ade9cf4", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "8845c98a-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:33 GMT", 
+                "content-length": "360", 
+                "content-type": "text/xml"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_iam_user_delete/iam.ListGroupsForUser_1.json b/tests/data/placebo/test_iam_user_delete/iam.ListGroupsForUser_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_iam_user_delete/iam.ListGroupsForUser_1.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "8863d911-b414-11e7-bd64-7d523ade9cf4", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "8863d911-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:33 GMT", 
+                "content-length": "322", 
+                "content-type": "text/xml"
+            }
+        }, 
+        "IsTruncated": false, 
+        "Groups": []
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_iam_user_delete/iam.ListMFADevices_1.json b/tests/data/placebo/test_iam_user_delete/iam.ListMFADevices_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_iam_user_delete/iam.ListMFADevices_1.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200, 
+    "data": {
+        "MFADevices": [], 
+        "IsTruncated": false, 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "8854bdc6-b414-11e7-bd64-7d523ade9cf4", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "8854bdc6-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:33 GMT", 
+                "content-length": "314", 
+                "content-type": "text/xml"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_iam_user_delete/iam.ListSSHPublicKeys_1.json b/tests/data/placebo/test_iam_user_delete/iam.ListSSHPublicKeys_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_iam_user_delete/iam.ListSSHPublicKeys_1.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200, 
+    "data": {
+        "SSHPublicKeys": [], 
+        "IsTruncated": false, 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "8872cd4b-b414-11e7-bd64-7d523ade9cf4", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "8872cd4b-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:33 GMT", 
+                "content-length": "329", 
+                "content-type": "text/xml"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_iam_user_delete/iam.ListServiceSpecificCredentials_1.json b/tests/data/placebo/test_iam_user_delete/iam.ListServiceSpecificCredentials_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_iam_user_delete/iam.ListServiceSpecificCredentials_1.json
@@ -0,0 +1,17 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "888c970b-b414-11e7-bd64-7d523ade9cf4", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "888c970b-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:33 GMT", 
+                "content-length": "357", 
+                "content-type": "text/xml"
+            }
+        }, 
+        "ServiceSpecificCredentials": []
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_iam_user_delete/iam.ListSigningCertificates_1.json b/tests/data/placebo/test_iam_user_delete/iam.ListSigningCertificates_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_iam_user_delete/iam.ListSigningCertificates_1.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200, 
+    "data": {
+        "Certificates": [], 
+        "IsTruncated": false, 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "888061fa-b414-11e7-bd64-7d523ade9cf4", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "888061fa-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:33 GMT", 
+                "content-length": "352", 
+                "content-type": "text/xml"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_iam_user_delete/iam.ListUsers_1.json b/tests/data/placebo/test_iam_user_delete/iam.ListUsers_1.json
--- a/tests/data/placebo/test_iam_user_delete/iam.ListUsers_1.json
+++ b/tests/data/placebo/test_iam_user_delete/iam.ListUsers_1.json
@@ -2,35 +2,545 @@
     "status_code": 200, 
     "data": {
         "Users": [
+            {
+                "UserName": "Alfredmarc.Gamulo@capitalone.com", 
+                "PasswordLastUsed": {
+                    "hour": 17, 
+                    "__class__": "datetime", 
+                    "month": 9, 
+                    "second": 15, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 27, 
+                    "minute": 48
+                }, 
+                "CreateDate": {
+                    "hour": 14, 
+                    "__class__": "datetime", 
+                    "month": 3, 
+                    "second": 16, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 16, 
+                    "minute": 58
+                }, 
+                "UserId": "AIDAIYEUEZZQWE5TZHHAE", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/Alfredmarc.Gamulo@capitalone.com"
+            }, 
             {
                 "UserName": "alice", 
                 "Path": "/test/", 
                 "CreateDate": {
-                    "hour": 0, 
+                    "hour": 14, 
                     "__class__": "datetime", 
-                    "month": 9, 
+                    "month": 10, 
+                    "second": 32, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 18, 
+                    "minute": 56
+                }, 
+                "UserId": "AIDAIAKM2IUZB4CV6NFGO", 
+                "Arn": "arn:aws:iam::644160558196:user/test/alice"
+            }, 
+            {
+                "UserName": "andrewalexander", 
+                "PasswordLastUsed": {
+                    "hour": 19, 
+                    "__class__": "datetime", 
+                    "month": 4, 
+                    "second": 16, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 10, 
+                    "minute": 38
+                }, 
+                "CreateDate": {
+                    "hour": 17, 
+                    "__class__": "datetime", 
+                    "month": 8, 
+                    "second": 35, 
+                    "microsecond": 0, 
+                    "year": 2016, 
+                    "day": 30, 
+                    "minute": 37
+                }, 
+                "UserId": "AIDAINLXB4P6J26AKFUC6", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/andrewalexander"
+            }, 
+            {
+                "UserName": "calvin@sixfeetup.com", 
+                "PasswordLastUsed": {
+                    "hour": 19, 
+                    "__class__": "datetime", 
+                    "month": 6, 
                     "second": 15, 
                     "microsecond": 0, 
                     "year": 2017, 
+                    "day": 15, 
+                    "minute": 7
+                }, 
+                "CreateDate": {
+                    "hour": 16, 
+                    "__class__": "datetime", 
+                    "month": 10, 
+                    "second": 27, 
+                    "microsecond": 0, 
+                    "year": 2016, 
+                    "day": 6, 
+                    "minute": 11
+                }, 
+                "UserId": "AIDAIVQZEKBMLZZXYA5P2", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/calvin@sixfeetup.com"
+            }, 
+            {
+                "UserName": "chad@sixfeetup.com", 
+                "PasswordLastUsed": {
+                    "hour": 13, 
+                    "__class__": "datetime", 
+                    "month": 10, 
+                    "second": 56, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 18, 
+                    "minute": 44
+                }, 
+                "CreateDate": {
+                    "hour": 15, 
+                    "__class__": "datetime", 
+                    "month": 12, 
+                    "second": 32, 
+                    "microsecond": 0, 
+                    "year": 2016, 
+                    "day": 19, 
+                    "minute": 4
+                }, 
+                "UserId": "AIDAIXI7ULG2SDYI3RBNM", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/chad@sixfeetup.com"
+            }, 
+            {
+                "UserName": "christo.adikary@capitalone.com", 
+                "PasswordLastUsed": {
+                    "hour": 18, 
+                    "__class__": "datetime", 
+                    "month": 9, 
+                    "second": 33, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 13, 
+                    "minute": 14
+                }, 
+                "CreateDate": {
+                    "hour": 19, 
+                    "__class__": "datetime", 
+                    "month": 9, 
+                    "second": 51, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 12, 
+                    "minute": 20
+                }, 
+                "UserId": "AIDAJ62G5JMVUT4KWN57E", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/christo.adikary@capitalone.com"
+            }, 
+            {
+                "UserName": "christopherocampo", 
+                "PasswordLastUsed": {
+                    "hour": 18, 
+                    "__class__": "datetime", 
+                    "month": 3, 
+                    "second": 1, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 3, 
+                    "minute": 26
+                }, 
+                "CreateDate": {
+                    "hour": 17, 
+                    "__class__": "datetime", 
+                    "month": 8, 
+                    "second": 35, 
+                    "microsecond": 0, 
+                    "year": 2016, 
+                    "day": 30, 
+                    "minute": 37
+                }, 
+                "UserId": "AIDAJOWQFESQNYYH3RURU", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/christopherocampo"
+            }, 
+            {
+                "UserName": "Dhruv.Salwan@capitalone.com", 
+                "PasswordLastUsed": {
+                    "hour": 2, 
+                    "__class__": "datetime", 
+                    "month": 9, 
+                    "second": 48, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 28, 
+                    "minute": 1
+                }, 
+                "CreateDate": {
+                    "hour": 18, 
+                    "__class__": "datetime", 
+                    "month": 3, 
+                    "second": 59, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 3, 
+                    "minute": 52
+                }, 
+                "UserId": "AIDAIXO7TZYXFJ7PH5UAO", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/Dhruv.Salwan@capitalone.com"
+            }, 
+            {
+                "UserName": "glenn@sixfeetup.com", 
+                "PasswordLastUsed": {
+                    "hour": 12, 
+                    "__class__": "datetime", 
+                    "month": 7, 
+                    "second": 30, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 12, 
+                    "minute": 59
+                }, 
+                "CreateDate": {
+                    "hour": 18, 
+                    "__class__": "datetime", 
+                    "month": 3, 
+                    "second": 48, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 27, 
+                    "minute": 40
+                }, 
+                "UserId": "AIDAIMII4JNO4PLRZXOMO", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/glenn@sixfeetup.com"
+            }, 
+            {
+                "UserName": "hackney", 
+                "Path": "/", 
+                "CreateDate": {
+                    "hour": 12, 
+                    "__class__": "datetime", 
+                    "month": 5, 
+                    "second": 11, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 15, 
+                    "minute": 37
+                }, 
+                "UserId": "AIDAJSIT3DH5B67JZOS3I", 
+                "Arn": "arn:aws:iam::644160558196:user/hackney"
+            }, 
+            {
+                "UserName": "John.Nelson@capitalone.com", 
+                "PasswordLastUsed": {
+                    "hour": 19, 
+                    "__class__": "datetime", 
+                    "month": 10, 
+                    "second": 49, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 10, 
+                    "minute": 46
+                }, 
+                "CreateDate": {
+                    "hour": 19, 
+                    "__class__": "datetime", 
+                    "month": 10, 
+                    "second": 18, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 10, 
+                    "minute": 43
+                }, 
+                "UserId": "AIDAJCZWB5WZ2P6XOLVVU", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/John.Nelson@capitalone.com"
+            }, 
+            {
+                "UserName": "joshuaroot", 
+                "PasswordLastUsed": {
+                    "hour": 14, 
+                    "__class__": "datetime", 
+                    "month": 9, 
+                    "second": 45, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 28, 
+                    "minute": 39
+                }, 
+                "CreateDate": {
+                    "hour": 16, 
+                    "__class__": "datetime", 
+                    "month": 9, 
+                    "second": 32, 
+                    "microsecond": 0, 
+                    "year": 2016, 
+                    "day": 21, 
+                    "minute": 26
+                }, 
+                "UserId": "AIDAJM67KUVNOIMGUCZO4", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/joshuaroot"
+            }, 
+            {
+                "UserName": "kapil", 
+                "PasswordLastUsed": {
+                    "hour": 11, 
+                    "__class__": "datetime", 
+                    "month": 10, 
+                    "second": 11, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 18, 
+                    "minute": 33
+                }, 
+                "CreateDate": {
+                    "hour": 19, 
+                    "__class__": "datetime", 
+                    "month": 5, 
+                    "second": 36, 
+                    "microsecond": 0, 
+                    "year": 2016, 
+                    "day": 16, 
+                    "minute": 3
+                }, 
+                "UserId": "AIDAJEZOTH6YPO3DY45QW", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/kapil"
+            }, 
+            {
+                "UserName": "kit", 
+                "PasswordLastUsed": {
+                    "hour": 18, 
+                    "__class__": "datetime", 
+                    "month": 10, 
+                    "second": 39, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 17, 
+                    "minute": 15
+                }, 
+                "CreateDate": {
+                    "hour": 14, 
+                    "__class__": "datetime", 
+                    "month": 7, 
+                    "second": 59, 
+                    "microsecond": 0, 
+                    "year": 2016, 
+                    "day": 27, 
+                    "minute": 40
+                }, 
+                "UserId": "AIDAJKVAHLRG2G6PHIBAM", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/kit"
+            }, 
+            {
+                "UserName": "mandeep", 
+                "PasswordLastUsed": {
+                    "hour": 19, 
+                    "__class__": "datetime", 
+                    "month": 9, 
+                    "second": 32, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 5, 
+                    "minute": 44
+                }, 
+                "CreateDate": {
+                    "hour": 19, 
+                    "__class__": "datetime", 
+                    "month": 5, 
+                    "second": 36, 
+                    "microsecond": 0, 
+                    "year": 2016, 
+                    "day": 16, 
+                    "minute": 3
+                }, 
+                "UserId": "AIDAIRGKK45UIXHXNN2SI", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/mandeep"
+            }, 
+            {
+                "UserName": "Nicholas.Lykins@capitalone.com", 
+                "PasswordLastUsed": {
+                    "hour": 19, 
+                    "__class__": "datetime", 
+                    "month": 10, 
+                    "second": 36, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 10, 
+                    "minute": 40
+                }, 
+                "CreateDate": {
+                    "hour": 12, 
+                    "__class__": "datetime", 
+                    "month": 8, 
+                    "second": 22, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 3, 
+                    "minute": 46
+                }, 
+                "UserId": "AIDAJ6NHAJZP3TIYBYABC", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/Nicholas.Lykins@capitalone.com"
+            }, 
+            {
+                "UserName": "rob@sixfeetup.com", 
+                "PasswordLastUsed": {
+                    "hour": 15, 
+                    "__class__": "datetime", 
+                    "month": 9, 
+                    "second": 10, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 19, 
+                    "minute": 11
+                }, 
+                "CreateDate": {
+                    "hour": 16, 
+                    "__class__": "datetime", 
+                    "month": 10, 
+                    "second": 27, 
+                    "microsecond": 0, 
+                    "year": 2016, 
+                    "day": 6, 
+                    "minute": 11
+                }, 
+                "UserId": "AIDAIPHUPZEIIDI4QI4GU", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/rob@sixfeetup.com"
+            }, 
+            {
+                "UserName": "saitheja.kadiyala@capitalone.com", 
+                "PasswordLastUsed": {
+                    "hour": 1, 
+                    "__class__": "datetime", 
+                    "month": 3, 
+                    "second": 26, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 30, 
+                    "minute": 32
+                }, 
+                "CreateDate": {
+                    "hour": 14, 
+                    "__class__": "datetime", 
+                    "month": 1, 
+                    "second": 12, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 12, 
+                    "minute": 47
+                }, 
+                "UserId": "AIDAJK6DJZNHAHXDXHNSQ", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/saitheja.kadiyala@capitalone.com"
+            }, 
+            {
+                "UserName": "Samson.Shi@capitalone.com", 
+                "PasswordLastUsed": {
+                    "hour": 17, 
+                    "__class__": "datetime", 
+                    "month": 8, 
+                    "second": 50, 
+                    "microsecond": 0, 
+                    "year": 2017, 
                     "day": 7, 
-                    "minute": 13
+                    "minute": 1
+                }, 
+                "CreateDate": {
+                    "hour": 15, 
+                    "__class__": "datetime", 
+                    "month": 8, 
+                    "second": 0, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 7, 
+                    "minute": 55
+                }, 
+                "UserId": "AIDAJATQ7WOI63EQTGBT6", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/Samson.Shi@capitalone.com"
+            }, 
+            {
+                "UserName": "scot@sixfeetup.com", 
+                "PasswordLastUsed": {
+                    "hour": 13, 
+                    "__class__": "datetime", 
+                    "month": 10, 
+                    "second": 43, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 13, 
+                    "minute": 32
+                }, 
+                "CreateDate": {
+                    "hour": 15, 
+                    "__class__": "datetime", 
+                    "month": 10, 
+                    "second": 43, 
+                    "microsecond": 0, 
+                    "year": 2016, 
+                    "day": 7, 
+                    "minute": 53
+                }, 
+                "UserId": "AIDAIQF3HRTVXDF7TMNAM", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/scot@sixfeetup.com"
+            }, 
+            {
+                "UserName": "tao-hung.yang@capitalone.com", 
+                "PasswordLastUsed": {
+                    "hour": 15, 
+                    "__class__": "datetime", 
+                    "month": 9, 
+                    "second": 9, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 13, 
+                    "minute": 23
+                }, 
+                "CreateDate": {
+                    "hour": 15, 
+                    "__class__": "datetime", 
+                    "month": 1, 
+                    "second": 8, 
+                    "microsecond": 0, 
+                    "year": 2017, 
+                    "day": 31, 
+                    "minute": 27
                 }, 
-                "UserId": "AIDAIYG6HNINF36JQFECS", 
-                "Arn": "arn:aws:iam::619193117841:user/test/alice"
+                "UserId": "AIDAIXHBMUDYXJBFL3JTW", 
+                "Path": "/", 
+                "Arn": "arn:aws:iam::644160558196:user/tao-hung.yang@capitalone.com"
             }
         ], 
         "ResponseMetadata": {
             "RetryAttempts": 0, 
             "HTTPStatusCode": 200, 
-            "RequestId": "583d6a70-9361-11e7-9aa2-57fc9245ff23", 
+            "RequestId": "87d77804-b414-11e7-ad14-5b6a92953c46", 
             "HTTPHeaders": {
-                "x-amzn-requestid": "583d6a70-9361-11e7-9aa2-57fc9245ff23", 
+                "x-amzn-requestid": "87d77804-b414-11e7-ad14-5b6a92953c46", 
                 "vary": "Accept-Encoding", 
-                "content-length": "2543", 
+                "content-length": "7303", 
                 "content-type": "text/xml", 
-                "date": "Thu, 07 Sep 2017 00:13:15 GMT"
+                "date": "Wed, 18 Oct 2017 14:56:32 GMT"
             }
         }, 
         "IsTruncated": false
     }
-}
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_iam_user_delete/iam.ListUsers_2.json b/tests/data/placebo/test_iam_user_delete/iam.ListUsers_2.json
--- a/tests/data/placebo/test_iam_user_delete/iam.ListUsers_2.json
+++ b/tests/data/placebo/test_iam_user_delete/iam.ListUsers_2.json
@@ -5,10 +5,10 @@
         "ResponseMetadata": {
             "RetryAttempts": 0, 
             "HTTPStatusCode": 200, 
-            "RequestId": "58708795-9361-11e7-881f-ed8b48e363fa", 
+            "RequestId": "88a687db-b414-11e7-bd64-7d523ade9cf4", 
             "HTTPHeaders": {
-                "x-amzn-requestid": "58708795-9361-11e7-881f-ed8b48e363fa", 
-                "date": "Thu, 07 Sep 2017 00:13:15 GMT", 
+                "x-amzn-requestid": "88a687db-b414-11e7-bd64-7d523ade9cf4", 
+                "date": "Wed, 18 Oct 2017 14:56:33 GMT", 
                 "content-length": "289", 
                 "content-type": "text/xml"
             }
diff --git a/tests/test_iam.py b/tests/test_iam.py
--- a/tests/test_iam.py
+++ b/tests/test_iam.py
@@ -204,7 +204,7 @@ def test_iam_user_delete(self):
         self.assertEqual(len(resources), 1)
         users = client.list_users(PathPrefix="/test/").get('Users', [])
         self.assertEqual(users, [])
-        
+
     def test_iam_user_policy(self):
         session_factory = self.replay_flight_data(
             'test_iam_user_admin_policy')