[英]Work around AWS assume_role session expiration
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).我正在从 AWS Health API 调用 4 个操作来使用这些循环收集所有发现(我删除了一些 DynamoDB 片段以使其更清楚)。 The issue is that the script takes quite some time to run and ends up timing out after an hour because of the ExpiredTokenException
.问题是脚本需要相当长的时间才能运行,并且由于ExpiredTokenException
而在一小时后超时。 I already tried the DurationSeconds
, and it's fixed at 3600.我已经尝试过DurationSeconds
,它固定在 3600。
Can I work around this somehow?我能以某种方式解决这个问题吗? Like splitting the function into multiple functions?比如把function拆分成多个函数? 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.这个问题GitHub上已经有issue了。
refreshing sts role assumption credentials for long running operations #443为长时间运行的操作刷新 sts 角色假设凭证 #443
Automatically use RefreshableCredentials when appropriate #2158在适当的时候自动使用 RefreshableCredentials #2158
Meanwhile, there is some intermediate workaround, I think you can have via RefreshableCredentials class in the botocore combined with get_session method.同时,有一些中间解决方法,我认为您可以通过botocore中的 RefreshableCredentials class 结合get_session方法。
...
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上面代码的工作版本可以在这个要点中找到
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.