AWS SDK for Goからminioへのアクセスでハマったこと

満足度98%

はじめに

先日の投稿 で紹介したminioを使ってみたところ、AWS SDK for Goでアクセスするとエラーになってしまいました。今回は備忘のためハマった内容と解消方法をまとめてみます。

検証環境

  • Docker: 18.06.0-ce
  • minio: 2018-08-02T23:11:36Z
  • Go: 1.10.3
  • AWS SDK for Go: v1.15.25
PRいまのAWSパートナー、請求代行だけなんだよな

ハマったこと

以下のソースコードでminioのオブジェクトを列挙しようとしたところエラーが発生しました。簡略化のためエラー発生時は panic で中断するようにしています。

main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package main
 
import (
  "fmt"
 
  "github.com/aws/aws-sdk-go/aws"
  "github.com/aws/aws-sdk-go/aws/credentials"
  "github.com/aws/aws-sdk-go/aws/session"
  "github.com/aws/aws-sdk-go/service/s3"
)
 
func newS3() (*s3.S3, error) {
  s, err := session.NewSession()
  if err != nil {
    return nil, err
  }
 
  ak := "MINIO_ACCESS_KEY"
  sk := "MINIO_SECRET_KEY"
  cfg := aws.Config{
    Credentials: credentials.NewStaticCredentials(ak, sk, ""),
    Region:      aws.String("ap-northeast-1"),
    Endpoint:    aws.String("http://127.0.0.1:9000"),
  }
  return s3.New(s, &cfg), nil
}
 
func main() {
  c, err := newS3()
  if err != nil {
    panic(err)
  }
 
  bucket := "minio-bucket"
  var token *string
  for complete := false; !complete; {
    in := s3.ListObjectsV2Input{Bucket: &bucket, ContinuationToken: token}
    out, err := c.ListObjectsV2(&in)
    if err != nil {
      panic(err)
    }
 
    for i, o := range out.Contents {
      fmt.Printf("[%d] : %s\n", i, *o.Key)
    }
 
    complete = out.IsTruncated != nil && !*out.IsTruncated
    token = out.NextContinuationToken
  }
}

この状態で実行するとエラーが発生しました。

1
2
3
4
5
6
7
8
$ go run main.go
panic: RequestError: send request failed
caused by: Get http://minio-bucket.127.0.0.1:9000/?list-type=2: dial tcp: lookup minio-bucket.127.0.0.1: no such host
 
goroutine 1 [running]:
main.main()
    /Users/yoshihitoh/go/src/use-minio/main.go:40 +0x317
exit status 2

http://{{ バケット名 }}.{{ エンドポイント }}/ の形式でURLを組み立てるようで、ローカル環境だとうまく動きません。

解消方法

どうしたものかと調べてみると、minioのcookbookにズバリな解決方法がのっていました。

aws.Config#S3ForcePathStyle の設定が必要なようです。構造体の初期化を以下の内容に書き換えます。

1
2
3
4
5
6
cfg := aws.Config{
    Credentials:      credentials.NewStaticCredentials(ak, sk, ""),
    Region:           aws.String("ap-northeast-1"),
    Endpoint:         aws.String("http://127.0.0.1:9000"),
    S3ForcePathStyle: aws.Bool(true), // NOTE: この指定を追加
}

再度実行してみます。

1
2
$ go run main.go
[0] : hello-minio.txt

今度はうまく動きましたね!

おわりに

見慣れないエラーで解消できるんかなーと不安でしたが、cookbookのおかげですんなり解消できました。他の言語のAWS SDK利用方法や、aws-cli、s3cmdの利用方法も記載されています。情報が充実していて素晴らしいですね。

すべてのAWSが5%オフ