I have a Go service that needs to connect Keyspaces on AWS. My pod has a role and AWS_SECRET_ACCESS_KEY
, AWS_ACCESS_KEY_ID
and AWS_SESSION_TOKEN
env vars.
I want to use aws SDK v2. What credential provider should I use? ec2rolecreds
or other one (maybe stscreds
)?
I tried to implement example from here. But I get an error
no EC2 IMDS role found, operation error ec2imds: GetMetadata, request canceled, context deadline exceeded
Where can I find working example and more explanations?
UPDATE
Now my code looks like this:
awsCfg, err := awsConfig.LoadDefaultConfig(ctx)
if err != nil {
return nil, fmt.Errorf("failed to load AWS config: %w", err)
}
imdsClient := imds.NewFromConfig(awsCfg)
appCreds := aws.NewCredentialsCache(ec2rolecreds.New(func(options *ec2rolecreds.Options) {
options.Client = imdsClient
}))
cluster := gocql.NewCluster(cassandraHost)
auth := sigv4.NewAwsAuthenticator()
auth.SessionToken = value.SessionToken
auth.AccessKeyId = value.AccessKeyID
auth.SecretAccessKey = value.SecretAccessKey
cluster.Authenticator = auth
session, err := cluster.CreateSession()
Retrieve()
returns an error
no EC2 IMDS role found, operation error ec2imds: GetMetadata, exceeded maximum number of attempts, 3, request send failed, Get \"http://169.254.169.254/latest/meta-data/iam/security-credentials/\": dial tcp 169.254.169.254:80: connect: host is down
UPDATE 2
In the same environment AWS SDK v1 works ok. So physically AWS endpoint is available.
session, err := aws_sess.NewSession()
if err != nil {
return fmt.Errorf("failed to create AWS session: %w", err)
}
creds := credentialsV1.NewChainCredentials(
[]credentialsV1.Provider{
&credentialsV1.EnvProvider{},
&ec2rolecredsV1.EC2RoleProvider{
Client: ec2metadataV1.New(session),
}})
value, getErr := creds.Get()
CodePudding user response:
no EC2 IMDS role found, operation error ec2imds: GetMetadata, exceeded maximum number of attempts, 3, request send failed, Get \"http://169.254.169.254/latest/meta-data/iam/security-credentials/\": dial tcp 169.254.169.254:80: connect: host is down
Your snippet of code is attempting to use the EC2 instance meta-data service to read an IAM role to use. For that to work, you need to be able to communicate with it, and the role must be attached to the instance.
Is your Go service running on an EC2 instance? If not, that would explain your error. If it is, make sure the process or container has appropriate network access (eg: network namespace) to communicate with 169.254.169.254.