会话已创建,但 boto 客户端未使用

Session created, but not used by boto client

我有以下代码,它允许我在 ~/.aws/config 中列出我所有帐户中所有资源的信息:

#!/bin/bash

#Output file
OUTFILE="out.txt"

###############################################################################################
#EXECUTION SECTION - Shouldn't have to change anything below this line.
###############################################################################################

rm -f $OUTFILE

for AWS_PROFILE in `grep '\[profile ' ~/.aws/config | awk {'print '} | sed 's/\]//g'`; do
    echo "====================================================================" >> $OUTFILE
    echo "!!==> $AWS_PROFILE " | tee -a $OUTFILE
echo "!!==> $AWS_PROFILE " | tee -a $OUTFILE
    for region in `aws --profile $AWS_PROFILE ec2 describe-regions --all-regions --query 'Regions[].RegionName' --output text`
    do
        echo "region = ${region}" >> $OUTFILE
        aws --profile $AWS_PROFILE resourcegroupstaggingapi get-resources --region ${region} --query 'ResourceTagMappingList[].ResourceARN' >> $OUTFILE
    done
done

同样,这有效;它在查询每个帐户时提示我输入 MFA 令牌,我至少有没有错误的原始输出。

我需要将其移植到 python,以实现可扩展性,与我们的代码库的其余部分保持一致。我从以下内容开始:

#!env python3.9

from pprint import pprint

import boto3
import boto, boto3
from boto.sts import STSConnection
from botocore.exceptions import ClientError

role_arn =  'arn:aws:iam::account-number-removed:role/role-name-here'

# Prompt for MFA time-based one-time password (TOTP)
mfa_TOTP = input("Enter the MFA code: ")

sts_connection = STSConnection()

tempCredentials = sts_connection.assume_role(
    role_arn=role_arn,
    role_session_name="AssumeRoleSession1",
    mfa_serial_number="arn:aws:iam::account-number-of-bastion-account-here::mfa/my-email-here",
    mfa_token=mfa_TOTP
)

assumed_role_session = boto3.Session(
    aws_access_key_id=tempCredentials.credentials.access_key,
    aws_secret_access_key=tempCredentials.credentials.secret_key,
    aws_session_token=tempCredentials.credentials.session_token
)

print(assumed_role_session.client("sts").get_caller_identity())
client = boto3.client('resourcegroupstaggingapi', )

regions = assumed_role_session.get_available_regions('ec2')

for region in regions:
    print(region)
    try:
        client = boto3.client('resourcegroupstaggingapi', region_name=region)
        pprint([x.get('ResourceARN') for x in client.get_resources().get('ResourceTagMappingList')])
    except ClientError as e:
        print(f'Could not connect to region with error: {e}')
    print()

当我 运行 它时,脚本启动并按预期获取会话。敏感信息已删除。

➜  aws git:(master) ✗ ./list-resources.py
Enter the MFA code: removed
{'UserId': 'alphanumeric-characters-here:AssumeRoleSession1', 'Account': 'account-number-removed', 'Arn': 'arn:aws:sts::account-number-removed:assumed-role/role-name-here/AssumeRoleSession1', 'ResponseMetadata': {'RequestId': 'id-here', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'id-here', 'content-type': 'text/xml', 'content-length': '451', 'date': 'Thu, 06 Jan 2022 19:48:11 GMT'}, 'RetryAttempts': 0}}

但是,当它遍历区域并尝试列出资源时,它会出错,这似乎是因为它仍在使用初始帐户中的令牌,而不是代入角色会话中的令牌。此外,它列出的资源是针对堡垒帐户的,而不是假定角色的帐户。

af-south-1
Could not connect to region with error: An error occurred (UnrecognizedClientException) when calling the GetResources operation: The security token included in the request is invalid.

ap-east-1
Could not connect to region with error: An error occurred (UnrecognizedClientException) when calling the GetResources operation: The security token included in the request is invalid.

ap-northeast-1
[]

...
us-east-1
['arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblah-development_users-ReadCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblahUsers-sk-data-index-WriteCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:Users-WriteCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblahUsers-ReadCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblahUsers-sk-gsiSk-index-ReadCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblahUsers-sk-data-index-ReadCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblahUsers-sk-gsiSk-index-WriteCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblah_development_clinton_test-ReadCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblah-development_users-WriteCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblah_development_clinton_test-WriteCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblah-development_users-sk-index-ReadCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:Users-ReadCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblah-development_users-sk-index-WriteCapacityUnitsLimit-BasicAlarm',
 'arn:aws:cloudwatch:us-east-1:account-number-of-bastion-account-here:alarm:blahblahUsers-WriteCapacityUnitsLimit-BasicAlarm']
....
us-west-2
['arn:aws:networkmanager::account-number-of-bastion-account-here:global-network/global-network-alphanumeric-values-removed']

请注意,我阅读了 ,我认为我不需要在此处汇总数据;事实上,可能是想把他们留在他们的地区。

用于查询资源的 boto3 客户端似乎没有获得与假定角色相同的凭据(令牌等)。关于如何做到这一点有什么想法吗?

需要在 assume_role_session 上创建 'resourcegroupstaggingapi' 客户端,而不是默认的 boto3 会话:

client = assumed_role_session.client('resourcegroupstaggingapi', region_name=region)

(请注意,您有一个重复的 client = boto3.client('resourcegroupstaggingapi', ...,应该删除第一个)