AWS SDK for Go v2 でカスタムエンドポイントを使用 - MinIO へ接続
AWS SDK for Go v2 を使って S3 互換の MinIO へ接続してみました。
今回のサンプルコードは こちら
はじめに
初期化(プロジェクトの作成)を実施します。
> go mod init sample
AWS SDK for Go v2 で S3 を扱うための依存モジュールを追加します。
> 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/s3 ・・・
カスタムエンドポイント
基本的に、AWS SDK for Go v2 では以下のような実装でカスタムエンドポイントを使用できます。
カスタムエンドポイントの適用例
resolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, opts ...interface{}) (aws.Endpoint, error) { return aws.Endpoint{ URL: "http://localhost:9000", // カスタムエンドポイント HostnameImmutable: true, }, nil }) cfg, err := config.LoadDefaultConfig( context.TODO(), config.WithEndpointResolverWithOptions(resolver), ) ・・・ svc := s3.NewFromConfig(cfg)
HostnameImmutable
を true
にする事で URL
で指定したエンドポイントにそのまま接続しますが、デフォルトの false
だとホスト名へバケット名を付与するので注意が必要です。
例えば、カスタムエンドポイントが http://localhost:9000
でバケット名が sample1
の場合、HostnameImmutable が false だと http://sample1.localhost:9000
へ接続する事になります。
また、カスタムエンドポイントの代わりに aws.Endpoint{}, &aws.EndpointNotFoundError{}
を返すようにすると、通常のエンドポイントを使うようになります。
下記サンプルでは、S3 への接続時に S3_ENDPOINT
環境変数が設定されていればカスタムエンドポイント(MinIO)へ接続し、そうでなければ通常のエンドポイントを使うようにしてみました。
処理としては、S3(もしくは MinIO)からオブジェクトを取得してローカルファイルへ保存します。
main.go(サンプルコード)
package main import ( "context" "io" "log" "os" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" ) func main() { endpoint := os.Getenv("S3_ENDPOINT") bucket := os.Getenv("BUCKET_NAME") key := os.Args[1] dest := os.Args[2] resolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, opts ...interface{}) (aws.Endpoint, error) { if service == s3.ServiceID && len(endpoint) > 0 { // カスタムエンドポイント使用 return aws.Endpoint{ URL: endpoint, HostnameImmutable: true, }, nil } // 通常のエンドポイント使用 return aws.Endpoint{}, &aws.EndpointNotFoundError{} }) cfg, err := config.LoadDefaultConfig( context.TODO(), config.WithEndpointResolverWithOptions(resolver), ) if err != nil { log.Fatal(err) } svc := s3.NewFromConfig(cfg) // オブジェクト取得 res, err := svc.GetObject(context.TODO(), &s3.GetObjectInput{ Bucket: &bucket, Key: &key, }) if err != nil { log.Fatal(err) } // ローカルファイル作成 fw, err := os.Create(dest) if err != nil { log.Fatal(err) } defer fw.Close() // ローカルファイルへ書き込み _, err = io.Copy(fw, res.Body) if err != nil { log.Fatal(err) } }
動作確認
MinIO を起動して下記を実施しておきます。
MinIO へ接続するための環境変数を設定します。
環境変数の設定(Windows 環境の場合)
set AWS_ACCESS_KEY_ID=minioadmin set AWS_SECRET_ACCESS_KEY=minioadmin set BUCKET_NAME=sample1 set S3_ENDPOINT=http://localhost:9000
実行します。
実行
> go run main.go a01/item-1.jpg output.jpg
MinIO の a01/item-1.jpg を output.jpg として保存できました。
ついでに、S3_ENDPOINT 環境変数の値を空にすると https://sample1.s3.ap-northeast-1.amazonaws.com/a01/item-1.jpg
へアクセスするようになりました。