serverless frameworkを使ってFunction ComputeとAPI Gatewayにデプロイする

serverlessを使う

github.com

serverlessはlambdaなどの各サービスの上へ簡単にサーバレスなアプリケーションを作成/デプロイできるCLIツールです。ロゴがカッコいいですね。

serverlessのプラグインとしてアリババクラウドが出しているserverless-aliyun-function-computeがあるのでこれを使います。

まずyarn global add serverlessでserverlessをインストールしておきましょう。

aliyun-nodejsのインストール

$ serverless install --url https://github.com/aliyun/serverless-function-compute-examples/tree/master/aliyun-nodejs
Serverless: Downloading and installing "aliyun-nodejs"...
Serverless: Successfully installed "aliyun-nodejs"
$ ls -lah aliyun-nodejs
total 32
drwxr-xr-x  6 ryouta  staff   192B Aug  7  2018 .
drwxr-xr-x  3 ryouta  staff    96B Aug  7  2018 ..
-rw-r--r--  1 ryouta  staff    86B Aug  7  2018 .gitignore
-rw-r--r--  1 ryouta  staff   191B Aug  7  2018 index.js
-rw-r--r--  1 ryouta  staff   322B Aug  7  2018 package.json
-rw-r--r--  1 ryouta  staff   712B Aug  7  2018 serverless.yml
$ serverless plugin install --name serverless-aliyun-function-compute
Serverless: Installing plugin "serverless-aliyun-function-compute@latest" (this might take a few seconds...)
Serverless: Successfully installed "serverless-aliyun-function-compute@latest"

credentialの設定をする

アリババクラウド、各サービスがそれぞれで秘密情報の場所とフォーマットを設定しているから同じ内容のファイルがバラけて気持ち悪い。

デフォルトのファイルの場所は~/.aliyuncli/credentialsです。変更も可能です。

$ mkdir ~/.aliyuncli
$ vim ~/.aliyuncli/credentials
$ cat ~/.aliyuncli/credentials
[default]
aliyun_access_key_id = xxxxxxxxxxxxxxx
aliyun_access_key_secret = xxxxxxxxxxxxxxxxxxx
aliyun_account_id = xxxxxxxxxxxxxxx

deployを実行する。

$ serverless deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Compiling function "hello"...
Serverless: Finished Packaging.
Serverless: Log project sls-xxxxxxxx-logs already exists.
Serverless: Log store sls-xxxxxxxxxx-logs/aliyun-nodejs-dev already exists.
Serverless: Log store sls-xxxxxxxxxx-logs/aliyun-nodejs-dev already has an index.
Serverless: RAM role sls-aliyun-nodejs-dev-exec-role exists.
Serverless: RAM policy fc-aliyun-nodejs-dev-access exists.
Serverless: RAM policy fc-aliyun-nodejs-dev-access has been attached to sls-aliyun-nodejs-dev-exec-role.
Serverless: Service aliyun-nodejs-dev already exists.
Serverless: Bucket sls-xxxxxxxxxxx already exists.
Serverless: Uploading serverless/aliyun-nodejs/dev/xxxxxxxxxxx-2018-08-07T04:01:01.158Z/aliyun-nodejs.zip to OSS bucket sls-xxxxxxxxxxxxx...
Serverless: Uploaded serverless/aliyun-nodejs/dev/xxxxxxxxxxxx-2018-08-07T04:01:01.158Z/aliyun-nodejs.zip to OSS bucket sls-xxxxxxxxxxxxx
Serverless: Updating function aliyun-nodejs-dev-hello...
Serverless: Updated function aliyun-nodejs-dev-hello
Serverless: RAM role sls-aliyun-nodejs-dev-invoke-role exists.
Serverless: Attaching RAM policy AliyunFCInvocationAccess to sls-aliyun-nodejs-dev-invoke-role...
Serverless: Attached RAM policy AliyunFCInvocationAccess to sls-aliyun-nodejs-dev-invoke-role
Serverless: Creating API group aliyun_nodejs_dev_api...
Serverless: Created API group aliyun_nodejs_dev_api
Serverless: Creating API sls_http_aliyun_nodejs_dev_hello...
Serverless: Created API sls_http_aliyun_nodejs_dev_hello
Serverless: Deploying API sls_http_aliyun_nodejs_dev_hello...
Serverless: Deployed API sls_http_aliyun_nodejs_dev_hello
Serverless: GET http://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-cn-shanghai.alicloudapi.com/foo -> aliyun-nodejs-dev.aliyun-nodejs-dev-hello
$ 
$ serverless invoke -f hello
Serverless: Invoking aliyun-nodejs-dev-hello of aliyun-nodejs-dev
Serverless: {"statusCode":200,"body":"{\"message\":\"Hello!\"}"}

serverless invokeに渡す必要がある-fオプションは、jsファイル中のhandler関数の名前です。(ここではhello)

出たエラー

serverless deployを実行した時に以下の2つのエラーが発生しましたが、ログを見ると特にリソース自体は作成されていたので何もせずdeployを再実行しました。私は3回目で正常に成功しましたw

きっとプラグイン側のバグでしょう。

POST /services failed with 400. requestid: 5a98e7ee-8159-cc22-0d5a-18bec02a9cc8, message: project 'sls-5326127221743842-logs' does not exist.

The role not exists:sls-aliyun-nodejs-dev-invoke-role

確認

コンソールで確認して見ると、Function ComputeとAPI Gatewayにリソースが作られていました。

f:id:asmsuechan:20180807130720p:plain

f:id:asmsuechan:20180807130742p:plain

funserverlessどちらを使うべきか

上記のように謎に失敗する時があることや鍵の指定方法を考えると、funがいいと思います。公式なので変更にも強そうです。

funだとタイムトリガーなど他のトリガーにも対応できますし。

asmsuechan.hatenablog.com