LoginSignup
6
5

More than 3 years have passed since last update.

AzureCLIでAzureFunctionsの構築

Posted at

PythonでAzureFunctionsを動かす

「サーバーレスがやってみたい」ので、AzureFunctionsをPythonで動かします。

image.png

AzureFunctionsでのPython対応は割と最近なようです。情報
個人利用レベルでまとめたものを以下に記載します。
チーム開発での利用方法や本番運用の方法などはまた後日しらべます。

動作環境

Windows10 / Powershell

Python 関数アプリではポータルにおける関数の編集はサポートされていません。開発には CLI または VS Code を使用してください。詳細情報

とのことなので、Pythonを用いて開発するにはCLIかVSCodeを用いる必要があり、今回はCLIで進めます。
CLIでの操作の方が、自分が今何をしているのか理解できるからいいですね(Gitもコマンドライン派です)

また、AzureFunctionsがpython3.6.xにしか対応していないようです。(2019/11/01現在)
私の環境は現在3.8が入っているので、切り変える必要があります。
バージョンの切り替えは、簡単にですが以下に記載しました。 参考にしてください。

AzureFunctionsとは?

そもそもAzureFunctionsはどんなものでしょうか。

Azure Functions は、インフラストラクチャを明示的にプロビジョニングしたり管理したりする必要がない、イベントトリガー型のコードを実行できるサーバーレス コンピューティング サービスです。

Function as a Service (FaaS)と呼ばれるもので、AWS LambdaGoogle Cloud Functionsと似た機能です。

関数アプリのプラン

関数アプリには実行環境の異なる3種類のプランがあり、通常のCLI構築では従量課金プランが選択されます。

プラン 英名 概要 課金体系
従量課金プラン Consumption plan 受信イベントの数に基づいて動的に追加および削除 関数の実行中にのみ課金
Premium プラン Premium plan 従量課金プランと同じように、Azure Functions ホストのインスタンスが、受信イベントの数に基づいて追加および削除 課金は、実行や消費されたメモリごとの課金ではなく、必要なインスタンスや事前ウォーミングされたインスタンスで使用されたコア秒数とメモリに基づいています。 1 つのプランにつき、少なくとも 1 つのインスタンスが常にウォーム状態である必要があります。 つまり、実行数に関係なく、アクティブなプランごとに最小の月額コストがかかります。
App Serviceプラン Dedicated plan 他の App Service アプリ (Basic、Standard、Premium、Isolated SKU) と同じ専用 VM 上でも実行できます。 App Service プランの関数アプリに対する支払いは、Web アプリなどの他の App Service リソースの場合と同じ

image.png

AzureFunctions(2.x)の対応言語

2019/11/05現在では、以下の言語に対応しています。

C#(.NET Core 2.2) / JavaScript(Bide 8,10) / F#(.NET Core 2.2) / Java(Java8) / PowerShell(PowerShell Core 6) / Python(Python 3.6.x) / TypeScript

AzureFunctionsの作成

本題に入ります。
AzureFunctionsをローカル開発するには、Azure Functions Core Toolsが必要です。

Azure Functions Core Tools を使用すると、ローカル コンピューター上のコマンド プロンプトまたはターミナルから関数を開発およびテストできます。 ローカル関数はライブ Azure サービスに接続できるため、完全な Functions ランタイムを使用してローカル コンピューター上で関数をデバッグすることができます。 Azure サブスクリプションに関数アプリをデプロイすることもできます。

npmを利用してインストールします。(要 Node.js)

in
npm install -g azure-functions-core-tools

関数アプリの作成

関数アプリプロジェクトの作成

関数アプリを作成するためのプロジェクトを作成します。
前述でインストールしたAzure Functions Core Toolsを利用します。

func init <project_name>でプロジェクトを作成します。

in
func init MyFunctionProj

実装言語の選択肢が表示されるので、今回はpythonを選択します。

out
Select a worker runtime:
dotnet
node
python
powershell

選択後、フォルダが作成されるので、フォルダを移動します。

in
cd  MyFunctionProj

関数アプリの作成

関数アプリを作成します。

AzureFunctionsでは、起動トリガーを選択する必要があります。
起動トリガーは、何を起因として関数アプリを起動させるかの設定で、以下の種類があります。
本記事では、よく利用されるHTTP triggerを利用します。

トリガー 概要
Azure Blob Storage trigger Azure Blob Storage 内でファイルがアップロードまたは変更されると実行
Azure Cosmos DB trigger Azure Cosmos DB データベースでドキュメントが追加または変更されると実行
Azure Event Grid trigger Event Gridのルーティング棋院で関数を実行
Azure Event Hub trigger Event Hubがメッセージを受信すると関数を実行
HTTP trigger Web アプリで HTTP 要求が発生すると関数を実行(今回のもの)
Azure Queue Storage trigger Azure Storage Queueに新しいアイテムが追加されると関数を実行
Azure Service Bus Queue trigger Azure Service Bus キューに新しいアイテムが追加されたら関数を実行
Azure Service Bus Topic trigger Azure Service Bus Topicへの新しいメッセージの到着に応答して関数を実行
Timer trigger 定義したスケジュールに従って定期的に Azure 関数を実行

関数アプリには、以下コマンドを利用します。

in
func new

起動トリガーの選択肢が表示されるので、HTTP triggerを選びます。

out
Select a template:
Azure Blob Storage trigger
Azure Cosmos DB trigger
Azure Event Grid trigger
Azure Event Hub trigger
HTTP trigger
Azure Queue Storage trigger
Azure Service Bus Queue trigger
Azure Service Bus Topic trigger
Timer trigger

選択後、関数名を記載要求されるので任意の関数名を記載します。
以下では、「httpTrigger」を記載しています。

in
Select a template: HTTP trigger
Function name: [HttpTrigger] httpTrigger

関数アプリのフォルダ構成

関数アプリのフォルダ構成は以下のような構成になっています。
1つのプロジェクトには複数の関数アプリを作成することも可能です。

/
│  .gitignore
│  host.json
│  local.settings.json
│  requirements.txt
│
├─.vscode
│      extensions.json
│
├─<function_name_1>
│      function.json
│      __init__.py
│
└─<function_name_2>
       function.json
       __init__.py

関数アプリで重要となってくるのは以下のファイルです。
中身の詳細については、後述します。

ファイル 役割
_init_.py 関数アプリプログラム
function.json 関数アプリの設定
host.json すべての関数アプリに影響するグローバル設定
local.settings.json ローカル環境でのアプリケーション変数

関数アプリの動作確認とデプロイ

前述までで処理で、既に動作可能なサンプルアプリが構築されています。
動作を確認してAzureへデプロイします。

関数アプリの動作確認

以下コマンドで、ローカル環境での実行を行います。

in
func host start
out
                  %%%%%%
                 %%%%%%
            @   %%%%%%    @
          @@   %%%%%%      @@
       @@@    %%%%%%%%%%%    @@@
     @@      %%%%%%%%%%        @@
       @@         %%%%       @@
         @@      %%%       @@
           @@    %%      @@
                %%
                %

Azure Functions Core Tools (2.7.1724 Commit hash: faf97bb64a53fbf1c7ef7e5c608c392c8662951b)
Function Runtime Version: 2.0.12763.0

...

Http Functions:

        httpTrigger: [GET,POST] http://localhost:7071/api/httpTrigger

...

上記のように実行され、表示されるhttp://localhost:7071/api/httpTriggerが関数アプリのURLです。
構築されているアプリは、クエリストリングを読み取って画面を表示するアプリです。

http://localhost:7071/api/httpTrigger へアクセス

html
Please pass a name on the query string or in the request body

http://localhost:7071/api/httpTrigger?name=TanakaTaro へアクセス

Hello TanakaTaro!

Azureへの関数アプリのデプロイ

動作していることが確認できたので、Azureへ関数アプリをデプロイします。

前提条件

ResousGroup 作成済
AzureStorageAccount 作成済
未作成の場合は、以前書いた記事を参考にしてみてください。

Azure側での関数アプリの作成

デプロイ先となるAzureの関数アプリを以下のコマンドで作成します。

az functionapp create --resource-group <resource_group> --os-type <os_type> --consumption-plan-location <c_plan_location> --runtime <runtime> --name <app_name> --storage-account <storage_account>

コマンドのオプションは以下のものを利用します。

概要
--resource_group (-g) 作成済のリソースグループ
--os_type functionの動作環境のOS Linux/Windows
--consumption_plan_location (-c) アプリを動作させるロケーション(※注)
--runtime 利用言語 dotnet/java/node/powershell/python
--storage_account (-s) 作成済のAzureStorageAccount

(※注)
ロケーションにより、対応言語が異なる場合があります。
2019/11/05現在、pythonの従量課金プランは日本では提供されていないようです。(プランは以下参照)

リージョン未対応の場合の表示
Requested features are not supported in region. Please try another region.

以下の構成で作成します。

in
az functionapp create -g <resource_groupe> --os-type Linux -c eastus --runtime python --name <function_name> --storage-account <storage_account>
out
Your Linux function app '<function_name>', that uses a consumption plan has been successfullycreated but is not active until content is published usingAzure Portal or the Functions Core Tools.

Azureへのデプロイ実施

以下コマンドで、ローカル環境の関数アプリをAzure環境へデプロイします。

in
func azure functionapp publish <app_name> --build remote
out
Getting site publishing info...
Creating archive for current directory...
Performing remote build for functions project.
Uploading 11.16 MB [###########################----------------------------------------]

...

Remote build succeeded!
Syncing triggers...
Functions in function_name:
    httpTrigger - [httpTrigger]
        Invoke url: https://function_name.azurewebsites.net/api/httpTrigger?code=<接続キー>

上記のようにURLが表示されれば、デプロイ成功です。
表示されているURLで、ローカル環境での接続と同じような結果が表示されます。

実行されたコードは、デプロイ時に同時に生成されるApplicationInsightsにログが残ります。

各種ファイルの詳細

前述までで、作成~デプロイは出来ましたが、あくまでもドキュメントの手順通りに実施したもので、関数アプリを使いこなせているとは言えません。
関数アプリを自由に使いこなすために、各ファイルの中身を確認していきます。

__init__.py

__init__.py は、関数アプリのプログラム本体です。
引数に、azure.functions.HttpRequest 返値に、azure.functions.HttpResponse を定義しています。
その他、特に気になる部分は無し。 普通のHTTP通信のやりとりのように思えます。

__init__.py
import logging

import azure.functions as func


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
             "Please pass a name on the query string or in the request body",
             status_code=400
        )

function.json

関数アプリのもう一つの重要な要素であり、関数アプリに関わる各種設定を記載するファイルです。

function.json
{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

まず、2つの要素があります。

scriptFile は、関数アプリのプログラムファイル名を記載しています。
bindingsは、関数アプリに対する input と output のトリガーとバインド情報を設定します。 
詳細は公式を参照するのが良いかと思います。

bindingsは、以下のような構成になっており、これを踏まえたうえで公式情報を見ればすんなりと理解できそうです。

bindings
{
    "type":"<type_name>",
    "direction":"in または out",
    "トリガー毎の個別設定":"個別設定"
}

本記事で構成している内容だと、

in
{
  "authLevel": "function",
  "type": "httpTrigger",
  "direction": "in",
  "name": "req",
  "methods": [
    "get",
    "post"
  ]
}


inputのトリガーのタイプはHTTP Trigger
認証レベルは"function"レベル
inputのazure.functions.HttpRequestreqと変数定義する
対応するメソッドはGETまたはPOST

と読み取ることができます。

認証レベルについての公式情報

out
{
  "type": "http",
  "direction": "out",
  "name": "$return"
}


outputのタイプはhttp
返却値は関数の戻り値

と読み取ることができます。

$returnについての公式情報
 → $returnを指定すると返り値を応答時の値と認識できるそうです。(C# 以外)

環境設定の所得

az functionapp config appsettings list -g resourcegroupus -n azuresamplefunction -o table

上記に記載したのは、HTTP Trigger時かつあくまでもサンプルの内容なので、他トリガーを利用する際はドキュメントをご覧ください。

host.json

host.jsonは、関数アプリ全体に影響を及ぼす設定です。
初期構築の際は、関数アプリのバージョンを表す情報しか記載されていません。

host.json
{
    "version":  "2.0"
}

関数アプリの同時実行やログの出力設定など、細かい調整を行うもので、本番運用する際には記載必須になるかと思います。
今回は特に気にせず進めるため、詳細は公式情報をご覧ください。

local.settings.json

local.settings.jsonは、ローカル環境構築時に利用される設定情報です。公式情報
デプロイ後の動作には影響しません。

local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureWebJobsStorage": "{AzureWebJobsStorage}"
  }
}

Valuesの値は、関数アプリの環境変数です。
環境変数は、Azure側に存在するので必要に応じて記載します。

{AzureWebJobsStorege}となっている箇所は、ストレージ アカウントの接続文字列です。公式情報
以下の形で記載またはAzureから環境情報を取得して設定する必要があります。

Key 値の例
AzureWebJobsStorage DefaultEndpointsProtocol=https;AccountName=[name];AccountKey=[key]

Azure環境情報取得

in
az functionapp config appsettings list -g <resource_groupe> -n <function_name> -o table
out

Name                            SlotSetting    Value
------------------------------  -------------  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
FUNCTIONS_WORKER_RUNTIME        False          python
FUNCTIONS_EXTENSION_VERSION     False          ~2
AzureWebJobsStorage             False          <接続文字列>
AzureWebJobsDashboard           False          <接続文字列>
WEBSITE_NODE_DEFAULT_VERSION    False          10.14.1
APPINSIGHTS_INSTRUMENTATIONKEY  False          <Application Insightsとの接続キー>

終わりに

AzureFunctionsを初めて利用した際に利用した情報を記載させていただきました。
FaaSは抽象度が高く、どのように動いているのか掴みづらい部分はありますが、CLIを通して、設定ファイルの内容を見つめることで少しづつ理解できるものかと思います。
まだ全然使いこなせていないので、引き続き学習していきます。

誤りがありましたらご連絡いただければ幸いです。

Pythonの仮想動作環境の作成

Pythonの仮想環境切り替えにvenvを利用します。

現在のバージョン確認

in
py --version
out
Python 3.8.0

仮想環境の作成

3.6系仮想環境の作成

別バージョンの仮想環境を作成する場合も、対象のバージョンのPythonをインストールしておく必要があります。
現在インストールされているバージョンを確認してない場合にはダウンロードしておきます。

in
 py --list
out
 -3.8-32 *
 -3.7-32
 -3.6-64

仮想環境作成

py -3.6 -m venv <venv_name>
py -3.6 -m venv venv
in
.\venv\Scripts\activate
(venv) PS C:\**>

再度バージョン確認
3.6系になってます

in
py --version
out
Python 3.6.8
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5