リセット状態の Windows から Visual Studio Code + Azure Functions を確実に動かす手順

![Visual Studio Code](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/696e056f-ebda-03a8-98cc-eba10dd917e0.png)

![System](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/6284047b-6c3d-5c3a-2059-7afbcef0d9f4.png)

![Azure Functions](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/ec04af36-54bf-ab94-bbcb-a9467ff5b220.png)


## Azure Functions のクイックスタートが動かない

最近のクラウドはサーバーレスが主流になってきて
クラウドを使い始めるハードルが低くなってきたと思います。
サーバーレスとはクラウドにサーバーを構築しなくても、
関数のコードとそれに関わる設定をアップロードするだけで
クラウドでプログラムが実行できるというサービスです。
具体的には、3大クラウド ベンダーでいえば、以下のサービスです。

- aws の Lambda
- Azure の Azure Functions ← 今回の対象
- GCP の Cloud Functions

どのクラウド ベンダーも公式のクイックスタートやチュートリアルが充実しており、
ネットや公式サポートを検索する環境も整ってきています。

ならばといざチュートリアルを試してみようと書いてある通りにやっても
上手くいかないといった経験がよくあると思います。 
なかなかハードルは下がらないという印象です。


## ケースを絞り、前提条件をなくす

動かない原因は、
古いバージョンの情報だったり、
前提条件を満たしていなかったり、
チュートリアルがいろいろなケースに対応しているために
どのケースを選ぶべきか分からなかったりと
いろいろあります。

そこで、本記事では、特定のケースについて絞り込んで、具体的に説明していきたいと思います。
また、前提条件をなくすために、Windows をリセットした状態から始めて確認しています。
チュートリアルを試すみなさんはリセット状態にしなくてもいいと思います。
開発環境はいろいろありますが最も使いやすいと思っているものを選びました。


## 対象システム

あらかじめ用意する必要があるのは、以下のとおりです。

- Windows 10 2004 64bit （多少古くてもよい）
- Microsoft アカウント [→アカウント作成ページ(Microsoft)](https://account.microsoft.com/)

以下の手順でインストールするものは、以下のとおりです。
すべてのバージョンは、執筆時点の最新版です。
この記事が古くなったら、以下で説明する手順では失敗するかもしれませんがご了承ください。

- Azure Functions 3.1
- Azure Functions Core Tools
- Azure CLI 2.12.1
- .NET Core SDK 3.1
- Visual Studio Code 1.50.0
- C#

これらを使って、クラウド上で C# 言語の関数を動かしてみます。

最後にデバッグ方法も説明します。


## 手順

手順は多いですが、とくに前提とする知識や考慮すべきことはないので、そのまま進めていくことができます。


### Visual Studio Code をインストールします

[https://code.visualstudio.com/](https://code.visualstudio.com/)
をブラウザーで開き、ダウンロードして、実行します。

![Visual Studio Code インストール ページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/2fe9bee2-1278-23d9-737c-5c765038b6a7.png)

インストール オプションはすべてデフォルトで構いません。

インストールが完了したら、Visual Studio Code を起動して
タスクバーにピン止めすることをオススメします。


### 開発に使う PC で Azure Portal にサインインします

[Azure Portal (https://portal.azure.com/)](https://portal.azure.com/)
をブラウザーで開き、サインインして、サインインの状態を維持するように設定します。

![Azure Portal ページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/cdc02328-431b-3e49-37d2-d869cdc1403d.png)

![Azure Portal ホーム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/2ff59b62-1da1-a628-3569-24c76761cbfd.png)

ホーム（Azure サービス）に入ることができたら、ブラウザーを閉じます。

ようこそ！のページになったときは、またサブスクリプションを持っていない状態です。
そのときは、無料使用版を開始してください。

![Azure Portal ようこそページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/0da3fe8b-6da9-7986-8b4b-a178f5d54eff.png)

下記のようにクイック スタートのページになったら、ホーム（左上）を押すと上記のホームになります。

![Azure Portal クイック スタート](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/0e09ce4d-8f8a-c839-f0da-1c3d50d827c0.png)

### Azure CLI をインストールします

https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-windows?view=azure-cli-latest&tabs=azure-cli

![Azure CLI のインストール ページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/01cca2d3-d189-51e9-e7a7-7aa5c3f2fa9e.png)

少し下へスクロールして [ Microsoft Installer (MSI) ] タブを選び、
[ Azure CLI current version ] ボタンを押します。
ダウンロードが完了したら、実行してインストールします。


### .NET Core SDK をインストールします

https://dotnet.microsoft.com/download/dotnet-core/3.1

![.NET Core SDK のインストール ページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/5ffbb2c2-2a27-d769-eec4-033b17ff970e.png)

[v3.1.x] の [ Build apps - SDK ] の列の中にある表の
[ Windows ] の行、[ Installers ] の列の [ x64 ]
をクリックしてダウンロード、実行します。


### Azure Functions Core Tools をインストールします

https://github.com/Azure/azure-functions-core-tools#installing

![Azure Functions Core Tools のインストール ページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/2864f65c-4a31-7e32-04bc-6bf9e5856329.png)

[ Installing ] の [ v3 ] の [ Windows 64-bit ] をクリックしてダウンロードし、実行します。


### Visual Studio Code を閉じます

Visual Studio Code が開いていたら閉じます。

（メモ）次の手順でインストール後に開きなおすことで、
いままでにインストールしたパッケージを認識するのだと思います。

（メモ）今回の手順では必要ありませんが、もし今回作成するプロジェクトがすでにあるときは、
以下の手順をします。

1. __Project__/bin フォルダーと __Project__/obj フォルダーが存在していれば削除します。
  なお、 __Project__ は .csproj ファイルがあるフォルダーのパスです。
2. Visuatl Studio Code を開きます
3. .cproj ファイルがあるフォルダーを開きます（[File >> Open Folder] メニュー）
4. しばらく待って、recommended extensions のインストールを勧められてもインストールしない
  （してもよい場合もある）
5. 「Restore」ボタンが右下に表示されたら押す


### 拡張機能をインストールします

Visuatl Studio Code の拡張機能を次の手順でインストールします。

1. Visuatl Studio Code を開きます（タスクバーにピン留めしたアイコンや、スタート メニューから開きます）
2. Visuatl Studio Code の拡張機能のボタンを押し、検索ボックスをクリックします
    ![Visuatl Studio Code の拡張機能](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/48e95adb-f65f-1af4-fc51-8c02aadd8949.png)
3. 検索ボックスを使って、以下の拡張機能をインストールします
    - Azure Tools
    - C#

公式ドキュメントで「拡張機能」といえば Visual Studio Code エクステンションのことです。


### Visual Studio Code から Azure へ再度サインインします

![Visual Studio Code から Azure へサインイン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/db95244e-1cd2-e6cc-37bd-638363be2bef.png)

Visual Studio Code の Azure ボタン（左）を押し、
Sign in to Azure をクリックします。
Sign in to Azure はいくつもありますがどれでも構いません。
クリックしたらブラウザーが開くので、アカウントを選んでください。

![Azure アカウントの選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/6c92629d-935f-0530-a638-f46000c3f1d4.png)

You are signed in now and can close this page.
と表示されるので、ブラウザーを閉じます。

以下のようにサブスクリプション名が表示されたら成功です。

![Select Subscriptions](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/af802315-ff53-87a0-e304-19cf9da940ce.png)

（メモ）もし、以下のように Select Subscriptionns と表示されたら失敗です。
次の手順を試すと直るかもしれません。

![Select Subscriptions](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/c65d2915-236a-0ae3-cd1f-c063e8cfc602.png)

1. Visual Studio Code で F1 キーをおして Azure: Sign Out を実行する
2. 問題が起きている PC で、 https://portal.azure.com/ に入れることを確認する
3. サブスクリプションを持っていることを確認する
- 参考: [（公式）Azure portal または Azure アカウント センターにおける「サブスクリプションが見つかりません」のサインイン エラー](https://docs.microsoft.com/ja-jp/azure/cost-management-billing/manage/no-subscriptions-found)


### ローカル プロジェクトと最初の関数を作成します

プロジェクトのフォルダーを作ります。
たとえば、デスクトップに try_Azure_functions_cs という名前のフォルダーを作ります。

プロジェクトのフォルダーを Visual Studio Code で開きます（[ File >> Open Folder ] メニュー）

Azure ボタン（左） を押して、Functions の右にマウス カーソルを動かし、
Create New Project（フォルダーのアイコン）を押します。

![Create New Project](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/1dae1978-461d-2f0d-81f4-575ec375cdc8.png)

対話式に質問されるので、以下のように入力します。

- ProjectFolder: __ProjectFolder__
- Language: C#
- Template: HttpTrigger
- FunctionName: __FunctionName__
- NameSpace: __NameSpace__
- AccessRights: Anonymous （あまりセキュアではないので注意）

上記の一部はプロジェクトに応じてよく変更する部分です。
今回の手順では、下記のように置き換えてください。
  - __ProjectFolder__: try_Azure_functions_cs
  - __FunctionName__: HttpTriggerCShap1
  - __NameSpace__: Company.Function

参考: [（公式）ローカル プロジェクトを作成する](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-create-first-function-vs-code?pivots=programming-language-csharp#create-your-local-project)


### 関数をローカルで実行します

F5 キーを押します。
F5 キーを押すと、C# のコードをビルドして、デバッガーと接続した状態の Web サーバーを
ローカルで起動します。

初回のみ、ファイアーウォールから警告されますが、そのまま「アクセスを許可」して構いません。
![Firewall](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/2247feae-f220-c97d-5b49-5258730d3100.png)

成功したら TERMINAL ビューにデバッグ実行中の Web サーバーの URL が緑色で表示されます。

![Web サーバーの URL](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/968179ac-e83f-0985-4a8b-ff895c9a0300.png)

Web サーバーの URL を開く（Ctrl キーを押しながら URL をクリックする）と
関数がコールバックされます。
ブラウザーで表示される内容は、コールバックされた関数の中で作成された内容です。

![成功した時のページの内容](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/cb04e718-842d-69f5-2642-c3651bdffff2.png)

HttpTriggerCSharp1.cs ファイルの Run 関数の中に、ブレークポイントを設定して、Web サーバーの URL を開く（Ctrl キーを押しながら URL をクリックする）と、ブレークします（実行がそこで一時停止します）

Web サーバーの実行を終了するには、TERMINAL ビューで [Ctrl]+[C] を押します。
コードの内容を変更したときは、Web サーバーの再起動が必要です。

以上で関数を実行できましたが、まだクラウド上では実行していません。
通常、ローカルで関数が完全に動くようにしてから、その関数をクラウド上にデプロイします。


### クラウドにデプロイします

今回の場合のデプロイとは、ローカルで実行した関数を Azure の「関数アプリ」
にアップロードすることです。 関数アプリとは、Azure Functions の関数を
REST API で HTTP アクセスできるようにする Azure のリソースです。

Azure ボタン（左） を押して、Functions の右にマウス カーソルを動かし、
Deploy to Function App ボタン（上向き矢印のアイコン）を押します。

![Deploy to Function App](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/fe6b70f8-5764-1889-2e78-644d47648b5b.png)

対話式に質問されるので、以下のように入力します。

- TargetFunctionApp: Create new Function App in Azure
- FunctionAppName: __FunctionAppName__
- Location: Japan East

上記の一部は Azure 全体で唯一の名前に変更する部分です。
以下の例は参考のために書いていますが使えません。
  - __FunctionAppName__: my-function-cs-01234

デプロイが完了するまで、約3分かかります。

参考: [（公式）Azure にプロジェクトを発行する](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-create-first-function-vs-code?pivots=programming-language-csharp#publish-the-project-to-azure)


### クラウド上で関数を実行します

デプロイした関数を呼び出します。 

Azure ボタン（左） を押して、Functions ビューのサブスクリプション名（例：無料試用版）
の中にある関数名（例：HttpTargetCSharp1）を右クリックして [ Copy Function URL ]。

![Copy Function URL](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/3e77deb8-dc1a-fea0-152e-919287fc6486.png)

ブラウザーでコピーした URL を開きます。
  - URLの例： https://my-function-cs-01234.azurewebsites.net/api/HttpTriggerCSharp1

ローカルで実行したときと同じ内容が表示されます。
クラウド上で実行しているので、スマホのブラウザーなどで同じ内容を見ることもできます。

![成功した時のページの内容](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/cb04e718-842d-69f5-2642-c3651bdffff2.png)

以上で、クラウド上で関数を動かすことができました。

参考: [（公式）Azure で関数を実行する](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-create-first-function-vs-code?pivots=programming-language-csharp#run-the-function-in-azure)


### クラウドで実行した関数をデバッグします

クラウド上で実行した場合、デバッガーには接続できません。
ローカルで実行したときに問題なかったのにクラウド上で問題が発生したときは、
log.LogInformation 関数でログを出力しながら解析することになります。

以下の手順でログのモニターを開いてから関数を実行すると、log.LogInformation 関数の出力内容が
ほぼリアルタイムで表示されます。

[Azure Portal](https://portal.azure.com/) >> 関数アプリ >> （アプリ名 __FunctionAppName__） >> 関数 >>
 （関数名 __FunctionName__） >> モニター >> ログ(タブ)

![Copy Funtion URL](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/5e21c9fa-b70b-e410-0475-298a8d35acf2.png)