Azure Functionsをローカル環境でデバッグ

#はじめに
最近流行り？のServerlessアーキテクチャーを試すべく、Azure Functionsを調べてみましたがStorageを使うと必ず課金されてしまうようです(微々たるものですが、、)。ということでローカル環境の構築方法を探してみたら普通にありましたので、Node.jsを使って簡単に試してみます。

#動作確認環境
OS: Window 10
Node.js: v4.4.7 
npm:3.10.6
Visual Studio Code: 1.7.2

*Node.jsは6.x LTS or later (required by the Yeoman dependency)が推奨のようですが、とりあえず動きました。

#1. Azure CLI とAzure Functions Core Toolsのインストール

```
npm install -g azure-cli
npm install -g azure-functions-core-tools
```
を実行し、Azure CLIとをAzure Functions Core Toolsインストールします。

#2. Azure functionプロジェクトの作成
以下のようにフォルダを作成し、`func init`コマンドでプロジェクトを作成します。

```
c:\dev\azure>mkdir AzureFunctionsDemo
c:\dev\azure>cd AzureFunctionsDemo
c:\dev\azure\AzureFunctionsDemo>func init
Writing .gitignore
Writing host.json
Writing appsettings.json
Initialized empty Git repository in c:/dev/azure/AzureFunctionsDemo/.git/
```

#3. 簡単なfunctionの作成と実行

`func new`コマンドでテンプレートからfunctionを作成します。

```
c:\dev\azure\AzureFunctionsDemo>func new

     _-----_
    |       |    ╭──────────────────────────╮
    |--(o)--|    │   Welcome to the Azure   │
   `---------´   │   Functions generator!   │
    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

? Select an option...
  1) List all templates
  2) List templates by language
  3) List templates by type
  Answer: 1
```

ひとまず1を入力し、全テンプレートを選択してみます。

```
? Select an option... List all templates
There are 63 templates available
? Select from one of the available templates...
  HttpTrigger-Batch
  HttpTrigger-CSharp
  HttpTrigger-FSharp
> HttpTrigger-JavaScript
  HttpTrigger-Powershell
  ImageResizer-CSharp
  ImageResizer-FSharp
(Move up and down to reveal more choices)
```

今回はHttpTrigger-JavaScriptを選択し、HttpTrigger-JSという名前のfunctionを作成します。

```
? Select from one of the available templates... HttpTrigger-JavaScript
? Enter a name for your function... HttpTrigger-JS
Creating your function HttpTrigger-JS...
Location for your function...
c:\dev\azure\AzureFunctionsDemo\HttpTrigger-JS


Tip: run `func run <functionName>` to run the function.
```

そして、func runコマンドで先ほど作成したfunctionを実行します。

```
c:\dev\azure\AzureFunctionsDemo>func run .\HttpTrigger-JS\ -c "{\"name\": \"Donna\"}"

We need to launch a server that will host and run your functions.
The server will auto load any changes you make to the function.
Do you want to always display this warning before launching a new server [yes/no]? [yes]

Response Status Code: OK
"Hello Donna"
```

毎回警告メッセージを表示するか聞かれるのでとりあえずYesでEnterkeyを押しますが、何も起きないので再度Enterkeyをします。すると、もう１つDOS窓のような画面が立ち上がり、ローカル環境でfunctionが実行されます。

元のWindow(DOS窓)
![image](https://qiita-image-store.s3.amazonaws.com/0/131481/d27a9290-8045-e4bd-fb59-7e3c50db3891.png)

AzureFunction実行中のWindow
![image](https://qiita-image-store.s3.amazonaws.com/0/131481/43753368-4c3c-16d8-fc2d-6df37020337c.png)

AzureFunction実行中のWindowに、今回作成したfunctionのURLが表示されているので、以下のようにパラメーターをセットしてブラウザにURLを入力すると、
http://localhost:7071/api/HttpTrigger-JS?name=test

"Hello test"
とブラウザに表示されます。

#3. Visual Studio Codeでデバッグ

以下のコマンドで現在のプロジェクトをVisual Studio Codeで開きます。

```
c:\dev\azure\AzureFunctionsDemo>code .
```

Visual Studio Codeでindex.jsにBreakpointを設定し、以下のコマンドを実行します。

```
c:\dev\azure\AzureFunctionsDemo>func run .\HttpTrigger-JS\ -c "{\"name\": \"Debugging!\"}" --debug
launch.json configured. Setup your break points, launch debugger (F5), and press any key to continue...
```
launch.json configuredと表示されていますが、VisualStudioでリモートデバッグできるように以下のような内容で自動でlaunch.jsonが作成されます。

```launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Attach to Azure Functions",
            "type": "node",
            "request": "attach",
            "port": 5858
        }
    ]
}
```

また、このタイミングでF5キーもしくは再生ボタンでdebuggerを起動します。
再度Enterkeyを押すとBreakpointまでdebuggerの処理が進みます。

一旦処理を抜けても、ブラウザからfunctionを呼び出すと再度debuggerの処理が動きます。
http://localhost:7071/api/HttpTrigger-JS?name=test

Visual Studio CodeでDebug中の画面。
![image](https://qiita-image-store.s3.amazonaws.com/0/131481/acb53fb1-0311-5779-afb9-69c294a894ba.png)


結構簡単にローカル環境で動かせる印象です。
次はStorage Emulatorを使用し、queueをトリガーにしたAzure functionを試してみる予定です。

#続編
[Azure Functions Queueトリガーを使う](http://qiita.com/tworks55/items/352c738b4e864775919d)
[Azure Functionsをローカル環境からAzure環境にデプロイ](http://qiita.com/tworks55/items/18b816a21a1125e9022a)

#参考URL
[Running Azure Functions Locally with the CLI and VS Code](https://blogs.msdn.microsoft.com/appserviceteam/2016/12/01/running-azure-functions-locally-with-the-cli/)
[Azure Functions における Azure Storage のトリガーとバインド](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-storage)
[Azure Storage の接続文字列を構成する](https://docs.microsoft.com/ja-jp/azure/storage/storage-configure-connection-string)
[開発時と本番環境とで Windows Azure Storage サービスの接続文字列を切り替える](http://devadjust.exblog.jp/20404969/)
[Azure CLI のインストール](https://docs.microsoft.com/ja-jp/azure/xplat-cli-install)