如何解决使用AWS开发工具包Go从Fargate任务中的角色加载AWS凭证的正确方法是什么?
我有以下代码段:
awsCredentials := credentials.NewChainCredentials(
[]credentials.Provider{
&ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(newSession,aws.NewConfig()),},&credentials.SharedCredentialsProvider{},&credentials.EnvProvider{},})
只要代码在EC2实例上运行或将访问/秘密密钥通过变量传递(用于本地测试),它就可以正常工作。
但是,由于NoCredentialProviders: no valid providers in chain
,此代码在ECS + Fargate上运行时失败。检查了正在运行的容器的环境变量,它具有预期的AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
,因此credentials.EnvProvider
应该读取它。
所以,我的问题是,读取这些凭据的正确方法是什么?因为我面临的问题不是缺少权限(这表明策略/角色错误),而是该代码无法获取凭据。
更新
我将其范围缩小为ec2rolescreds
。
使用以下简单示例:
package main
import (
"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,})
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
相同的错误
解决方法
解决方案是使用会话而不是凭据来初始化客户端,即:
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")
正如 documentation 指出的那样。请注意,角色的策略必须启用 sts:AssumeRole
操作。有关详细信息,请参阅 stscreds.NewCredentials(...)
docs
因此,可以使用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
和{{ 1}}。
通过覆盖默认链凭证,它无法在RemoteCredProvider
中查找凭证,RemoteCredProvider
是处理环境变量AWS_CONTAINER_CREDENTIALS_FULL_URI
的提供者。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。