I'm calling 4 actions from AWS Health API to collect all the findings using these loopy loops (I removed some DynamoDB pieces to make it clearer). The issue is that the script takes quite some time to run and ends up timing out after an hour because of the ExpiredTokenException
. I already tried the DurationSeconds
, and it's fixed at 3600.
Can I work around this somehow? Like splitting the function into multiple functions? Or that wouldn't work at all?
sts = boto3.client('sts')
# use STS to AssumeRole for the Organization Health Account
memberAcct = sts.assume_role(RoleArn='arn:aws:iam::x:role/Health-Role',RoleSessionName='xacct-health')
# retrieve creds from member account to create new Health Boto3 Client
xAcctAccessKey = memberAcct['Credentials']['AccessKeyId']
xAcctSecretKey = memberAcct['Credentials']['SecretAccessKey']
xAcctSeshToken = memberAcct['Credentials']['SessionToken']
health = boto3.client('health',aws_access_key_id=xAcctAccessKey,aws_secret_access_key=xAcctSecretKey,aws_session_token=xAcctSeshToken)
def health_collect():
try:
paginator = health.get_paginator('describe_events_for_organization')
iterator = paginator.paginate()
for page in iterator:
for e in page['events']:
eventArn = str(e['arn'])
healthEventScope = str(e['eventScopeCode'])
if healthEventScope == 'ACCOUNT_SPECIFIC':
affectedAccounts = health.describe_affected_accounts_for_organization(eventArn=eventArn)['affectedAccounts']
for affectedAcctId in affectedAccounts:
eventDetails = health.describe_event_details_for_organization(
organizationEventDetailFilters=[
{
'eventArn': eventArn,
'awsAccountId': affectedAcctId
}
]
)
eventDescription = str(eventDetails['successfulSet'][0]['eventDescription']['latestDescription'])
entityDetails = health.describe_affected_entities_for_organization(
organizationEntityFilters=[
{
'eventArn': eventArn,
'awsAccountId': affectedAcctId
}
]
)
entityValue = str(entityDetails['entities'][0]['entityValue'])
if entityValue == 'AWS_ACCOUNT':
entityValue = affectedAcctId
else:
else:
affectedAccounts = 'ALL'
entityArn = 'NOT_SPECIFIC'
entityValue = 'NOT_SPECIFIC'
eventDetails = health.describe_event_details_for_organization(organizationEventDetailFilters=[{'eventArn': eventArn}])
eventDescription = str(eventDetails['successfulSet'][0]['eventDescription']['latestDescription'])
except Exception as e:
print(e)
health_collect()
There are already issues on GitHub for this problem.
refreshing sts role assumption credentials for long running operations #443
Automatically use RefreshableCredentials when appropriate #2158
Meanwhile, there is some intermediate workaround, I think you can have via RefreshableCredentials class in the botocore combined with get_session method.
...
def assumed_session(role_arn, session_name, session=None):
if session is None:
session = Session()
def refresh():
# call assume role and return a dict of
# access_key
# secret
# token
session_credentials = RefreshableCredentials.create_from_metadata(
metadata=refresh(),
refresh_using=refresh,
method='sts-assume-role')
s = get_session()
s._credentials = session_credentials
region = session._session.get_config_variable('region') or 'us-east-1'
s.set_config_variable('region', region)
return Session(botocore_session=s)
a working version of the above code can be found in this gist
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.