当我这样做时:
session1 = boto3.session.Session(profile_name='my_profile')
iam_client = session1.client('iam')
给定user='an_existin_iam_user'
,以下操作成功,因为我可以成功打印accessKeyId和accessKeySecret。
responseCreateAccessKey = iam_client.create_access_key(UserName=user)
accessKeyId = responseCreateAccessKey.get('AccessKey').get('AccessKeyId')
accessKeySecret = responseCreateAccessKey.get('AccessKey').get('SecretAccessKey')
因此,我可以使用iam_client为其他用户创建访问凭据(假设my_profile AWS配置文件持有管理员iam用户的凭据)
现在,使用上面新创建的凭据,我想创建一个新的IAM用户。以下是我试图实现的目标:
尝试1
temp_session = boto3.Session(aws_access_key_id=accessKeyId,aws_secret_access_key=accessKeySecret,region_name='ap-southeast-1')
temp_iam_client = temp_session.client('iam')
responseCreateUser = temp_iam_client.create_user(UserName='my-new-user')
尝试2
temp_iam_client = boto3.client('iam',aws_access_key_id=accessKeyId,aws_secret_access_key=accessKeySecret,region_name='ap-southeast-1')
responseCreateUser = temp_iam_client.create_user(UserName='my-new-user')
尝试3
temp_session = boto3.session.Session(aws_access_key_id=accessKeyId,aws_secret_access_key=accessKeySecret,region_name='ap-southeast-1')
temp_iam_client = temp_session.client('iam')
responseCreateUser = temp_iam_client.create_user(UserName='my-new-user')
尝试4(下面的一个答案中也有建议)
temp_session = boto3.session.Session(aws_access_key_id=accessKeyId,aws_secret_access_key=accessKeySecret,region_name='ap-southeast-1')
temp_iam_client = temp_session.client('iam')
time.sleep(5)
responseCreateUser = temp_iam_client.create_user(UserName='my-new-user')
以上每一项都失败,并出现以下错误
调用CreateUser操作时发生错误(InvalidClientTokenId):请求中包含的安全令牌无效。
我这里缺少什么吗?我所要做的就是创建一个新用户,使用(如上所示)新生成的访问凭据(accesskey和access secret)。如果我得到一个AccessDenied
异常,那没关系。我期待那些没有正确权限的用户。但InvalidClientTokenId
异常是我不明白为什么我会得到它。
此外,如果有帮助的话,我将尝试在100多个用户的迭代循环中完成这项工作(创建访问密钥和机密,然后使用它创建新用户)。(当然,循环处理当前正在处理的用户的访问密钥已经达到最大值的情况等)例如,如果我尝试从ipython控制台单独为用户(比如existing-test-user
)执行上述用户创建操作,那么我会得到正确的AccessDenied
异常。然而,当循环到达该用户名时(例如,在迭代最初的几个用户之后),我会得到InvalidClientTokenId
异常。
关于get_credentials()
部分的另一个注意事项,我只是想知道它是否与凭据缓存有关?
AWS IAM API采用最终一致的模型,因此在IAM资源更新期间(例如创建访问密钥)会发生延迟。这意味着,即使创建AWS访问密钥的函数调用成功,也不一定意味着AWS访问密钥已立即在AWS服务器上完成创建。https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_eventual-一致性
新答案
使用回退,我们可以设置一个重试策略,用于在超时时使用新创建的AWS访问密钥创建IAM用户:
import boto3
import botocore
import backoff
@backoff.on_exception(backoff.expo, botocore.exceptions.ClientError, max_time=30)
def create_user(access_key_id, access_key_secret, username):
temp_session = boto3.Session(aws_access_key_id=access_key_id,aws_secret_access_key=access_key_secret,region_name='ap-southeast-1')
temp_iam_client = temp_session.client('iam')
temp_iam_client.create_user(UserName=username)
session = boto3.session.Session(profile_name='default')
iam_client = session.client('iam')
response_access_key = iam_client.create_access_key(UserName='user')
access_key_id = response_access_key.get('AccessKey').get('AccessKeyId')
access_key_secret = response_access_key.get('AccessKey').get('SecretAccessKey')
create_user(access_key_id, access_key_secret, 'my-new-user')
老答案
在创建AWS访问密钥后添加睡眠是一种解决方法。
import boto3
import time
session1 = boto3.session.Session(profile_name='my_profile')
iam_client = session1.client('iam')
responseCreateAccessKey = iam_client.create_access_key(UserName=user)
accessKeyId = responseCreateAccessKey.get('AccessKey').get('AccessKeyId')
accessKeySecret = responseCreateAccessKey.get('AccessKey').get('SecretAccessKey')
time.sleep(10)
temp_session = boto3.Session(aws_access_key_id=accessKeyId,aws_secret_access_key=accessKeySecret,region_name='ap-southeast-1')
temp_iam_client = temp_session.client('iam')
responseCreateUser = temp_iam_client.create_user(UserName='my-new-user')