Sergei Basharov
Sergei Basharov

Reputation: 53830

How to run AWS SDK with credentials from variables?

I used environment variables before and it worked fine.

Now I am migrating my config variables into a single file and I have AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID variables containing respective values that are loaded from this file.

I tried this code but receiving an error:

creds := credentials.NewStaticCredentials("123", conf.AWS_SECRET_ACCESS_KEY, conf.AWS_ACCESS_KEY_ID)
sess, err := session.NewSession(&aws.Config{Credentials: creds})

Here is the error

InvalidClientTokenId: The security token included in the request is invalid.

How do I properly inject my keys into the aws sdk calls?

Upvotes: 23

Views: 27414

Answers (7)

Arnab_Ghosh
Arnab_Ghosh

Reputation: 319

I was running SNS in my local with localstack, and while publishing messages to the topic I kept getting this error: Failed to publish message to SNS: InvalidClientTokenId: The security token included in the request is invalid.

According to the first answer I updated my code to this:

sess, err := session.NewSession(&aws.Config{
        Region:      aws.String(awsRegion),
        Credentials: credentials.NewStaticCredentials(awsAccessKeyId, awsSecretAccessKey, ""),
    })

snsClient := sns.New(sess)

I made sure the values were correct (based on the AWS Profile) I'm using, and AWS_SNS_TOPIC_ARN value is correct, still no use.

Finally I tweaked the session code to:

sess, err := session.NewSession(&aws.Config{
        Region:      aws.String(awsRegion),
        Credentials: credentials.NewStaticCredentials(awsAccessKeyId, awsSecretAccessKey, ""),

        Endpoint:   aws.String(snsEndpoint),  //"http://localhost:4566" in my case
        DisableSSL: aws.Bool(true),
    })

And voila! it worked.

Few Tips from ChatGPT,

  1. LocalStack typically runs over HTTP. Ensure that SSL is disabled in the AWS SDK configuration.
  2. By default, the AWS SDK tries to connect to the actual AWS endpoints. To interact with LocalStack, you need to explicitly set the endpoint to point to your LocalStack instance.

Upvotes: 0

Rui Eusebio
Rui Eusebio

Reputation: 161

Hi you have the option to utilize your configurations within an aws.Credentials struct, as demonstrated in the code snippet below.

package services

import (
    "context"
    "fmt"
    "ldapmng/config"
    "time"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/credentials"
    "github.com/aws/aws-sdk-go-v2/service/directoryservice"
)

type AwsService struct {
    Ds *directoryservice.Client
}

func NewAwsService(ctx context.Context) (*AwsService, error) {

    awsService := &AwsService{}

    settings, _ := config.LoadSettings()

    awsSessionExpiration, err := time.Parse("2006-01-02T15:04:05-07:00", settings.AwsSessionExpiration)

    creds := aws.Credentials{
        AccessKeyID:     settings.AwsAccessKeyId,
        SecretAccessKey: settings.AwsSecretAccessKey,
        SessionToken:    settings.AwsSessionToken,
        // Source:          ,
        // CanExpire:       false,
        Expires: awsSessionExpiration,
    }

    credsProvider := credentials.StaticCredentialsProvider{
        Value: creds,
    }

    cfg := aws.Config{
        Region:      settings.AwsRegion,
        Credentials: credsProvider,
    }

    if err != nil {
        fmt.Println("Error loading AWS configuration:", err)
        return nil, err
    }

    awsService.Ds = directoryservice.NewFromConfig(cfg)

    return awsService, nil
}

Upvotes: 0

RaminNietzsche
RaminNietzsche

Reputation: 2791

You can pass the creds variable to the aws.Config struct to set the AWS credentials for the S3 session.

You need to import the github.com/aws/aws-sdk-go/aws/credentials package.

package main

import (
    "fmt"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/credentials"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

func main() {
    accessKey := "ACCESS"
    secretKey := "SECRET"
    creds := credentials.NewStaticCredentials(accessKey, secretKey, "")

    sess, err := session.NewSession(&aws.Config{
        Credentials: creds,
        Endpoint:    aws.String("ENDPOINT"),
        Region:      aws.String("REGION"),
    })
    if err != nil {
        panic(err)
    }

    svc := s3.New(sess)

    bucketName := "ramingotestsdk"

    _, err = svc.CreateBucket(&s3.CreateBucketInput{
        Bucket: aws.String(bucketName),
    })
    if err != nil {
        panic(err)
    }

    fmt.Printf("Bucket %s created\n", bucketName)
}

OUTPUT:

Bucket ramingotestsdk created

Upvotes: 0

Deep Nirmal
Deep Nirmal

Reputation: 1251

Connect your sdk client using this generic service

var awsSession *session.Session

func init() {
    initializeAwsSession()
}


func initializeAwsSession() {
    awsSession = session.Must(session.NewSession(&aws.Config{
        Region:      aws.String("ap-southeast-1"),
        Credentials: credentials.NewStaticCredentials("YOUR_ACCESS_KEY","YOUR SECRET_KEY", ""),
    }))
}

Upvotes: -1

Dave Maple
Dave Maple

Reputation: 8402

Try re-ordering your args so that ACCESS_KEY is the 1st param and SECRET_KEY is the second:

creds := credentials.NewStaticCredentials(conf.AWS_ACCESS_KEY_ID, conf.AWS_SECRET_ACCESS_KEY, "")

Try adding the region as well:

sess, err := session.NewSession(&aws.Config{
    Region:      aws.String("us-west-2"),
    Credentials: credentials.NewStaticCredentials(conf.AWS_ACCESS_KEY_ID, conf.AWS_SECRET_ACCESS_KEY, ""),
})

Upvotes: 46

greenif
greenif

Reputation: 1093

Or you can just temporaly set Environment variables.

package main
import (
    "fmt"
    "os"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3/s3manager"
)

const (
    AccessKeyId     = "XXXXXXXXXXXXXXXXXX"
    SecretAccessKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    Region          = "eu-west-1"
    Bucket          = "XXXXX-XXXX-XXX"
)

func main() {
    os.Setenv("AWS_ACCESS_KEY_ID",     AccessKeyId)
    os.Setenv("AWS_SECRET_ACCESS_KEY", SecretAccessKey)

    filename := os.Args[1]

    file, err := os.Open(filename)
    if err != nil {
        fmt.Println("Failed to open file", filename, err)
        os.Exit(1)
    }
    defer file.Close()

    conf := aws.Config{Region: aws.String(Region)}
    sess := session.New(&conf)

    svc := s3manager.NewUploader(sess)

    fmt.Println("Uploading file to S3...")
    result, err := svc.Upload(&s3manager.UploadInput{
        Bucket: aws.String(Bucket),
        Key:    aws.String(filepath.Base(filename)),
        Body:   file,
    })
    if err != nil {
        fmt.Println("error", err)
        os.Exit(1)
    }
}

Upvotes: 7

Xibz
Xibz

Reputation: 366

Additionally, if you hadn't known, the SDK allows for the use of the shared config under .aws/config. You can put your values in there and then set the environment variable AWS_SDK_LOAD_CONFIG to a truthy value to load the shared config. An example shared config would look like this:

[default]
aws_access_key_id = AKID
aws_secret_access_key = SECRET

Then running:

AWS_SDK_LOAD_CONFIG=true go run main.go

Upvotes: 5

Related Questions