6

Here is what I am trying to do. I have 2 AWS Accounts A and B. Using AWS SDK for Go v2 I want to use a CLI profile with credentials for Acct A and assume a role in Account B that requires MFA.

I have read through the package docs for config and stscreds https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/stscreds. It is so confusing host of issues (compile errors). I tried https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/[email protected]/stscreds as well as you see in the code, however the line below errors.

cfg.Credentials = &aws.CredentialsCache{Provider: creds} 

ERROR: unknown field 'Provider' in struct literal of type aws.CredentialsCache

Here is what I have so far.

 package main import ( "context" "log" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials/stscreds" "github.com/aws/aws-sdk-go-v2/service/sts" ) func main() { region := "us-west-2" profile := "acctacliprofile" roleToAssume := "arn:aws:iam::accountB:role/TestRole" externalID := "TestingOnly" mfaSerial := "arn:aws:iam::acctA:mfa/user" ctx := context.TODO() cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region), config.WithSharedConfigProfile(profile)) if err != nil { log.Fatal(err) } creds := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), roleToAssume, func(o *stscreds.AssumeRoleOptions) { o.SerialNumber = aws.String(mfaSerial) o.ExternalID = aws.String(externalID) o.TokenProvider = stscreds.StdinTokenProvider }) c, err := creds.Retrieve(ctx) if err != nil { log.Fatal(err) } log.Printf("%T\n", c) log.Printf("%v\n", c.AccessKeyID) log.Printf("%v\n", c.SecretAccessKey) log.Printf("%v\n", c.SessionToken) } 

This basically works, asks to provide the MFA token and assume role succeeds but how do I use these credentials to create service clients etc since cfg was created with the local cli profile, and I want to use the temporary credentials to make the service calls.

Since the code below from docs fail, how do I update cfg with the new credentials and make the s3 or other service calls with creds.

cfg.Credentials = &aws.CredentialsCache{Provider: creds} // Create service client value configured for credentials // from assumed role. svc := s3.NewFromConfig(cfg) 

Wish the docs for the new AWS Go SDK v2 didn't leave a lot to be desired.

Thanks for any help.

1 Answer 1

6

Code that finally works using Go SDK v2

go version go1.15.11 darwin/amd64 

go.mod

module stsassumerolemfav2 go 1.15 require ( github.com/aws/aws-sdk-go-v2 v1.5.0 github.com/aws/aws-sdk-go-v2/config v1.2.0 github.com/aws/aws-sdk-go-v2/credentials v1.2.0 github.com/aws/aws-sdk-go-v2/service/sns v1.4.0 github.com/aws/aws-sdk-go-v2/service/sts v1.4.0 ) 

main.go

import ( "context" "log" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials/stscreds" "github.com/aws/aws-sdk-go-v2/service/sns" "github.com/aws/aws-sdk-go-v2/service/sts" ) func main(){ region := "region" //add region profile := "cli-profile" //add cli profile account A roleToAssume := "arn:aws:iam::acctB:role/TestRole" externalID := "TestingOnly" mfaSerial := "arn:aws:iam::acctA:mfa/usermfadevice" ctx := context.TODO() cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region), config.WithSharedConfigProfile(profile)) if err != nil { log.Fatal(err) } // Create the credentials from AssumeRoleProvider to assume the role // referenced by the "myRoleARN" ARN using the MFA token code provided. creds := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), roleToAssume, func(o *stscreds.AssumeRoleOptions) { o.SerialNumber = aws.String(mfaSerial) o.ExternalID = aws.String(externalID) o.TokenProvider = stscreds.StdinTokenProvider }) cfg.Credentials = aws.NewCredentialsCache(creds) // Create service client value configured for credentials from assumed role. //Note: Not checking NextToken since test results are small dataset and do not need pagination. snsclient := sns.NewFromConfig(cfg) lti := &sns.ListTopicsInput{} lto, err := snsclient.ListTopics(ctx, lti) if err != nil { log.Println(err) } if lto != nil { for _, t := range lto.Topics { log.Println(*t.TopicArn) } } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.