Azure Functions開発環境をVSCodeに構築する

# 背景
チーム内開発でサーバー管理をなくしたいと思ったので、サーバーレスのサービス（Azure Functions）を利用してみました。今回はVSCode上でAzure Functionsを開発、デバッグ、デプロイする環境の構築について紹介させて頂きます。

# 環境及びツール
- VSCode(Remote-Containers使用、前回の記事をご参照ください↓)
[WSL2にDocker環境を構築してVSCodeのRemote-Containersを使ってみた](https://qiita.com/GiantPanda/items/39bb844d130d210026c7)

- Python 3.9

- Azure

# Azure Functions開発環境構築
## 拡張プラグイン導入
最初にVSCodeでAzure Functionsの開発を行うための拡張プラグインを導入します。詳細は下記リンクから確認できますが、簡単に言うとVSCode上でAzure Functionsの開発、デバッグ、デプロイを可能とするものです。

[VSCode Azure Functions拡張プラグイン](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions)

コンテナを立ち上げると同時に適用したいので、**devcontainer.json**の**extensions**セクションに拡張プラグイン名を追記してコンテナをリビルドします。
```json
"extensions": [
    "ms-azuretools.vscode-azurefunctions"
]
```

Pythonのバージョンを**3.9**に指定します。
```json
"name": "Python 3"
"build": {
    "dockerfile": "Dockerfile",
    "context": "..",
    "args": { 
        "VARIANT": "3.9",
        "NODE_VERSION": "lts/*"
    }
}
```
コンテナ再起動後に下記のような見た目になっていれば正しくインストールされています。
![Azure Functionsインストール.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/b6f4eedb-fa6c-53ff-8b25-392bc63c91aa.png)

## 依存パッケージのインストール
Azure Functionsプロジェクトをビルドするにはpipパッケージ**azure-functions**が必要です。
```shell
pip install -r requirements.txt
```
また、ローカルデバッグを行うには**Azure Functions Core Tools**が必要です。

[Azure Functions Core Toolsのインストール](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=v4%2Clinux%2Ccsharp%2Cportal%2Cbash#v2)

これらのインストールコマンドを**Dockerfile**に追記してコンテナを再起動します。

## Azure Functionsプロジェクトの初期化
Azure Functionsプロジェクトの初期化を行います。**WORKSPACE**右側のプラスボタンをクリックして**Create Function**を選択します。警告ダイアログが表示されますが特に気にする必要はないのでそのまま進みます。
![Azure Functionsテンプレート作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/4cd61395-5f8d-1b50-3f3a-b95b92c5c208.png)
Azure Functionsプロジェクトを設定していきます。

**1.プログラム言語**
使用するプログラム言語です。**Python**を選択します。
![1.プログラム言語選択.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/e6da2375-02f4-65f7-4ef2-3a02bfe9a08b.png)
**2.venv(仮想環境)**
仮想環境を作成する場合に利用するPython環境を指定するオプションです。すでにコンテナ化しているので仮想環境はなしで進めます。**Skip virtual einvironment**を選択します。
![2.仮想環境作成.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/8e8f4772-51fe-23a9-f540-d3c7452a95e0.png)
**3.トリガータイプ**
Azure Functionsを実行する条件を指定します。様々な条件を指定できますが、今回は定期的に実行したいので**Timer trigger**を選択します。
![3.トリガータイプ選択.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/72225d6c-46b7-d6cf-166d-2125e006315d.png)
**4.プロジェクト名**
プロジェクト名を指定します。**qiita_test**を指定します。
![プロジェクト名の指定.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/404966f0-70ba-cd93-5120-99e03605c7c8.png)
**5.実行スケジュール**
cron式で指定します。後からでも変更可能です。デフォルトの**5分毎**で設定します。
![5.実行間隔指定.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/4a8e6ed0-02fc-a426-689a-11ec2dc47b39.png)


上記設定が完了したらプロジェクトフォルダが作成されます。
![プロジェクト作成完了.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/320c956d-4b0c-32b3-232f-8e863f8d0573.png)


- **\_\_init\_\_.py**
Azure Functions本体。

- **host.json**
Azure Functionsの全体設定を記載するファイル。詳細は公式ドキュメントをご参照ください。
[host.jsonレファレンス](https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json)

- **local.settings.json**
ローカル実行時に参照する環境変数を設定するファイル。デプロイ後の関数には影響しません。

以上でAzure Functionsプロジェクトの作成は完了です。

## Function Appの作成
Azure上にFunction Appを作成します。最初に、作成する予定のAzureアカウントにログインします。（Webページが表示されますのでそちらに従って操作します。）
![サインイン.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/e1af24a4-1bff-62a3-8305-7ac1ddd31955.png)
ログイン後は利用できるサブスクリプション一覧が表示されます。使用するサブスクリプションを展開し、**Function App**を右クリックして**Create Function App in Azure**を選択します。
![Azure Functions作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/a1a531fe-b006-3a31-6f7c-0f5bfd9bd163.png)
Function Appの情報を指定していきます。

**1.Function App名**
Function Appの名前です。**qiita-test**にします。
![1.関数名指定.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/06372056-ea25-d5a4-8993-41fda269b98b.png)
**2.ランタイムスタック**
Function Appでランタイム環境です。**Python3.9**を選択します。
![2.ランタイムを選択.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/a6c2c1e6-020d-cefd-a07e-835f293c07a9.png)
**3.デプロイリージョン**
Functionを配置するリージョンです。（必要に応じて選択してください。）
![3.リソースリージョン選択.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/3a8ace36-4db8-9166-c1ab-819ee5ea3c53.png)
設定後、しばらくするとコンソール画面に作成完了メッセージが表示されます。
![Azure Function作成完了.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/3e0bdfab-1484-bf0d-13f0-5bd585077010.png)

## Azure Functionsのデバッグ
**F5**ボタンを押してAzure Functionsのデバッグを行います。最初にストレージアカウントを選択してAzure Functions本体の保存場所を指定する必要があります。ダイアログが表示されたら、**Select storage account**を押下してストレージアカウントを選択します。先ほどAzure Functionsを作成した際に自動で**qiitatest**という名前のストレージアカウントが作成されているのでそちらを選択します。
![ストレージアカウント選択.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/24bd68a2-3326-49bf-c13d-d3430b35fe82.png)
少し待つとコンソール画面にログが表示されますので、正しく実行されたことが確認できます。
![Azure Fucntion実行.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/19394f6a-3602-0225-2498-f637119e8ad8.png)
ブレークポイントを設定しておけばしっかり中断します。
![ブレークポイント.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/6fbe2d2f-5f7d-1f05-f3a2-cda6b0332f6e.png)

## Azure Functionsのデプロイ
作成したAzure FucntionsをAzure上にデプロイします。**WORKSPACE**右上のクラウドアイコンを押下して**Deploy to Function App**を選択します。
![Auzre Functionsデプロイ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/d0e66e65-68ca-8057-6226-1e0236b9e8a1.png)

デプロイの情報を設定していきます。

**1.サブスクリプション**
Azureのサブスクリプションを指定します。（必要に応じて選択してください。）
![1.サブスクリプション指定.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/da7d9aea-5195-afad-1ced-b38b2f7fd0f6.png)
**2.Function App**
デプロイ対象のFunction Appです。先ほど作成した**qiita-test**を選択します。
![2.Function App選択.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/b1d9ec3e-9435-b21a-97a3-e8241a0eb942.png)
Function Appの上書き確認ダイアログが表示されますが、特に問題ありませんので**Deploy**ボタンを押下します。しばらくするとデプロイが完了します。
![Azure Functionsデプロイ完了.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/5d5cfeb0-9d02-14b0-0e48-9341c6e1105a.png)
Azureの方を確認してみます。関数アプリqiita-testに移動します。下記のメトリックの通り、関数が5分間隔で実行されていることが確認できます。
![Azure Fucntion App.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/2d61ee57-df58-a4ba-9a90-c2bb78394c9b.png)
続けてApplication Insightsのログを確認してみます。トレースから関数が正しくトリガーして実行されていることが確認できます。
![Application.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169128/2c5b756b-d9b3-5128-f6b9-8c4d79b1a492.png)


# 最後に
VSCode上でAzure Functionsを開発する手法について紹介しました。Azure Functionsの作成からデプロイまでかなり便利に行えるかと思います。次回はAzure Functionsを使って何か作ってみたいと思います。