もう怖くない!サーバーレス入門 - Pythonで行うAzure Functionsの実践

以前から「サーバーレス」という言葉をよく耳にしていたのですが、なかなか手が出せていませんでした。サーバーレスの仕組みはサーバーの管理や運用を自分たちで気にしなくていいため、開発に集中できる魅力があり、使ってみたい仕組みの一つではあります。そこで、Microsoft Azure(以下 Azure)のサービスの一つ、Azure Functionsを使ってみて、HTTPリクエストをトリガにコードを実行までやってみようと思います。プログラミングはPythonで行ってみます。

今回の内容は「Azure Functions をPythonVisual Studio Codeで試してみる」という体験記です。

今回の概要

初めての方だと、だいたい約1.5時間のボリュームかなと思いますが、慣れている方だと30分もかからないと思います。

私はPythonの基本的な書き方を知っているレベルで、Azureの操作はほぼ初めてというレベルでも問題なくデプロイできました。今回は、Visual Studio Code (以下VS Code)を使って、Webからのアクセス(HTTPトリガー)で動くシンプルな関数を作成し、ローカルでテストして最後にAzure上にデプロイすることを目指します。

2. Azure Functionsの基本

「サーバーレス」・「イベント駆動」ってどういうこと?

サーバーレス (Serverless)

「サーバーが存在しない」という意味ではなく、開発者がサーバーの準備や設定、スケール、メンテナンスといったインフラ管理を意識しなくて済む考え方です。クラウドサービス(今回はAzure)が、コードを実行するために必要なリソースを裏側で自動的に管理してくれることになります。

イベント駆動 (Event-driven)

何かの「イベント」が発生したことをトリガーとして、コードが自動的に実行される仕組みです。 例えば以下のようなものがトリガに該当します。

  • 特定のURLにHTTPリクエストが送られてきた時
  • ストレージに新しいファイルがアップロードされた時
  • データベースのデータが更新された時
  • タイマートリガー

Azure Functionsをの良さは?

主なメリットは以下の通りです。

以下に、Azure Functionsのメリットをテーブル形式でまとめました:

メリット 説明
インフラ管理からの解放 サーバーの運用や保守の手間から解放されます。
コスト効率 コードが実行された時間やリソースに対してのみ課金される従量課金が基本です。
自動スケーリング アクセス数によってリソースのスケールアウト・スケールインを行います。
好きな言語で開発 PythonJavaScriptなど多くの言語がサポートされています。

どんなことができる?

PythonAzure Functionsを組み合わせることで、以下のようなアプリケーションが実現できます:

  • シンプルなWeb API / RESTエンドポイントの構築
  • ファイル処理 ⋯ ファイルがアップロードされたら自動でリサイズなど
  • スケジュールされたタスクの実行 ⋯ 定期的なバッチ処理の自動化
  • データベース変更への対応 ⋯ データが変更されたら関連処理を実行

3. 開発の準備:ツールを揃えよう!

動作に必要な環境

以下のソフトウェアが必要です

  • Azureアカウント(無料アカウント作成可能)
  • Python
  • VS Code

今回はWindows11上のWSLUbuntuで実行を行っています。 以下では、WSLの環境設定やAzureアカウントの登録方法に関しては省略しているのでご容赦ください🙇

VS Codeの便利な拡張機能をインストール

今回はほぼVS Codeとコンソール(Windowsターミナル)での操作となります。操作に必要な拡張機能をインストールしておきます。

  1. Azure Tools ⋯ Azure関連の便利な拡張機能パック
  2. Azure Functions ⋯ プロジェクト作成、実行、デバッグ、デプロイを簡単に
  3. Python ⋯ VS CodePythonコードを書くための拡張機能
  4. Azurite ⋯ Azure Storageエミュレーター(今回は使っていないけど)

Azure Functions Core Tools のセットアップ

作成したAzure Functionsのコードをローカルで実行・デバッグするために必要なコマンドラインツールとなります。

  1. VS Codeでコマンドパレットを開く(【Ctrl+Shift+P】)
  2. Azure Functions: Install or Update Azure Functions Core Tools と入力して実行
  3. func --version コマンドで確認

(注意)WSLでエラーが出た場合には下記を参照してください。

WSLではインストールするディレクトリのパーミッションが原因でエラーになるようです。

$ sudo npm install -g azure-functions-core-tools@4 --unsafe-perm=true

ここまでで環境構築が終わりました。

必要なツール一覧(再掲)

ツール名 目的 インストール方法など
Azure アカウント Azureリソースを使うために必要 無料アカウント作成可
Python Functionsのコードを書く言語 公式サイトから
Visual Studio Code 開発の中心となるエディタ/IDE 公式サイトから
Azure Tools Azure関連拡張機能パック VS Code内で検索 & インストール
Azure Functions Functions開発支援 Azure Toolsに含まれる
Python (VS Code拡張) VS CodeでのPython開発支援 VS Code内で検索 & インストール
Azurite ローカルでのAzure Storageエミュレーション VS Code内で検索 & インストール
Azure Functions Core Tools ローカルでのFunctionsランタイム実行・デバッグ VS Codeコマンドパレットからインストール

4. いよいよコーディング!最初の関数を作成&ローカル実行

VS Codeでプロジェクト作成

  1. 保存用フォルダを作成(例:my-python-functions)
  2. VS Codeでフォルダを開く(個人的には先にフォルダを作成しておくと良いと思います)
  3. コマンドパレット【Ctrl+Shift+P】を開き、Azure Functions: Create New Project...を入力し実行

  1. 以下の質問に回答
    • Select a folder: 保存用のフォルダを入力または選択
    • Select a language: Pythonを選択
    • Select a Python interpreter: インストール済みのPythonのバージョンを選択
    • Select a template: HTTP triggerを選択
    • Provide a function name: HttpExampleと入力
    • Select an authorization level: ANONYMOUSを選択

ここまで入力するとテンプレートが展開されて以下のような画面となります。

作成されたプロジェクトの中身

実行が正常に終了するとディレクトリには以下のファイルが生成されます。

functions-project/
├── .venv/               # Python仮想環境フォルダ
├── .vscode/             # VS Code用設定ファイル
├── function_app.py      # ★ 関数のメインコード!
├── host.json            # Functionsホストランタイム設定
├── local.settings.json  # ★ ローカル実行時の設定
├── requirements.txt     # ★ 必要なPythonパッケージリスト
├── .funcignore          # デプロイ時に無視するファイル設定
└── .gitignore           # Gitで無視するファイル設定

特に重要なファイル

  • function_app.py:実際のPython関数コード
  • requirements.txt:依存パッケージの一覧
  • local.settings.json:ローカル実行の設定("AzureWebJobsStorage": "UseDevelopmentStorage=true" が重要)

function_app.py(HTTPトリガー関数)の仕組み

今回の動作の要となるファイルがfunction_app.pyとなります。テンプレートの内容となりますが、内部を確認しておきます。

処理としてはHTTPリクエストのGETでもPOSTでもどちらでも大丈夫ですが、データ内にnameというパラメータがあればそのデータを使用してResponseを返すという処理です。

import logging
import azure.functions as func

# FunctionAppオブジェクトを初期化
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

# @app.routeデコレータでHTTPトリガーを設定
@app.route(route="HttpExample")
def HttpExample(req: func.HttpRequest) -> func.HttpResponse:
    """
    HTTPリクエストを受け取り、挨拶を返す関数
    """
    logging.info('Python HTTP trigger function processed a request.')

    # URLのクエリパラメータから 'name' を取得
    name = req.params.get('name')

    # クエリパラメータに name がなければ、リクエストボディから取得
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    # name が取得できたら、挨拶メッセージを返す
    if name:
        return func.HttpResponse(
             f"Hello, {name}. This HTTP triggered function executed successfully.",
             status_code=200
        )
    # name が取得できなかったら、使い方を示すメッセージを返す
    else:
        return func.HttpResponse(
             "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
             status_code=200
        )

ローカル実行前の重要ステップ

  1. 仮想環境の有効化
# WSLの場合
$ source .venv/bin/activate
  1. 依存パッケージのインストール

依存するパッケージに関してはプロジェクト設定時にrequirements.txtを生成してくれるので、それを使用します。

$ pip install -r requirements.txt
  1. Azuriteエミュレーターの起動
    • コマンドパレット【Ctrl+Shift+P】でAzurite: Startを実行

ローカルで関数を実行

  1. 画面左の【実行とデバッグ】ボタンをクリック

  1. 【Attach to Python Functions】ボタンをクリック
  2. ターミナルに以下のような出力が表示される

ローカルでのテスト方法

方法1: VS Codeから直接実行

  1. Azureアイコン → ワークスペース(ローカル) → Functions → HttpExample を右クリック
  2. 「Execute Function Now...」を選択
  3. リクエストボディを入力(例:{ "name": "ローカルテスト" }

方法2: Webブラウザを使う

  1. ブラウザで http://localhost:7071/api/HttpExample?name=ブラウザテスト にアクセス

方法3: curl コマンドを使う

# GETリクエスト
$ curl "http://localhost:7071/api/HttpExample?name=%E3%83・・・以下略(日本語の場合にはURLエンコードにすること)"

# POSTリクエスト
$ curl -X POST http://localhost:7071/api/HttpExample -H "Content-Type: application/json" -d '{ "name": "curlでPOST" }'

テスト後は、VS Codeのターミナルで【Ctrl+C】または VS Codeデバッグツールバーの【停止】ボタンで関数を停止します。

5. 関数の動作の"きっかけ":トリガーを知る

トリガーとは?

トリガー (Trigger) は、関数コードの実行を開始させる「きっかけ」となるイベントです。今回のHttpExample関数では、特定のURLへのHTTPリクエストがトリガーとなります。

他のトリガーの例: - タイマートリガー:設定したスケジュールで実行 - キュートリガー:メッセージキューに新しいメッセージが追加されたら実行 - Blobトリガー:ストレージに新しいファイルが作成されたら実行 - Cosmos DBトリガー:データベースでドキュメントが更新されたら実行

6. 関数をAzureへデプロイ

VS CodeからAzureにサインイン

  1. VS Codeの左側の【Azureアイコン】をクリック
  2. Azureサブスクリプション名が表示されていれば、サインイン済み
  3. サインインしていなければ【Sign in to Azure…】をクリック

Azure上に関数の設定を構築する

デプロイに必要なAzureリソース作成手順

  1. コマンドパレット【Ctrl+Shift+P】でAzure Functions: Create Function App in Azure...を入力し実行

  1. 以下の質問に回答
設定項目 説明
サブスクリプション 使用するAzureサブスクリプション
Function App名 グローバルに一意な名前(今回はmy-python-function-app-自分の名前のイニシャル‐日付としています
場所(リージョン) Japan Eastとしました
ランタイムスタック 使用するPythonバージョン
メモリサイズ 今回はデフォルト値の2048でよいでしょう
Maximum instance Count 今回は100としました

ローカルのコードをAzureへデプロイ

  1. コマンドパレット【Ctrl+Shift+P】でAzure Functions: Deploy to Function App...を入力して実行
  2. 現在のプロジェクトフォルダを選択
  3. デプロイ先の関数アプリを選択
  4. デプロイ処理が完了するまで待つ

デプロイ後の動作確認

  1. VS CodeのAzure拡張機能ビューを開く
  2. リソース → サブスクリプション → 関数アプリ → デプロイした関数アプリ → Functions
  3. HttpExample関数を右クリックし、【Copy Function Url】を選択

  1. WebブラウザでコピーしたURLにアクセス(例:https://[関数アプリ名].azurewebsites.net/api/HttpExample?name=Azureデプロイ成功
  2. Webブラウザで「Hello, Azureデプロイ成功. This HTTP triggered function executed successfully.」のようなレスポンスが表示されれば成功!

7. 体験してみて⋯

体験すると思ったよりも楽ですね。特に以下の点がいいなと思いました。

良かった点

  1. VS Codeとの連携がいい

    • プロジェクト作成からデプロイまでVS Codeだけで完結する
    • ローカル実行もデバッグVS Codeで可能
  2. Pythonコードの書きやすさ

    • Flaskなどに似たデコレータスタイル
    • 関数定義とトリガー設定がまとまっている
  3. ローカル開発環境の快適さ

    • Core ToolsAzureと同じ環境をローカルで再現
    • Azuriteでストレージもエミュレート

注意点・ハマりどころ

  1. 最初に揃えるツールが多い

    • VS Code本体、Python、Azure Tools、Azurite、Core Toolsと多め
    • WSL環境でのインストールに注意
  2. Azuriteの起動忘れに注意

    • ローカル実行前にAzuriteを起動する習慣は必要そう
  3. Azureリソース名の制約

    • グローバルに一意な名前が必要
    • 使える文字や長さに制限がある

9. おわりに

初心者の自分でも約1時間程度でデプロイまで終了し、サーバーレス開発の一連の流れを体験できたことは大きな収穫でした。最初は「Azure」や「サーバーレス」という言葉に尻込みしていましたが、実際に手を動かしてみると想像以上に取り組みやすく、VS Codeという馴染みのある環境から離れることなく開発できる点が素晴らしいと感じました。

印象的だったのは、コードを書いてから実際に動くものを確認するまでのサイクルの短さです。ローカル環境でのテストが簡単にできるため、安心して開発を進められます。また本番環境での挙動もリアルタイムで確認できる点もいいですね。

また、サーバーレス特有の「コードに集中できる」という利点を肌で感じることもできました。小規模なプロジェクトから始めて、徐々に複雑な機能を追加していくアプローチが、Azure Functionsでは特に有効ではないでしょうか。