我在这里做错了什么?如果我使用的话,我可以通过aws cli以及boto来承担角色:
boto3.setup_default_session(profile_name="ROLE_TO_ASSUME")
我尝试做的事情:我的脚本需要运行多个AWS账户。每次我需要在不同的配置文件上运行脚本时,我已经厌倦了输入我的mfa角色。
我收到以下代码的错误消息:
User: arn:aws:iam::<management account>:user/Ops/<my user> is not authorized to perform: sts:AssumeRole on resource
我们的AWS设置如下: 我是用户,是管理帐户组的一部分。该组具有在每个帐户上设置了ROLE_TO_ASSUME角色的信任关系。
这是我的蟒蛇:
import boto3
def main():
boto3.setup_default_session(profile_name="default")
ec2 = boto3.client('ec2')
get_assumerole_credentials('arn:aws:iam::<REPLACE WITH ACCOUNTID>:role/ROLE_TO_ASSUME')
def get_assumerole_credentials(arn):
sts_client = boto3.client('sts')
# Use client object and pass the role ARN
assumedRoleObject = sts_client.assume_role(RoleArn=arn,
RoleSessionName="AssumeRoleCredstashSession1")
credentials = assumedRoleObject['Credentials']
return dict(aws_access_key_id=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken'])
if __name__ == "__main__":
main()
这是我的〜/ .aws / config
[profile default]
region = us-west-2
output = json
aws_access_key_id=<censored>
aws_secret_access_key=<censored>
[profile ROLE_TO_ASSUME]
region = us-west-2
source_profile = default
role_arn = arn:aws:iam::<accountid>:role/ROLE_TO_ASSUME
mfa_serial = arn:aws:iam::<accountid>:mfa/<my_user>
根据第一回复编辑:
要明确的是,如果我指定了&#39;个人资料,我可以担任一个角色。参数如下例所示:
boto3.setup_default_session(profile_name='ROLE_TO_ASSUME')
ec2 = boto3.resource('ec2', region_name='us-west-1')
但是我需要在脚本中使用boto3的STS来获取角色,以获得临时证书。
当我使用boto3 STS假设角色连接方法时,我注意到没有MFA提示。
答案 0 :(得分:2)
此处所有其他解决方案均不刷新假定的凭证。但是它们确实会过期(默认情况下为15分钟,但是您可以在执行AssumeRole调用时将其设置为更长,直到当前会话的最大API会话持续时间,默认为1小时)。
如果您需要自动刷新凭据,在这里我分享了我在学习boto的代码并尝试解决boto对文件系统和配置文件的依赖性几个小时之后编写的代码。
在这里,我只是使用了内置的boto缓存机制,并定期刷新假定的凭据,而无需接触任何文件:
from datetime import datetime
import boto3
from botocore.credentials import (
AssumeRoleProvider,
AssumeRoleCredentialFetcher,
DeferredRefreshableCredentials,
CredentialResolver
)
from dateutil.tz import tzlocal
class RamAssumeRoleProvider(AssumeRoleProvider):
"""
Overrides default AssumeRoleProvider to not use profiles from filesystem.
"""
def __init__(self,
source_session: boto3.Session,
assume_role_arn: str,
expiry_window_seconds: int):
super().__init__(
load_config=lambda: source_session._session.full_config,
client_creator=source_session._session.create_client,
cache={},
profile_name='not-used'
)
self.expiry_window_seconds = expiry_window_seconds
self.source_session = source_session
self.assume_role_arn = assume_role_arn
assert assume_role_arn, "assume_role_arn is required"
def load(self):
fetcher = AssumeRoleCredentialFetcher(
client_creator=self.source_session._session.create_client,
source_credentials=self.source_session.get_credentials(),
role_arn=self.assume_role_arn,
expiry_window_seconds=self.expiry_window_seconds,
cache=self.cache,
)
return DeferredRefreshableCredentials(
method=self.METHOD,
refresh_using=fetcher.fetch_credentials,
time_fetcher=lambda: datetime.now(tzlocal())
)
def get_assume_role_session(
source_session: boto3.Session,
assume_role_arn: str,
expiry_window_seconds=15 * 60
) -> boto3.Session:
"""
Creates a new boto3 session that will operate as of another user.
Source session must have permission to call sts:AssumeRole on the provided ARN,
and that ARN role must have been trusted to be assumed from this account (where source_session is from).
See https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html
Uses internal session._session to hack it together, as I haven't found another way.
"""
# must have .load() method to be used in CredentialsResolver.
provider = RamAssumeRoleProvider(
source_session=source_session,
assume_role_arn=assume_role_arn,
expiry_window_seconds=expiry_window_seconds
)
# must have .load_credentials() method to be used in register_component()
resolver = CredentialResolver([provider])
new_session = boto3.Session()
new_session._session.register_component('credential_provider', resolver)
return new_session
答案 1 :(得分:1)
我认为以下内容适合您
boto3.setup_default_session(profile_name='ROLE_TO_ASSUME')
ec2 = boto3.resource('ec2', region_name='us-west-1')
因此,要获得STS临时凭证,请执行以下操作
boto3.setup_default_session(profile_name='ROLE_TO_ASSUME')
session = boto3.session.Session()
temp_credentials = session.get_credentials().get_frozen_credentials()
注意:如果第一个假设工作正常,这与MFA无关。
如果您正在寻找MFA的假定角色,请参阅假设MFA角色 http://boto3.readthedocs.io/en/latest/reference/services/sts.html#STS.Client.assume_role
答案 2 :(得分:1)
import boto3
# Prompt for MFA time-based one-time password (TOTP)
mfa_TOTP = raw_input("Enter the MFA code: ")
def role_arn_to_session(**args):
"""
Usage :
session = role_arn_to_session(
RoleArn='arn:aws:iam::<ACCOUNT_NUMBER>:role/example-role',
RoleSessionName=<'SESSION_NAME'>,
SerialNumber='<ARN_OF_MFA_DEVICE',
TokenCode=mfa_TOTP)
client = session.client('ec2')
"""
client = boto3.client('ec2')
response = client.assume_role(**args)
return boto3.Session(
aws_access_key_id=response['Credentials']['AccessKeyId'],
aws_secret_access_key=response['Credentials']['SecretAccessKey'],
aws_session_token=response['Credentials']['SessionToken'])
答案 3 :(得分:0)
我认为如果我们需要承担角色-这就是我所做的,它会自动承担角色。步骤(Windows / Unix):
在目录中,创建一个名为凭据的文件名(不带扩展名) 在凭据中,输入
[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
在同一目录.aws中,创建一个名为config的文件名(不带扩展名)并输入以下信息
[default]
region=us-west-2
role_arn=arn:aws:iam::
source_profile=default
import boto3
client = boto3.client('s3')
boto3会在这些默认位置查找凭据/配置文件,并在其中拾取所有访问/角色信息。
答案 4 :(得分:0)
import boto3
mfa=raw_input()
hours_required=2
device_id=<arn of mfa device>
sts_client=boto3.client('sts')
credentials=sts_client.get_session_token(DurationSeconds=hours_required*60*60,SerialNumber=device_id,TokenCode=mfa)
session=boto3.session.Session(
aws_access_key_id=credentials['Credentials']['AccessKeyId'],
aws_secret_access_key=credentials['Credentials']['SecretAccessKey'],
aws_session_token=credentials['Credentials']['SessionToken']
)
现在您可以使用会话变量并使用它来创建sts客户端,并在该对象上调用承担角色。