boto3 会话和 aws_session_token 管理

boto3 sessions and aws_session_token management

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

我看到 here 我们可以将 aws_session_token 传递给 Session 构造函数。

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

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

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

简答:

AWS 生成的令牌不会永远存在,使用生成的令牌创建的任何 boto3 会话也是如此。但是只要您的令牌不是由帐户根用户生成的,您就可以为您的令牌设置一个很长的 TTL(最多 36 hours)。这给了你很多时间来做你需要用你的 Python 脚本做的事情。

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

中描述的凭据

长而散漫的答案:

我为几十个 AWS 账户编写了很多自动化代码,所以我处理了很多这些东西。

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

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

  1. 在您的 ~/.aws/credentials 文件中维护一个配置文件,其中包含您的 AWS IAM 用户访问密钥,运行 您的 Python 脚本使用该配置文件。

    • 您的 Python 脚本只需创建一个不带参数的 boto3.session.Session 对象。当您不为会话实例提供令牌或配置文件名称时,boto3 会通过扫描上面 link 中描述的凭据优先级列表来自动查找凭据。

    • 我完全不推荐这个,但它确实有效,并且让您了解如何使用 AWS 配置文件。这是使用您的 IAM 用户的 API 密钥的永久访问权限,该密钥永不过期。虽然您可以将这些密钥用于您的 IAM 用户已获得许可的任何操作,但除了承担专门角色来完成所有其他工作外,您不应将它们用于任何其他用途。

  2. 从命令行使用 AWS CLI 担任角色,将令牌加载到环境变量中,然后 运行 您的 Python 脚本。

    • 优点:
      • 轻松实现自动化。
      • 可以轻松设置令牌TTL。
      • 令牌可以加载到环境变量中并立即成为 可用于您的 Python 脚本。
    • 缺点:
      • 仅当您的 Python 脚本与一个 AWS 账户交互时才实用。
      • 如果您的 Python 脚本 运行 比令牌 TTL 长(不太可能,但并非不可能),那么您的脚本将遇到 AccessDenied 错误并停止。
  3. 运行 Python 脚本并让它处理角色假设和令牌杂耍。

    • 优点:
      • 允许您在一处同时访问多个帐户。
      • 可以轻松设置令牌TTL。
      • 如果令牌过期,您可以捕获 AccessDened 异常,刷新令牌,然后继续。
    • 缺点:
      • 涉及维护 Python 代码,该代码获取访问令牌并与它们创建 boto 会话。当然,它没有那么多代码,但它仍然是代码,这意味着维护和混乱。

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

方法一:
在命令行中,将您的 AWS_PROFILE 变量设置为您的个人资料名称和 运行 脚本。使用您的 AWS 配置文件(IAM 用户访问密钥)在脚本中完成的所有操作。

AWS_PROFILE=<YOUR_CREDENTIALS_PROFILE_NAME> python <PATH_TO_SCRIPT>

方法二:
在命令行中,使用您的 AWS 配置文件在账户中担任角色,然后将生成的令牌存储在环境变量中。现在,当您执行脚本时,它会自动使用这些标记:

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 }'`
export AWS_SECRET_ACCESS_KEY=`echo ${credentials} | awk '{print }'`
export AWS_SECURITY_TOKEN=`echo ${credentials} | awk '{print }'`
export AWS_DEFAULT_REGION=<AWS_REGION>

python <path_to_your_python_script>

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

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

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 用于担任角色,并且任何后续工作都通过该角色执行,因为会话是使用假定创建的角色。

AWS_PROFILE=<YOUR_CREDENTIALS_PROFILE_NAME> python <PATH_TO_SCRIPT>

希望对您有所帮助!