echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

【Serverless Framework】Azureにサービスをデプロイする

概要

以前、【Serverless Framework】簡単デプロイとserverless.ymlの記載についてで、Serverless Framework(以下SFW)を使ってAWSにサービスをデプロイする方法を書きました。

今回はその続きとして、最近おざなりになっていたSFWを使用した、Azureへのサービスのデプロイ方法について記載します。

触れないこと

  • SFWの詳細
    • これは「概要」内のAWS版の記事を参照してください。
  • Azureの詳細

インストール&サービス作成

インストール&サービス作成は、AWS版と大差ありません。
インストールして、テンプレートを指定して、サービス作成(create)する...という感じです。

ただAzureでは「serverless-azure-functions」というモジュールが追加で必要のようなので、別途npm installして、「plugins」定義に追加しておきます。

# SFWインストール
> npm install serverless -g  
  
# serverless-azure-functionsのインストール  
> npm install serverless-azure-functions  --save-dev  
  
# サービス作成(templateは他にもいろいろ。--helpで一覧を表示可能)  
> serverless create --template azure-nodejs --name azure-sample

定義の作成

定義の作成ですが、「百聞は一見に如かず」なので、まずはserverless.ymlファイルの一例を。

なお、下記serverless.ymlファイルを含むプロジェクト一式を下記レポジトリで公開していますので、興味があればご一読ください。

service: azure-sample-new-20190825

provider:
  name: azure
  location: japanwest

plugins:
  - serverless-azure-functions

package:
  exclude:
    - README.md
  include:
    - lambda/**

## azure functions dedinition.
## azure functions works at ([endpointurl]/api/[route])
## e.g. https://your-function-app-name.azurewebsites.net/api/hello
## this is able to change at congigration of host.json
## https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-host-json
functions:
  hello:
    handler: lambda/Hello/index.handler
    events:
      - http: true
        x-azure-settings:
          # direction: in
          name: req
          methods: 
            - get
          route: hello
          authLevel : anonymous
      - http: true
        x-azure-settings:
          direction: out
          name: res
  goodbye:
    handler: lambda/Goodbye/index.handler
    events:
      - http: true
        x-azure-settings:
          # direction: in
          name: request
          methods: 
            - get
          route: goodbye
          authLevel : anonymous
      - http: true
        x-azure-settings:
          direction: out
          name: res
  goodbye2:
    handler: lambda/Morning/index.handler
    events:
      - http: true
        x-azure-settings:
          # direction: in
          name: request2
          methods: 
            - post
          route: posthello
          authLevel : anonymous
      - http: true
        x-azure-settings:
          direction: out
          name: response

service

サービス(デプロイするアプリの管理単位。CloudFormationみたいなもの)の名前、という点ではAWSと同じです。

  • Azureの場合、「[サービス名]-rg」というのがリソースグループの名前になります。(AWSと違い、「serverless-deployment-bucket」などを使用して任意の名前を付ける...みたいなことはできないみたい)
  • リソースグループ名は、サブスクリプション内での重複はNGなので、必ず重複がない名前にしてください。

provider

  • name:デプロイ先クラウドの名前。create時に--templateを指定した場合、自動で設定されています。
  • location: デプロイ先のリージョンを指定します。(japaneast, japanwestなど)

plugins

先述の通り、ここには先程インストールした「serverless-azure-functions」を指定します。

include/exclude

AWSと同じく、パッケージファイルに含める/除外するファイルの設定です。

functions

Azure Functionの定義。今回の中心となる部分です。(ただ「定義名」「handler」「[events] - [http]」の部分は、AWSと同じなので省略)

※eventsはhttp(http通信)以外にもいろいろありますが、今回はhttpのみ紹介。(それ以外のイベントはSFW公式サイトを参照)

Azureの場合、下記のルールがあるようです。

  • (イベントの種類以外の)定義は「x-azure-settings」以下に定義
  • リクエスト/レスポンスで個別に定義が必要
  • AWSとは違い、API Management(AWSで言うAPI Gateway)には紐づかない

なお、ここ項目の説明はこちら。

項目名 説明 備考
direction 通信の向き(?)
inはリクエスト、outはレスポンス。
inを定義したらエラーになった。in側は定義不要かも。
name Azure Functionファイル内でのリクエスト、およびレスポンスオブジェクトの名前。
methods リクエストメソッドの種類(get, postなど)を配列形式で in側のみ。
定義とメソッドが1:1ではないのが、AWSとの違い
route リクエストURLに適用される、エンドポイントURLの後に付与される文字 in側のみ。
デフォルトは「定義名(helloなど)」
AuthLevel リクエスト時の認証に適用される認証レベル。 in側のみ。
function, anonymous, adminから選択

デプロイ

デプロイですが、これはAWSと同じく「deploy」コマンドを実施するだけです。

下記の処理が行われた後、デプロイされます。問題がなければ、デプロイ完了するはずです。

  • [関数定義名]-function.jsonの作成
  • host.jsonの作成
  • .serverlessフォルダに、パッケージしたファイル(*.zip)の作成
# デプロイ
> serverless deploy -v  

あとはAzureにアクセスし、リソースグループ&Azure Functionが作成されており、各Azure Functionに「[エンドポイントURL] + [route]の設定値」のURLで正常にレスポンスが返ってくればOKです。

※デフォルトのエンドポイントは、https://[サービス名].azurewebsites.net/api/[routeの設定値] です。(「api」を忘れやすい)

デプロイできない場合

デプロイ時ができない場合、下記事項を確認してください。

「At least one resource deployment operation failed」というエラーが発生する。

この場合「[service]に指定した名前-rg」という名前のリソースグループがすでに存在している可能性が高いです。
コンソール操作や「serverless remove」コマンドで該当のリソースグループを削除してから、再度実施してください。

※deployコマンドがエラーになってもリソースグループ自体は作成されますので、そのリソースグループの消し忘れ...というのが、よくあるケースです

エラーは発生しないが、デプロイ中に「Creating Function App」から一切処理が進まない

この場合、AzureのActivityログに下記「Failed」ログが無いか確認してください。
下記ログがあった場合、過去のCreating Function App処理が何故か生き続けていることが原因である可能性があります。

項目名 内容
Error Code Conflict
Message Cannot modify this web hosting plan because another operation is in progress. (中略) OperationName: Create

対策としては、「service名を変更して、別リソースグループ名でデプロイする」になります。(これ、バグなのかも...)

SFWがAzure対応したのは2017年と比較的新しいからか、一部AWSで対応している機能が機能しなかったりなどありますが(※)、サービスのデプロイは十分可能です。
本格的にサーバーレスアプリを作る場合はもちろん、「WPF、Xamarin.Formsなどでサーバーレスアプリを作りたい!」という場合に、サクッとAzureの環境を作るような場合にも、非常に有用だと思います。

では、今回はこの辺で。

※例えば「package」コマンドや「--package」オプションなどは機能しないようです。(公式サイトにも記載がない)