03/06/2023 - AWS, GO
Bildiğimiz gibi, bir uygulamanın başka bir hesaptan bir hesaba erişmesi gerekiyorsa, rolü üstlenmesi ve geçici kimlik bilgileri alması gerekir (süresi 15 dakika içinde sona erer ancak otomatik olarak yenilenir). Buna hesaplar arası erişim denir. Kısacası, uygulama X uygulamasında çalışıyor ve Y hesabındaki kaynakları kullanmak istiyor.
Örnek olması açısından, uygulamanın aynı hesap içinden kaynakları (IAM) kullandığı bir örnek de ekleyeceğim. Hesaplar arası erişim için S3 kaynaklarına odaklanacağız.
Aşağıdaki paketleri yükleyin.
go get github.com/aws/aws-sdk-go-v2
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/service/iam
go get github.com/aws/aws-sdk-go-v2/service/s3
go get github.com/aws/aws-sdk-go-v2/service/sts
package aws
import (
"context"
"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"
)
// NewDefaultConfig current credentials for the current account and returns AWS
// config. Credentials do not expire.
func NewDefaultConfig(ctx context.Context) (aws.Config, error) {
return config.LoadDefaultConfig(ctx)
}
// NewCrossAccountConfigWithRole retrieves temporary credentials from the STS
// service for assumed role and returns AWS config for cross-account access. Credentials
// last 15 minutes but get automatically refreshed.
func NewCrossAccountConfigWithRole(ctx context.Context, roleARN string) (aws.Config, error) {
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
return aws.Config{}, err
}
stsClient := sts.NewFromConfig(cfg)
stsCreds := stscreds.NewAssumeRoleProvider(stsClient, roleARN)
cfg.Credentials = aws.NewCredentialsCache(stsCreds)
return cfg, nil
}
package aws
import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/iam"
)
func NewIAMClient(cfg aws.Config) *iam.Client {
return iam.NewFromConfig(cfg)
}
package aws
import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func NewS3Client(cfg aws.Config) *s3.Client {
return s3.NewFromConfig(cfg)
}
package api
import (
"context"
"log"
"net/http"
"github.com/aws/aws-sdk-go-v2/service/iam"
)
// CurrentAccount holds AWS current account dependencies.
type CurrentAccount struct {
IAMClient *iam.Client
}
// IAM fetches IAM groups from the current account.
func (c CurrentAccount) IAM(w http.ResponseWriter, r *http.Request) {
out, err := c.IAMClient.ListGroups(context.Background(), nil)
if err != nil {
log.Fatal(err)
}
for _, group := range out.Groups {
log.Println(*group.GroupName)
}
}
package api
import (
"context"
"log"
"net/http"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
// CrossAccount holds AWS cross-account dependencies.
type CrossAccount struct {
S3Client *s3.Client
}
// S3 fetches S3 bucktes from a cross account.
func (c CrossAccount) S3(w http.ResponseWriter, r *http.Request) {
out, err := c.S3Client.ListBuckets(context.Background(), nil)
if err != nil {
log.Fatal(err)
}
for _, bucket := range out.Buckets {
log.Println(*bucket.Name)
}
}
package main
import (
"aws/api"
"aws/aws"
"context"
"log"
"net/http"
)
func main() {
ctx := context.Background()
currentAccountConfig, err := aws.NewDefaultConfig(ctx)
if err != nil {
log.Fatal(err)
}
crossAccountConfig, err := aws.NewCrossAccountConfigWithRole(ctx, "arn:aws:iam::1234567890:role/services")
if err != nil {
log.Fatal(err)
}
currectAccountAPI := api.CurrentAccount{
IAMClient: aws.NewIAMClient(currentAccountConfig),
}
crossAccountAPI := api.CrossAccount{
S3Client: aws.NewS3Client(crossAccountConfig),
}
httpRouter := http.NewServeMux()
httpRouter.HandleFunc("/iam", currectAccountAPI.IAM)
httpRouter.HandleFunc("/s3", crossAccountAPI.S3)
log.Fatalln(http.ListenAndServe(":1234", httpRouter))
}
İsterseniz bunun yerine normal ortam değişkenlerini kullanabilirsiniz.
[default]
region = eu-west-1
output = json
[default]
aws_access_key_id = QWERTY09876541
aws_secret_access_key = QWERTY1234567890
$ go run -race main.go
$ curl http://localhost:1234/iam
2023/06/03 14:53:39 admins
2023/06/03 14:53:39 devops
2023/06/03 14:53:39 developers
$ curl http://localhost:1234/s3
2023/06/03 14:53:45 inanzzz-development-cvs
2023/06/03 14:53:45 inanzzz-development-images