BACKGROUND:
The AWS operation to list IAM users returns a max of 50 by default.
Reading the docs (links) below I ran following code and returned a complete set data by setting the "MaxItems" to 1000.
paginator = client.get_paginator('list_users')
response_iterator = paginator.paginate(
PaginationConfig={
'MaxItems': 1000,
'PageSize': 123})
for page in response_iterator:
u = page['Users']
for user in u:
print(user['UserName'])
http://boto3.readthedocs.io/en/latest/guide/paginators.html https://boto3.readthedocs.io/en/latest/reference/services/iam.html#IAM.Paginator.ListUsers
QUESTION:
If the "MaxItems" was set to 10, for example, what would be the best method to loop through the results?
I tested with the following but it only loops 2 iterations before 'IsTruncated' == False and results in "KeyError: 'Marker'". Not sure why this is happening because I know there are over 200 results.
marker = None
while True:
paginator = client.get_paginator('list_users')
response_iterator = paginator.paginate(
PaginationConfig={
'MaxItems': 10,
'StartingToken': marker})
#print(response_iterator)
for page in response_iterator:
u = page['Users']
for user in u:
print(user['UserName'])
print(page['IsTruncated'])
marker = page['Marker']
print(marker)
else:
break
(Answer rewrite)
**NOTE **, the paginator contains a bug that doesn't tally with the documentation (or vice versa). MaxItems
doesn't return the Marker or NextToken when total items exceed MaxItems number. Indeed PageSize
is the one that controlling return of Marker/NextToken indictator.
import sys
import boto3
iam = boto3.client("iam")
marker = None
while True:
paginator = iam.get_paginator('list_users')
response_iterator = paginator.paginate(
PaginationConfig={
'PageSize': 10,
'StartingToken': marker})
for page in response_iterator:
print("Next Page : {} ".format(page['IsTruncated']))
u = page['Users']
for user in u:
print(user['UserName'])
try:
marker = response_iterator['Marker']
print(marker)
except KeyError:
sys.exit()
It is not your mistake that your code doesn't works. MaxItems
in the paginator seems become a "threshold" indicator. Ironically, the MaxItems
inside original boto3.iam.list_users still works as mentioned.
If you check boto3.iam.list_users, you will notice either you omit Marker
, otherwise you must put a value. Apparently, paginator is NOT a wrapper for all boto3 class list_* method.
import sys
import boto3
iam = boto3.client("iam")
marker = None
while True:
if marker:
response_iterator = iam.list_users(
MaxItems=10,
Marker=marker
)
else:
response_iterator = iam.list_users(
MaxItems=10
)
print("Next Page : {} ".format(response_iterator['IsTruncated']))
for user in response_iterator['Users']:
print(user['UserName'])
try:
marker = response_iterator['Marker']
print(marker)
except KeyError:
sys.exit()
You can follow up the issue I filed in boto3 github. According to the member, you can call build_full_result
after paginate(), that will show the desire behavior.
This code wasn't working for me. It always drops off the remainder of the items on the last page and doesn't include them in the results. Gives me a result of 60 accounts when I know I have 68. That last result page doesn't get appended to my list of account UserName's. I have concerns that these above examples are doing the same thing and people aren't noticing this in the results.
That and it seems overly complex to paginate through with an arbitrary size for what purpose?
This should be simple and gives you a complete listing.
import boto3
iam = boto3.client("iam")
paginator = iam.get_paginator('list_users')
response_iterator = paginator.paginate()
accounts=[]
for page in response_iterator:
for user in page['Users']:
accounts.append(user['UserName'])
len(accounts)
68
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With