Google Cloud Functions の Tips vol.1
最近はずっと Google Cloud Functions 書く時、TypeScript+Node.JS で書いてたんですけど、久々に Golang で書いたらいろいろ忘れてたので、戻ってこれるように Tips をまとめます。
今回紹介するやつら
- always HTTPS(今回は HTTP トリガーの function で逝きます)
- 環境変数の使用
- 依存関係の解決その 1
- 依存関係の解決その 2(private repository だった時)
- ファイルシステムへのアクセス
always HTTPS
HTTP トリガーの Cloud Functions(以下 CF)を定義したとき、常に HTTPS にさせる方法(デフォは HTTP, HTTPS の両方で受け付けます)。挙動としては HTTP でアクセスすると HTTPS にリダイレクトされます。
gcloud functions deploy
コマンドに --security-level secure-always
をくっつける。それだけ。ちなみにデフォは secure-optional
。(記事執筆時点 2021-09-02T02:00:00+09:00)
参考 URL:
- https://cloud.google.com/functions/docs/writing/http#security_levels
環境変数の利用
gcloud functions deploy
コマンドに直接貼り付けて書いてもいいんですけど、デプロイの都度環境変数が変わっちゃうのが怖いので、ワイはファイルに指定派。
# env.yaml
MYNAME: "jupemara"
# bool型を指定すると怒られる(後述)
# BOOLEAN_VALUE: TRUE
STRING_VALUE: "TRUE"
yaml 形式で書いて、 gcloud functions deploy
コマンドに --env-vars-file env.yaml
みたいにファイルパスを渡してやれば OK。
KEY: VALUE
形式で書く。ただし、string 型を指定しないといけないので、 TRUE
みたいなものを渡したいときは "TRUE"
"
でくくって文字列にしてあげる必要がある。
あと GOOGLE_
prefix は予約語がいくつかあるので、非推奨。
参考 URL
- https://cloud.google.com/functions/docs/configuring/env-var
- https://cloud.google.com/functions/docs/configuring/env-var#using_build_environment_variables
- https://cloud.google.com/functions/docs/configuring/env-var#best_practices_and_reserved_environment_variables
依存関係の解決その 1
go.mod を使う方法と vendor ディレクトリを使う方法がある。
go.mod
go mod init
とか go get
とか go install
とか使って依存関係をインスコしてく。んで普通に deploy すれば OK
vendor
go mod vendor
使って依存モジュールを事前にディレクトリとして保存しておく必要あり。
共存について
go.mod と vendor の両方が存在してると vendor が無視される。vendor を優先してほしいときは .gcloudignore
に go.mod
って書いとくべし。
参考 URL
- https://cloud.google.com/functions/docs/writing/specifying-dependencies-go
- https://cloud.google.com/functions/docs/writing/specifying-dependencies-go#using_a_vendor_directory
依存関係の解決その 2
正直コレがドキュメントに記載されていない気がしていて、前もそういえばおんなじことやったなーと思ったので、ここが一番の Tips になると思う。公式ドキュメントには
関数の依存関係が一般公開されていないリポジトリでホストされる場合、その関数をデプロイする前に、vendor ディレクトリを使用して依存関係を取得する必要があります。go.mod ファイルを使用する場合は、上記の手順を参照して、go.mod ファイルと vendor ディレクトリの間の競合を回避してください。
ってかいてあるんやけど、んじゃあ自分自身が private repository で自分自身の他のディレクトリ配下のファイルに依存してるときはどうすんのって話なんやけど、( go mod vendor
を実行しても自分自身はディレクトリに入らないし、外部から依存関係解決させようとするとそんな repository ねえよって言われる。。。)結論から言うと
gcloud functions deploy --source ./
って repository の場所をカレントディレクトリにしたあと、vendor ではなく go.mod で依存関係を解決してあげると、あら不思議!デプロイできちゃう。
https://github.com/GoogleCloudPlatform/golang-samples/issues/743#issuecomment-458574149 この github のコメントには go.mod がある場所が root になるし、1 階層上のディレクトリを含めようとしても go.mod のある場所になるからそれはできない。そういうときは vendor を使えとしか書いてない。。。
--source ./
を使おうぜっていう Tips。コレで go.mod だけにできるのはかなりうれ C.
ファイルシステムへのアクセス
コンフィグファイルとかをリポジトリのルートに config.yaml
とか config.json
とかおいて実行したいよねーって思うんやけど、んで例えば
// ----config.go----
package config
import (
"io/ioutil"
"gopkg.in/yaml.v2"
)
func ReadConfigFile(path string) ([]byte, error) {
bytes, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return bytes, err
}
こんな関数があるとしてコレをリポジトリのルートから config.ReadConfigFile("./config.yaml")
とかやろうとすると(ってかやりたいよね??)、んなファイルはねえよって怒られちゃう。
コレは Cloud Functions の仕様で ./serverless_function_source_code/config.yaml
みたいに ./serverless_function_source_code
を格納先として指定してあげる必要があるんだな。
コレもよく忘れる... いつか普通に ./config.yaml
って直接指定できる日がコレばいいのだが。。。
参考 URL
- https://cloud.google.com/functions/docs/samples/functions-concepts-filesystem
まとめ
--source ./
をつけろ- そもそも現時点(2021-09-02T02:00:00+09:00)では Golang のランタイムが 1.13 なので、
io/util
のモジュールがio
に命名変更された件とかは含まれてないので、用途によっては Cloud Run でいいと思いますw- ref: https://cloud.google.com/functions/docs/concepts/exec