Cloud Run の Go言語から GCP の Firestore にアクセスする


サービスアカウントの作成

認証情報を作成する

ロールは Datastore のを使う。

キーを作成する

  • とりあえず JSON 形式で作成した。
  • 自動的にダウンロードされる。

ソース

main.go

  • import は Firesotre のために追加したものだけ記載
main.go(かなり抜粋)
import (
  "context"
  "cloud.google.com/go/firestore"
  "google.golang.org/api/iterator"
)

func helo(w http.ResponseWriter, r *http.Request) {
  ctx := context.Background()
  client, err := firestore.NewClient(ctx, "GCPのプロジェクトID")
  if err != nil {
    log.Fatalf("Failed to create client: %v", err)
  }
  defer client.Close()

  iter := client.Collection("users").Documents(ctx)
  for {
    doc, err := iter.Next()
    if err == iterator.Done {
      break
    }
    if err != nil {
      log.Fatalf("Failed to iterate: %v", err)
    }
    fmt.Fprintf(w, "%v\n", doc.Data())
  }
}

Dockerfile

  • ca-certificatescrt がないと動かなかった。
Dockerfile
ARG APP_DIR="/appdir"
# builder
FROM golang:1.15
ARG APP_DIR
RUN go env -w GO111MODULE=on \
 && go env -w CGO_ENABLED=0
WORKDIR ${APP_DIR}
COPY . .
RUN go build -v -o app

# product
FROM scratch
ARG APP_DIR
ARG PORT="80"
ENV GOOGLE_APPLICATION_CREDENTIALS="${APP_DIR}/key.json" \
    PORT="${PORT}"
WORKDIR ${APP_DIR}
COPY --from=0 ${APP_DIR}/app ./app
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt 
COPY key.json ./key.json
EXPOSE ${PORT}
ENTRYPOINT ["./app"]

メモ

動くまでに出たエラーたちをただ羅列しただけ

Failed to iterate: rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: x509: certificate signed by unknown authority"

The request failed because either the HTTP response was malformed or connection to the instance had an error.

Failed to iterate: rpc error: code = Unauthenticated desc = transport: oauth2: cannot fetch token: 400 Bad Request

Response: {"error":"invalid_grant","error_description":"Invalid grant: account not found"}

Failed to iterate: rpc error: code = PermissionDenied desc = Missing or insufficient permissions.

その他

cloudbuild.yaml とか、記載以外は前のまま。前の記事

おかしい

  • コンテナにキーをコピーするとか、いらないはず。 デフォルトのサービスアカウントに firestore の 読み込み権限があればいいと思うのがけど、そもそも「編集者」って強力な権限なのに。。。
  • いろいろ別プロジェクトで再構築していると、やっぱ動いた。
  • yaml の deploy のところに、- '--service-account' で 作成したサービスアカウントを指定すれば、キーを作ったりコピーしたりはいらなかった。
  • 後日、まっさらなプロジェクトでもういっかいやってみますが、基本的には キーをコンテナにコピーなんてことは、いらないっぽ。