selmertsxの素振り日記

ひたすら日々の素振り内容を書き続けるだけの日記

CloudFunctionsをServerless Framework & TypeScriptの環境で試してみる

やったこと

Serverless Frameworkを使って CloudFunctionを動かしてみました。 試した内容は下記の通りです。

  • TypeScriptで書けるようにしてみる
  • serverless.ymlの設定で環境変数を利用する
  • 日本のリージョンにDeployする

実際に利用したコード https://github.com/selmertsx/study/tree/master/serverless/cloudfunction-sls-sample

前提

https://serverless.com/framework/docs/providers/google/guide/quick-start/

上記チュートリアルを実行して、nodejsのコードをdeploy & invokeできるようにしてある前提で話を進めます。

TypeScriptで書けるようにする

https://github.com/prisma/serverless-plugin-typescript このpluginを利用します。

手順は簡単で、下記の手順を踏むだけで設定可能です

  • serverless.yml のpluginsに serverless-plugin-typescript を追加する
  • 指定されたフォーマットでtsconfig.jsonの設定をする
  • 既存のコードをTypeScriptに置き換える
  • (options) package.jsonのmain fieldを書き換える
plugins:
  - serverless-google-cloudfunctions
  - serverless-plugin-typescript
// Note: outDir と rootDir optionsを上書きしないこと
{
  "compilerOptions": {
    "target": "es5",
    "outDir": ".build", 
    "moduleResolution": "node",
    "lib": ["es2015"],
    "rootDir": "./"
  }
}

もし起点となるコードが index.ts でなければ、package.jsonのmain fieldを下記のように書き換える必要があります。

// handler.tsを起点にしたい場合
{
  // ...
  "main": "handler.js",
  // ..
}

serverless.ymlの設定で環境変数を利用する

https://serverless.com/framework/docs/providers/google/guide/variables/

公式ドキュメントを見ると、ymlやjsとして別のファイルに切り出したり、serverless.dev.ymlのように環境毎にymlを分けたりする方法が書かれています。今回はgitにcommitしたくないコードの管理がしたかったので、ちょっとその用途とは違うため別の方法を模索しました。

https://serverless.com/framework/docs/providers/aws/guide/variables/

awsの方のGuideを見てみると、下記のような機能がありました。

o reference environment variables, use the ${env:SOME_VAR} syntax in your serverless.yml configuration file. It is valid to use the empty string in place of SOME_VAR. This looks like "${env:}" and the result of declaring this in your serverless.yml is to embed the complete process.env object (i.e. all the variables defined in your environment).

これについてgoogleでも使えないかと試してみたところ、普通に使えたので今回はそれを利用しました。

service: cloudfunction-sls-sample
provider:
  name: google
  project: ${env:PROJECT}

日本のリージョンにDeployする

cloud functionsでServerless Frameworkを利用し、regionを何も指定せずにdeployをすると us-central1にdeployがされます。 deploy先のregionをserverless.ymlで設定していきましょう。 deployする先の指定は、serverless-google-cloudfunctionsのv2.0.0 から出来るようになっています。 けれども、sls コマンドでinstallされるversionはv1.2.0なので、pluginのバージョンを上げる必要があります。

https://github.com/serverless/serverless/blob/63b8dafbeb7bd463acf9fe9a4f5ec51c7e972928/lib/plugins/create/templates/google-nodejs/package.json#L12

"devDependencies": {
  "serverless-google-cloudfunctions": "^2.0.0",
  "serverless-plugin-typescript": "^1.1.5"
}

その後、serverless.ymlの値を書き換えて実行してみます。

service: cloudfunction-sls-sample
provider:
  name: google
  region: asia-northeast1
  runtime: nodejs8
  project: ${env:PROJECT}

実行結果がこちらになります。

$ sls deploy
service: cloudfunction-sls-sample
project: xxx
stage: dev
region: us-central1

Deployed functions
first
  https://us-central1-xxx.cloudfunctions.net/http

ぱっと見るとus-central1にdeployされていてギョっとしますがcliを使って実際にdeployされているregionを確認してみると、ちゃんとasia-northeast1になっていることが確認できます。

gcloud beta functions describe http --region asia-northeast1
availableMemoryMb: 256
entryPoint: http
httpsTrigger:
  url: https://asia-northeast1-xxx.cloudfunctions.net/http <==ここをチェック
labels:
  goog-dm: sls-cloudfunction-sls-sample-dev
name: projects/xxx/locations/asia-northeast1/functions/http
runtime: nodejs8
serviceAccountEmail: xxx@appspot.gserviceaccount.com
sourceArchiveUrl: gs://sls-cloudfunction-sls-sample-dev-xxx/serverless/cloudfunction-sls-sample/dev/xxx-2018-09-25T10:08:07.390Z/cloudfunction-sls-sample.zip
status: ACTIVE
timeout: 60s
updateTime: '2018

AWS Lambdaと比較した所感

  • localでの動作確認について、lambdaはpluginで提供されているが、cloud functionsはまだない。
  • LambdaではTypeScriptテンプレートがあるので、特に何の指定もしなくて良い
  • Lambdaは起動するためのeventsが豊富
    • cloud functionsはhttpとpub subだけ
    • これがcloud functionsのデメリットとなるかは、pub subを触ってみないとなんとも言えない

コミットチャンス

宿題

  • credentialsや環境変数をcode buildなどから扱えるようにしたい
  • cloud functionに渡す権限を、もっとちゃんと整理したい