如何在EMR实例中正确提供spark-redshift的凭据?

时间:2015-11-19 07:33:10

标签: amazon-web-services apache-spark amazon-redshift emr aws-sdk

我们尝试使用spark-redshift项目,遵循提供凭据的第3条建议。即:

  

IAM实例配置文件:如果您在EC2上运行并进行身份验证   S3使用IAM和实例配置文件,然后必须配置   temporary_aws_access_key_id,temporary_aws_secret_access_key和   要指向的temporary_aws_session_token配置属性   通过AWS Security Token Service创建的临时密钥。这些   然后临时密钥将通过LOAD和UNLOAD传递给Redshift   命令。

我们的Spark应用程序正在从EMR集群运行。出于这个目的,我们尝试从此节点的内部实例中获取临时凭证,调用getSessionToken,如下所示:

val stsClient = new AWSSecurityTokenServiceClient(new InstanceProfileCredentialsProvider())        
val getSessionTokenRequest = new GetSessionTokenRequest()
val sessionTokenResult =  stsClient.getSessionToken(getSessionTokenRequest);
val sessionCredentials = sessionTokenResult.getCredentials()

但即使带有403 Access Denied的策略应用于EMR实例的角色,这也会引发sts:getSessionToken

然后我们尝试了以下两种选择。首先,使用AssumeRole政策:

val p = new STSAssumeRoleSessionCredentialsProvider("arn:aws:iam::123456798123:role/My_EMR_Role", "session_name")
val credentials: AWSSessionCredentials = p.getCredentials
val token = credentials.getSessionToken

和第二,从InstanceProfileCredentialsProvider

投射结果
val provider = new InstanceProfileCredentialsProvider()
val credentials: AWSSessionCredentials = provider.getCredentials.asInstanceOf[AWSSessionCredentials]
val token = credentials.getSessionToken

它们都有效,但这是预期的做法吗?在推送结果或添加AssumeRole政策时,是否存在严重错误?

谢谢!

1 个答案:

答案 0 :(得分:1)

GetSessionToken API旨在由IAM用户调用,如其文档中所述:

  

返回AWS账户或IAM用户的一组临时凭证。

在第一个示例中,您使用EMR实例角色调用API,这是一个IAM角色(一些差异在here解释)。在此特定情况下,EMR实例角色凭证是EMR代表您的实例获取的会话凭证。

您的错误的具体措辞是什么?如果是Cannot call GetSessionToken with session credentials,那将证实以上所有内容。

当您将实例角色转换为会话令牌时,它可以正常工作,因为如上所述,假设角色的凭据会话凭据,因此它才有效。

显式调用AssumeRole没有任何问题。这正是EMR服务所做的。将结果转换为会话凭据也没有任何问题,因为它们几乎可以保证成为您用例的会话凭据。