amazon-web-services - boto3 session 和 aws_session_token 管理

标签 amazon-web-services amazon-sqs

我正在开发处理 AWS SQS 队列的 python 软件。它使用 boto3 ,主要是 boto3.session.Session .

我见过here我们可以通过 aws_session_tokenSession构造函数。

在亚马逊之外运行我的代码时,我需要定期刷新此 aws_session_token因为它的有效期只有一个小时。所以我需要重新实例化一个 boto3.Session靠我自己。

我只是想知道 AWS 内部是如何工作的。我是否需要通过获取新的 aws_session_token 来手动刷新我的 session ?通过环境?或者我的 session 是否“永远”有效/是否在内部处理,因此我不必刷新我的 AWS session ?

文档对我来说似乎不清楚。

最佳答案

简短的回答:

AWS 生成的 token 不会永远持续下去,使用生成的 token 创建的任何 boto3 session 也是如此。但是,只要您的 token 不是使用帐户 root 用户生成的,您就可以在 token 上设置很长的 TTL(最多 36 hours)。这为您提供了大量时间来执行需要对 Python 脚本执行的操作。

AWS 有多种方式来处理对您账户的临时和永久访问。通常,您会希望依赖临时凭证,因为它们使用起来更安全并且更符合最佳实践。 Boto3 使用优先列表,列出扫描凭证的位置 here

冗长而杂乱的答案:

我为数十个 AWS 账户编写了大量自动化代码,因此我处理了很多这些东西。

这假设您在 Linux 中进行开发。 Windows 非常相似,但也有一些不同。

有(至少)三种方法来处理对您的 AWS 账户的远程访问:

  • 在包含您的 AWS IAM 用户访问 key 的 ~/.aws/credentials 文件中维护一个配置文件,并使用该配置文件运行您的 Python 脚本。
  • 您的 Python 脚本所要做的就是创建一个没有参数的 boto3.session.Session 对象。当您没有为 session 实例提供 token 或配置文件名称时,boto3 会通过扫描上述链接中描述的凭据优先级列表来自动查找凭据。
  • 我根本不推荐这个 ,但它可以工作并让您了解如何使用 AWS 配置文件。这是使用您的 IAM 用户的 API key 的永久访问,该 key 永不过期。虽然您可以将这些 key 用于您的 IAM 用户已被授予权限的任何操作,但您不应将它们用于除承担专门角色以执行所有其他工作之外的任何其他用途。
  • 从命令行使用 AWS CLI 担任角色,将 token 加载到环境变量中,然后运行您的 Python 脚本。
  • 好处:
  • 容易自动化。
  • 可以轻松设置 token TTL。
  • token 可以加载到环境变量中并立即变为
    可用于您的 Python 脚本。
  • 缺点:
  • 仅当您的 Python 脚本与一个 AWS 账户交互时才实用。
  • 如果您的 Python 脚本运行时间超过 token TTL(不太可能,但并非不可能),那么您的脚本将遇到 AccessDenied 错误并停止。
  • 运行 Python 脚本并让它处理角色假设和 token 杂耍。
  • 好处:
  • 允许您在一个地方同时访问多个帐户。
  • 可以轻松设置 token TTL。
  • 如果 token 过期,您可以捕获 AccessDened 异常,刷新 token ,然后继续。
  • 缺点:
  • 涉及维护获取访问 token 并与它们创建 boto session 的 Python 代码。当然,它不是那么多代码,但它仍然是代码,这意味着维护和困惑。

  • 我通常更喜欢方法 2 和 强烈反对方法 1 .方法 3 视情况而定。

    方法一:
    从命令行,将您的 AWS_PROFILE 变量设置为您的配置文件名称并运行脚本。脚本中使用您的 AWS 配置文件(IAM 用户访问 key )完成的所有操作。
    AWS_PROFILE=<YOUR_CREDENTIALS_PROFILE_NAME> python <PATH_TO_SCRIPT>
    

    方法二:
    在命令行中,使用您的 AWS 配置文件代入账户中的角色,然后将生成的 token 存储在环境变量中。现在,当您执行脚本时,它将自动使用这些 token :
    credentials=`AWS_PROFILE=<YOUR_AWS_PROFILE_NAME> aws sts assume-role --role-arn <YOUR_AWS_ROLE_NAME> --role-session-name <SOME_SESSION_NAME> --query 'Credentials.{AKI:AccessKeyId,SAK:SecretAccessKey,ST:SessionToken}' --output text`
    
    export AWS_ACCESS_KEY_ID=`echo ${credentials} | awk '{print $1}'`
    export AWS_SECRET_ACCESS_KEY=`echo ${credentials} | awk '{print $2}'`
    export AWS_SECURITY_TOKEN=`echo ${credentials} | awk '{print $3}'`
    export AWS_DEFAULT_REGION=<AWS_REGION>
    
    python <path_to_your_python_script>
    

    注意:由于您的 token 已加载到环境变量中,因此在运行脚本时不应设置 AWS_PROFILE。所有 AWS 开发工具包都会自动在这些环境变量中查找凭证 token 。您可以阅读有关它们的更多信息 here .

    方法三:
    在您的 Python 代码中,生成访问 token ,然后使用这些 token 创建 session 。

    import boto3
    
    role_info = {
        'RoleArn': 'arn:aws:iam::<AWS_ACCOUNT_NUMBER>:role/<AWS_ROLE_NAME>',
        'RoleSessionName': '<SOME_SESSION_NAME>'
    }
    
    client = boto3.client('sts')
    credentials = client.assume_role(**role_info)
    
    session = boto3.session.Session(
        aws_access_key_id=credentials['Credentials']['AccessKeyId'],
        aws_secret_access_key=credentials['Credentials']['SecretAccessKey'],
        aws_session_token=credentials['Credentials']['SessionToken']
    )
    

    以与方法 1 相同的方式运行您的脚本,不同之处在于这次您的 AWS_PROFILE 用于代入该角色,并且任何后续工作都通过该角色执行,因为 session 是使用代入的角色创建的。
    AWS_PROFILE=<YOUR_CREDENTIALS_PROFILE_NAME> python <PATH_TO_SCRIPT>
    

    希望这可以帮助!

    关于amazon-web-services - boto3 session 和 aws_session_token 管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51266120/

    相关文章:

    ios - IPv6 支持 iOS 应用程序并支持 AWS

    amazon-web-services - 如何获取S3存储桶上每个文件夹的总对象数和总存储量

    python - AWS : empty SQS queue when subscribed to SNS via boto3

    amazon-web-services - 如何限制SQS队列中的消息数?

    java - 抛出异常和@JMSListener 时,SQS 消息可见性超时设置为 0

    python - AWS Lambda python 函数从 S3 解析 json 并存储在 DynamoDB 中

    python - 将 numpy 安装到目录后,AWS Lambda 中缺少必需的依赖项 ['numpy' ],如何修复?

    python - 亚马逊 Redshift : How can I convert a 15 char Salesforce Id value into an 18 char Id value

    c# - 有效监控新的 SQS 消息

    python - 是否可以在消息不可见时从 SQS 检索消息?