为了账号安全,请及时绑定邮箱和手机立即绑定

使用 AWS SDK Go 从 Fargate 任务中的角色加载 AWS 凭证的正确方法是什么?

使用 AWS SDK Go 从 Fargate 任务中的角色加载 AWS 凭证的正确方法是什么?

Go
慕妹3146593 2022-07-04 10:39:21
我有以下片段:awsCredentials := credentials.NewChainCredentials(    []credentials.Provider{        &ec2rolecreds.EC2RoleProvider{            Client: ec2metadata.New(newSession, aws.NewConfig()),        },        &credentials.SharedCredentialsProvider{},        &credentials.EnvProvider{},    })只要代码在 EC2 实例上运行或访问/密钥通过变量传递(用于本地测试),它就可以正常工作。但是,此代码在 ECS+Fargate 上运行时会失败,因为NoCredentialProviders: no valid providers in chain. 检查正在运行的容器的环境变量,它有预期的AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,所以credentials.EnvProvider应该阅读它。所以,我的问题是,阅读这些凭证的正确方法是什么?因为我面临的问题不是缺少权限(这将表明策略/角色中的错误),而是该代码无法获取凭据。更新我已将其范围缩小到使用ec2rolescreds.使用这个简单的例子:package mainimport (    "fmt"    "log"    "github.com/aws/aws-sdk-go/aws"    "github.com/aws/aws-sdk-go/aws/credentials"    "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"    "github.com/aws/aws-sdk-go/aws/ec2metadata"    "github.com/aws/aws-sdk-go/aws/session"    "github.com/aws/aws-sdk-go/service/s3")func main() {    newSession, err := session.NewSession()    if err != nil {        log.Fatal(err)    }    awsCredentials := credentials.NewChainCredentials(        []credentials.Provider{            &ec2rolecreds.EC2RoleProvider{                Client: ec2metadata.New(newSession, aws.NewConfig()),            },            &credentials.SharedCredentialsProvider{},            &credentials.EnvProvider{},        })    sess, err := session.NewSession(&aws.Config{        Region:      aws.String("us-east-1"),        Credentials: awsCredentials},    )    if err != nil {        log.Fatal(err)    }    // Create S3 service client    svc := s3.New(sess)    result, err := svc.ListBuckets(nil)    if err != nil {        log.Fatal(err)    }    fmt.Println("Buckets:")    for _, b := range result.Buckets {        fmt.Printf("* %s created on %s\n",            aws.StringValue(b.Name), aws.TimeValue(b.CreationDate))    }}如果我删除ec2rolescreds,则本地和 ECS+Fargate 中的一切都正常。但是,如果我按原样运行此代码,我会得到相同的错误NoCredentialProviders: no valid providers in chain
查看完整描述

2 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

因此,可以使用 Config 对象来配置会话。


通读该对象的规格,它对凭据说:


// The credentials object to use when signing requests. Defaults to a

// chain of credential providers to search for credentials in environment

// variables, shared credential file, and EC2 Instance Roles.

Credentials *credentials.Credentials

默认值已经是我的代码片段所做的,所以我删除了所有awsCredentials块,现在它在任何地方都可以正常工作。在本地,EC2、Fargate...


更新


为了扩大答案,删除awsCredentials使这项工作的原因是,如果您检查 SDK 的代码,https://github.com/aws/aws-sdk-go/blob/master/aws/defaults/defaults.go #L107,默认凭据同时检查EnvProvider和RemoteCredProvider。


通过覆盖默认链凭据,它无法在 中查找凭据RemoteCredProvider,这是处理环境变量的提供程序AWS_CONTAINER_CREDENTIALS_FULL_URI。


查看完整回答
反对 回复 2022-07-04
?
Cats萌萌

TA贡献1805条经验 获得超9个赞

解决方案是使用会话而不是凭据来初始化客户端,即:


conf := aws.NewConfig().WithRegion("us-east-1")

sess := session.Must(session.NewSession(conf))


svc := s3.New(sess)

// others:

//   svc := sqs.New(sess)

//   svc := dynamodb.New(sess)

//   ... 

因为,正如@Ay0 指出的那样,默认凭证链已经包含EnvProvider和RemoteCredProvider。


如果您仍然需要凭据,您可以使用:


creds := stscreds.NewCredentials(sess, "myRoleARN")

正如文档指出的那样。请注意,角色的策略必须sts:AssumeRole启用操作。有关更多信息,这里是stscreds.NewCredentials(...)文档


查看完整回答
反对 回复 2022-07-04
  • 2 回答
  • 0 关注
  • 181 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号