繁体   English   中英

解决 AWS assume_role session 过期

[英]Work around AWS assume_role session expiration

我正在从 AWS Health API 调用 4 个操作来使用这些循环收集所有发现(我删除了一些 DynamoDB 片段以使其更清楚)。 问题是脚本需要相当长的时间才能运行,并且由于ExpiredTokenException而在一小时后超时。 我已经尝试过DurationSeconds ,它固定在 3600。

我能以某种方式解决这个问题吗? 比如把function拆分成多个函数? 或者那根本行不通?

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()

这个问题GitHub上已经有issue了。

为长时间运行的操作刷新 sts 角色假设凭证 #443

在适当的时候自动使用 RefreshableCredentials #2158

同时,有一些中间解决方法,我认为您可以通过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)

上面代码的工作版本可以在这个要点中找到

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM