3大クラウドのFaaSをServelessFrameworkでやってみた。

Terraformで3大クラウドのVPC構築できるところは試したので、次はいよいよ本命の
Servelessを試してみようということでServelessFrameworkに手を出してみました。
クラウドプロバイダー間の差異を吸収してFaaSを統一的に動かそうというような
そういう発想のものだそうです。
マルチクラウドでServeless構成でなるべく手間を少なくという発想なので非常に
ありがたいサービスじゃないかと飛びついた次第です。

コンテナとかk8s使えというお声もあるかもしれないですが、なんせ自身がへぼいのと
サーバという発想が残ったり環境依存とかできてしまったりとかするし
スケールするときとかもう考慮しないといけないことが色々あるのでかなり逃げています。
Docker-composeですら逃げてたりする位、ダメな奴なので設定とか、もうあまり考えたくありません。
どうしてもマネージドサービスで何とかしたいと思い、少し調べてみた次第です。
ひとまず手順まとめてみました。

3つの仮想マシン準備してそれぞれAWS用、GCP用Azure用に割り当てました。それぞれの仮想マシン構築方法やCLIインストール手順は割愛します。
GCPについてはTeraformで作成したプロジェクトを流用しています。

◆インストール手順

$ sudo apt install -y nodejs npm
$ sudo npm install n -g
$ sudo n stable
$ sudo apt purge -y nodejs npm
$ exec $SHELL -l
$ node -v
v12.16.0
$ npm -v
6.13.4
$ sudo npm install -g serverless
$ sudo chown -R $USER:$(id -gn $USER) /home/users/.config
$ serverless --version
Framework Core: 1.67.3
Plugin: 3.6.6
SDK: 2.3.0
Components: 2.30.1
$ sudo npm install serverless-offline
$ mkdir sls
$ cd sls

◆それぞれで構築

1.AWSの場合

マネジメントコンソールで専用のIDを作成する。権限はadministrator必須

#認証設定
$ aws configure
AWS Access Key ID : IAMで発行したアクセスキー
AWS Secret Access Key : IAMで発行したトークン
Default region name : ap-northeast-1
Default output format : json

#テンプレート作成
$ mkdir sls
$ cd sls
$ sls create -t aws-python3 -p sample
$ vi handler.py
-----
import json

def hello(event, context):
    body = {
        "message": "Hello, world",
    }
    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response
-----
$ vi serverless.yml
-----
service: sample

provider:
  name: aws
  runtime: python3.8
  region: ap-northeast-1

plugins:
  - serverless-offline

functions:
  hello:
    handler: handler.hello

    events:
      - http:
          path: hello
          method: get
          cors: true
-----
#ローカルテスト
$ sls offline -o 0.0.0.0
#http://仮想マシンのIP:3000/dev/helloでテストできる

#デプロイ
$ sls deploy
#削除
$ sls remove

2.Azureの場合

#認証設定
$ az account set --subscription="SUBSCRIPTIONID"
$ az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/SUBSCRIPTIONID"
Creating a role assignment under the scope of "/subscriptions/SUBSCRIPTIONID"
{
  "appId": "APPID",
  "displayName": "XXX",
  "name": "XXXX",
  "password": "PASSWORD",
  "tenant": "TENANTID"
}
#環境変数に埋め込み
$ export AZURE_SUBSCRIPTION_ID='SUBSCRIPTIONID'
$ export AZURE_CLIENT_ID='APPID'
$ export AZURE_CLIENT_SECRET='PASSWORD'
$ export AZURE_TENANT_ID='TENANTID'

#テンプレート作成
$ sls create -t azure-nodejs -p sample
#プラグイン追加
$ cd sample/
$ npm install
$ npm install azure-functions-core-tools

#テンプレートのサンプル利用、serveless.yml編集
$ vi serverless.yml
----
service: sample

provider:
  name: azure
  region:   Japan East
  runtime:  nodejs10.x

plugins:
  - serverless-azure-functions
  - serverless-offline

package:
  exclude:
    - local.settings.json
    - .vscode/**

functions:
  hello:
    handler: src/handlers/hello.sayHello
    events:
      - http: true
        x-azure-settings:
          methods:
            - GET
          authLevel: anonymous
  goodbye:
    handler: src/handlers/goodbye.sayGoodbye
    events:
      - http: true
        x-azure-settings:
          methods:
            - GET
          authLevel: anonymous
-----------

#デプロイ
$ sls deploy

#動作確認
$ sls invoke -f hello -d '{"name": "Azure"}'
$ sls invoke -f goodbye -d '{"name": "Azure"}'

#削除
$ sls remove

3.GCPの場合

#サービスAPI有効化
$ gcloud services enable deploymentmanager.googleapis.com cloudfunctions.googleapis.com storage-component.googleapis.com logging.googleapis.com
#クレデンシャル取得
$ PROJECT=myproject-XXXXX
$ SERVICE_ACCOUNT=gcf-sls-deploy
$ KEY_FILE=~/credentials/serveless.json
$ ROLES="roles/deploymentmanager.editor roles/storage.admin roles/logging.admin roles/cloudfunctions.developer"
$ gcloud iam service-accounts create ${SERVICE_ACCOUNT} --display-name "Cloud Functions deployment account for Serverless Framework"
$ for role in ${ROLES};do \
 gcloud projects add-iam-policy-binding ${PROJECT} \
 --member=serviceAccount:${SERVICE_ACCOUNT}@${PROJECT}.iam.gserviceaccount.com \
 --role=${role}\
 done
$ gcloud iam service-accounts keys create ${KEY_FILE} \
   --iam-account ${SERVICE_ACCOUNT}@${PROJECT}.iam.gserviceaccount.com

#テンプレート作成
$ mkdir sls
$ cd sls
$ sls create --template google-python --path sample
#プラグイン追加
$ cd sample
$ npm install

#テンプレートのサンプル編集、serveless.yml編集
$ vi main.py
----------------
def sample(request):
    return f'Hello World!'
----------------
$ vi serveless.yml
----------------
service: sample

provider:
  name: google
  runtime: python37
  region: asia-northeast1
  project: myproject-XXXXX
  credentials: ~/credentials/serveless.json

plugins:
  - serverless-google-cloudfunctions

package:
  exclude:
    - node_modules/**
    - .gitignore
    - .git/**

functions:
  sample:
    handler: http
    events:
      - http: path
----------------

# デプロイ
matarain@gcp_dev:~/sls/sample$ sls deploy

#CloudFunctions一般公開
・CloudFunctionsのコンソールを開いて[メンバーを追加]クリック











・[新しいメンバー]に「allUsers」を入力し、[ロールを選択]にて
 [Cloud Functions 起動元]を選択する。














・[保存]をクリック後に[一般公開アクセスを許可]をクリックする。













#テスト:デプロイ時に表示されるURLにcurl
$ curl https://asia-northeast1-myproject-XXXXX.cloudfunctions.net/sample-dev-sampl

#削除
$ sls remove


AWSは情報が多々あるのと、比較的スムーズに動くので良かったですが、AzureとGCPは情報が少ない上に非実装の機能とかあったりしてかなり嵌りました。ないならドキュメントに書かないでほしい。
 その手順が必要ながらServelessFrameworkではそのパラメータが見当たらず嵌った。
 →結局手動
*GCPでinvokeが動くとか書いてあったけどエラーしか出なくて動かなくなってた。
 →Teratailで質問中、回答つかない(泣)
*Azureでofflineテストができるかのように公式に書いてあったので嵌った。
*Azureで現時点ではNode動かす場合、Node10系しか動かない。

極めつけはserveless.ymlのproviderを1個しか指定できないのでマルチクラウドデプロイを実現しようとするとかなり面倒くさいということでした。Teraformと違ってあまり嬉しくない結果でした。
今のままならAWSだとSAM使った方がいいし、AzureもazとかVSCodeのextension使った方がいいしGCPならCloudSDK使った方がいいと確実に思います。

ただデプロイとかについては同一コマンドでできるので、デプロイのみと割り切って使うのであればありかもしれないかなと思いました。ローカルの開発環境は課題かと思ってます。

CloudSDKのpython3対応進んできているのでGCPにも手を出してみようかと思います。
次はGAEとAzureのWebAPPsでいろいろとやりたいなぁ。

◆参考サイト

・3大クラウド汎用でとか考えている人【英語】



・nodeインストール関連


・ServelessFramework公式


・AWS


・Azure


・GCP

コメント

このブログの人気の投稿

証券外務員1種勉強(計算式暗記用メモ)

GASでGoogleDriveのサブフォルダとファイル一覧を出力する

マクロ経済学(IS-LM分析)