- creds := aws.NewChainProvider(
- []aws.CredentialsProvider{
- aws.NewStaticCredentialsProvider(v.AccessKeyID, v.SecretAccessKey, v.AuthToken),
- ec2rolecreds.New(ec2metadata.New(cfg)),
- })
-
- cfg.Credentials = creds
+ cfg, err := config.LoadDefaultConfig(context.TODO(),
+ config.WithRegion(v.Region),
+ config.WithCredentialsCacheOptions(func(o *aws.CredentialsCacheOptions) {
+ // (from aws-sdk-go-v2 comments) "allow the
+ // credentials to trigger refreshing prior to
+ // the credentials actually expiring. This is
+ // beneficial so race conditions with expiring
+ // credentials do not cause request to fail
+ // unexpectedly due to ExpiredTokenException
+ // exceptions."
+ //
+ // (from
+ // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)
+ // "We make new credentials available at least
+ // five minutes before the expiration of the
+ // old credentials."
+ o.ExpiryWindow = 5 * time.Minute
+ }),
+ func(o *config.LoadOptions) error {
+ if v.AccessKeyID == "" && v.SecretAccessKey == "" {
+ // Use default sdk behavior (IAM / IMDS)
+ return nil
+ }
+ v.logger.Debug("using static credentials")
+ o.Credentials = credentials.StaticCredentialsProvider{
+ Value: aws.Credentials{
+ AccessKeyID: v.AccessKeyID,
+ SecretAccessKey: v.SecretAccessKey,
+ Source: "Arvados configuration",
+ },
+ }
+ return nil
+ },
+ func(o *config.LoadOptions) error {
+ if ec2metadataHostname != "" {
+ o.EC2IMDSEndpoint = ec2metadataHostname
+ }
+ if v.overrideEndpoint != nil {
+ o.EndpointResolverWithOptions = aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
+ if service == "S3" {
+ return *v.overrideEndpoint, nil
+ }
+ return aws.Endpoint{}, errEndpointNotOverridden // use default resolver
+ })
+ }
+ return nil
+ },
+ )
+ if err != nil {
+ return fmt.Errorf("error loading aws client config: %w", err)
+ }