Azure Functions V2 を Mac+VSCode で動かすまでの手順

サーバレス系スタックの代表格のひとつである **Azure Functions** は最近どんどん進化しており、今ではMacでも普通に動かせるようになっています。メインの開発がSPAやネイティブでフロントエンドを開発な人も、さくっとバックエンドをサーバレスで作れるようになっておくと便利ですよね。

## Azure Functions 開発環境に必要なライブラリ・ツール群

Mac + VSCodeでAzure Functionsを動かすためには、ざっと以下のようなツール群を入れておく必要があります。なお、MacではAzure Functions V2のみがサポートされています。V2は執筆時点ではプレビューです。

* Node.js
* .NET Core SDK
* Azure Functions Core Tools
* Azurite

### Node.js

Macで開発している人でNode.jsが入っていない人はいないと思いますが、Azure Functions V2の実行で必要なバージョンが入っているかは確認しておく必要があります。執筆時点では、8.4.0以上が必須要件になっています。

* [Azure Functions runtime 2.0 known issues · Azure/azure-functions-host Wiki · GitHub](https://github.com/Azure/azure-functions-host/wiki/Azure-Functions-runtime-2.0-known-issues)

自分のMacでは **Nodebrew** を使ってNodeのバージョンを管理しています。やりたいことに合わせてバージョンを切り替えられるので、とても便利です。

* [GitHub - hokaccha/nodebrew: Node.js version manager](https://github.com/hokaccha/nodebrew)

### .NET Core SDK

Node.jsで開発するのに.NET Coreが必要になるのは若干違和感がありますが、現状ではFunctionsのExtensionを導入する場合に必須なので、 [.NET Downloads for macOS](https://www.microsoft.com/net/download/macos) から.NET Coreを導入しておきましょう。今のところHomebrewでのインストールはサポートされていませんが、Issueはあるのでそのうち実現されるかも。

* [Homebrew formula #533](https://github.com/dotnet/cli/issues/533)

### Azure Functions Core Tools

Azure FunctionsをCLIで実行するためのツールです。もちろんMacもサポートされており、こちらは最近Homebrewでのインストールがサポートされました。

* [GitHub - Azure/azure-functions-core-tools: Command line tools for Azure Functions](https://github.com/Azure/azure-functions-core-tools)

Homebrewを使ったインストール

```bash
brew tap azure/functions
brew install azure-functions-core-tools 
```

これでFunctionsを開発するための```func```コマンドが使えるようになります。

### Azurite

Azure Functionの実行にはAzure Storageが必須になりますが、ローカル開発ではエミュレータの利用が推奨されます。
ただし、Azure Storage Emulator は残念ながらMac環境ではサポートされていないので、最近コミュニティからAzure公式のGithubリポジトリに移管された **Azurite** というエミュレータを導入します。

* [GitHub - Azure/Azurite: A lightweight server clone of Azure Storage that simulates most of the commands supported by it with minimal dependencies](https://github.com/azure/azurite)

Azuriteのインストール

```bash
npm install -g azurite
```

Azuriteの起動は-lオプションで実行ディレクトリを指定できます。

```bash
azurite -l ~/azurite
```

Azurite実行後は、通常のAzure Storageと同様に、 **Azure Storage Explorer** で操作が可能です。

* [Azure Storage Explorer – クラウド ストレージ管理 | Microsoft Azure](https://azure.microsoft.com/ja-jp/features/storage-explorer/)

## Azure Functionsの開発

ここからは個別のFunctionsをローカルで開発する方法です。上記の開発環境が出来ている場合はここからはじめられます。

### プロジェクトの作成

まず、以下のコマンドを実行してFunctionsプロジェクトを初期化します。

```bash
func init my-function-app
```

Azure Functionsの実行には Azure Storage が必須なので、プロジェクトディレクトリに自動作成された```local.settings.json```でストレージアカウントを設定します。ローカル開発環境では通常以下のようにストレージエミュレータを使うように指定します。

```json
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true"
  }
}
```

### Functionの作成

プロジェクトを作成しただけでは実際に実行するFunctionがひとつも無い状態です。なお、プロジェクトには複数のFunctionを作成できますが、 ```local.settings.json``` は共有されるので、接続文字列などの環境変数を共有して良い場合は同一プロジェクト内に複数のFunctionを作成して良いと思います。

以下コマンドでは対話形式でFunctionを作成できます。開発言語とテンプレートを聞かれますので、好きな種類を選択して下さい。

```bash
$ func new
Select a language:
1. C#
2. JavaScript
Choose option: 2
JavaScript
Select a template:
1. Blob trigger
2. Cosmos DB trigger
3. Event Grid trigger
4. HTTP trigger
5. Queue trigger
6. SendGrid
7. Service Bus Queue trigger
8. Service Bus Topic trigger
9. Timer trigger
Choose option: 5
Queue trigger
Function name: [QueueTriggerJS]
$
```

この例では、言語を ```JavaScript``` に、テンプレートに ```Queue trigger``` を選択しました。
これでFunction名のディレクトリができ、配下に以下のファイルが生成されます。

* ```function.json```: Functionの設定ファイル
* ```index.js```: 実行コード

これ以外に ```readme.md``` と ```sample.dat``` ができますが、必要なければ削除して下さい。

### Functionの実行

実際には、ここでコードを編集していきますが、初期生成直後の時点でも稼働確認はできるので、以下コマンドを実行します。

```bash
func host start
```

以下のようなエラーが出る場合は、ストレージエミュレータが実行されていません。

```bash
[2018/xx/xx xx:xx:xx] QueueTriggerJS: Microsoft.Azure.WebJobs.Host: Error indexing method 'Functions.QueueTriggerJS'. Microsoft.Azure.WebJobs.Host: Please verify that the Azure Storage Emulator is running. Microsoft.WindowsAzure.Storage: An error occurred while sending the request. System.Private.CoreLib: An error occurred while sending the request. System.Net.Http: Couldn't connect to server.
```

Azuriteを使っている場合は、別のターミナルセッションで以下コマンドを実行しておきましょう。

```bash
azurite -l ~/azurite
```

ターミナルにAzure Functionsのアスキーアートやその他実行ログが出力され、最終的に ```Job host started``` が表示されれば、Functionがトリガーを待っている状態で正しく起動したことになります。今回はQueueトリガーで作成しましたので、Storage Explorerを使ってキューを作成すればFunctionは問題なく実行されるはずです。

これで、Mac + VSCode環境で Azure Functions のローカル開発環境ができました。あとは好きなようにコードをガンガン書いてデプロイするだけです。

拡張機能のインストールやAzureへのデプロイなどについては、以下の公式ドキュメントを参照して下さい。

* [ローカルでの Azure Functions の開発と実行 | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local)