Use aws-sdk-go-v2/config to load AWS config

Replace the hand-rolled credential chain (static, ECS endpoint, EC2
role) with config.LoadDefaultConfig, which handles the full standard
AWS credential resolution chain automatically.

Co-authored-by: Neil McGibbon <code@neilmcgibbon.com>
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2026-06-06 09:00:04 +02:00
parent 66721d63a8
commit daf139c12d
3 changed files with 30 additions and 52 deletions

8
go.mod
View File

@@ -7,8 +7,8 @@ require (
github.com/99designs/gqlgen v0.17.90
github.com/anthropics/anthropic-sdk-go v1.45.0
github.com/aws/aws-sdk-go-v2 v1.41.7
github.com/aws/aws-sdk-go-v2/config v1.32.14
github.com/aws/aws-sdk-go-v2/credentials v1.19.17
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23
github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.52.0
github.com/aws/aws-sdk-go-v2/service/s3 v1.101.0
github.com/brianvoe/gofakeit/v7 v7.15.0
@@ -57,6 +57,12 @@ require (
github.com/ProtonMail/go-crypto v1.4.1 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect

View File

@@ -16,16 +16,12 @@ package awsconfig
import (
"context"
"fmt"
"net/http"
"net/url"
"os"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go-v2/credentials/endpointcreds"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"go.gearno.de/kit/httpclient"
"go.gearno.de/kit/log"
)
@@ -45,15 +41,11 @@ const (
DefaultSessionName = "go.probo.inc/probo"
)
func NewConfig(logger *log.Logger, httpClient *http.Client, opts Options) aws.Config {
func NewConfig(logger *log.Logger, httpClient *http.Client, opts Options) (aws.Config, error) {
if opts.Region == "" {
opts.Region = DefaultRegion
}
if opts.SessionName == "" {
opts.SessionName = ""
}
logger = logger.Named(
"aws.client",
log.WithAttributes(
@@ -67,52 +59,29 @@ func NewConfig(logger *log.Logger, httpClient *http.Client, opts Options) aws.Co
httpClient = httpclient.DefaultPooledClient(httpclient.WithLogger(logger))
}
cfg := aws.NewConfig()
cfg.HTTPClient = httpClient
cfg.Region = opts.Region
// cfg.Logger = logger TODO: add logger interface for aws
loadOpts := []func(*config.LoadOptions) error{
config.WithRegion(opts.Region),
config.WithHTTPClient(httpClient),
}
if opts.AccessKeyID != "" && opts.SecretAccessKey != "" {
// Use static credentials if provided
cfg.Credentials = credentials.NewStaticCredentialsProvider(
opts.AccessKeyID,
opts.SecretAccessKey,
opts.SessionName,
)
} else {
imdsClient := imds.New(imds.Options{HTTPClient: httpClient})
loadOpts = append(loadOpts, config.WithCredentialsProvider(
credentials.NewStaticCredentialsProvider(
opts.AccessKeyID,
opts.SecretAccessKey,
opts.SessionName,
),
))
}
ec2Provider := ec2rolecreds.New(func(options *ec2rolecreds.Options) {
options.Client = imdsClient
})
ecsCredentialsURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI")
ecsEndpoint, _ := url.JoinPath("http://169.254.170.2", ecsCredentialsURI)
ecsProvider := endpointcreds.New(
ecsEndpoint,
func(options *endpointcreds.Options) {
options.HTTPClient = httpClient
},
)
cfg.Credentials = aws.NewCredentialsCache(
aws.CredentialsProviderFunc(func(ctx context.Context) (aws.Credentials, error) {
creds, err := ecsProvider.Retrieve(ctx)
if err == nil {
return creds, nil
}
return ec2Provider.Retrieve(ctx)
}),
func(o *aws.CredentialsCacheOptions) {
o.ExpiryWindow = 10 * time.Minute
},
)
cfg, err := config.LoadDefaultConfig(context.Background(), loadOpts...)
if err != nil {
return aws.Config{}, fmt.Errorf("cannot load AWS config: %w", err)
}
if opts.Endpoint != "" {
cfg.BaseEndpoint = new(opts.Endpoint)
}
return cfg.Copy()
return cfg, nil
}

View File

@@ -245,7 +245,7 @@ func (impl *Implm) Run(
return fmt.Errorf("cannot get cookie secret bytes: %w", err)
}
awsConfig := awsconfig.NewConfig(
awsConfig, err := awsconfig.NewConfig(
l,
httpclient.DefaultPooledClient(
httpclient.WithLogger(l),
@@ -259,6 +259,9 @@ func (impl *Implm) Run(
Endpoint: impl.cfg.AWS.Endpoint,
},
)
if err != nil {
return fmt.Errorf("cannot initialize AWS config: %w", err)
}
html2pdfConverter := html2pdf.NewConverter(
impl.cfg.ChromeDPAddr,