なんか微妙にハマったので書きまとめておきます。Cloud Functionsの実行環境はNode.js 6です。
デプロイ先のプロジェクト設定
現在のプロジェクトがデプロイ先のプロジェクトとして設定されているか確認してください。以下のコマンドで確認できます。
$ gcloud config list
[core]
account = *****@gmail.com
disable_usage_reporting = True
project = eimei4coding <-- プロジェクト名
もし意図したプロジェクトと違っていたら以下のコマンドで変更。
$ gcloud config set project %プロジェクト名%
Functionsのデプロイコマンド
以下のコマンドで行います。
$ gcloud beta functions deploy %Function名% \
--entry-point=%呼び出し関数名% \
--trigger-http
--trigger-httpは関数のトリガータイプをHTTPにしている。もちろん他のトリガータイプを指定することもできる。
このコマンドによりディレクトリ配下のファイルをzipで固めてデプロイします。きちんと動くようにデプロイするためには、ディレクトリ配下に以下のファイルを置く必要があります。
- 実行するFunctionは、index.js もしくは function.jsというファイル名にする
- package.jsonも必要
でないとこんなエラーが出たりします。
ERROR: (gcloud.beta.functions.deploy) OperationError: code=3, message=Function load error: File index.js or function.js
that is expected to define function doesn't exist in the root directory.
環境変数の設定
コマンドラインに環境変数を書いたyamlファイルを指定すると、デプロイ先に環境変数を設定できます。Functionごとに環境変数を割り当てられます。
TWITTER_CONSUMER_KEY: ******
TWITTER_CONSUMER_SECRET: ******
--env-vars-fileでyamlファイルを指定する
$ gcloud beta functions deploy myfunction \
--entry-point=main \
--env-vars-file=env.yaml \
--trigger-http
これでデプロイ先のNode.jsからもprocess.env.TWITTER_CONSUMER_KEYのように参照できます。
1つのディレクトリに複数のFunctionのjsファイルがある場合
1プロジェクトで複数のFunctionが必要な場合もあります。Functionごとにフォルダを分けて、それぞれにindex.js、package.jsonを置く形にしておけば、デプロイもコマンドでサクッといきますが、そうでない場合もありますよね。
私はindex.jsという同名ファイルが複数あると、作業中に何を触っているかわからなくなるからファイル名を分けたいし、package.jsonは面倒なのですべての関数で共通にしたいです。よってフォルダ配下は以下のようになっています。
- function1.js
- function2.js
- function3.js
- package.json
function1〜3はそれぞれ別のCloud Functionとしてデプロイしたい。またfunction1~3のファイル名はデプロイ先のFunction名と一致させたい。
こういう場合は、シェルスクリプト使って一旦別フォルダにファイルをrenameして移してデプロイすると良いと思います。
#!/bin/sh
# 第1引数にFunctionのjsファイル名を受け取る。
# つまり$1にファイル名が入る
# deployディレクトリを作る
mkdir deploy
# Functionのjsをindex.jsにrenameしてdeployへコピー
cp $1.js deploy/index.js
# package.jsonもコピー
cp package.json deploy/
cd deploy
# deploy配下のindex.jsとpackage.jsonをzipしてデプロイ
gcloud beta functions deploy $1 \
--entry-point=main \
--env-vars-file=env.yaml \
--trigger-http