How to authenticate gocql to AWS

Issue

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()

Solution

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.

Answered By – sbrichards

Answer Checked By – Marilyn (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.