Visual Studio 2015 のAzure FunctionsでStartしたときのUAC

Microsoft Azure2 Advent Calendar 2016 の3日目の隙間に向けて・・・隙間なネタを・・・!

開始するたびにダイアログがぽこぽこ上がってくるこれ・・・

UACを切ってしまえば・・・でもいいのだけど。それはそれで不安があるしとか思いつつ、もう一ついけそうだと思ってたのが、Visual Studioを管理者モードで起動する

2016-12-04-1

こうすると、親プロセスであるVisual Studioが管理者状態で動いていているので、そこから開始されるFunctionsのローカル実行のプロセスも自動的に管理者権限で動いてくれるということで、UACのダイアログは出てこなくなる。

ただ、Visual Studioに特権が与えられるので、それはそれで不安になることもあるかもしれない。

クリスマス近いんだねー

(メモ)Visual Studio 2015 の Azure Functions プロジェクトに 参照サービスを追加する

Functions単体では、ただコードを書いて、日付を返すとかはできますが、それだけでは、日付を返すとか文字列を変換するとかのことはできても、それは普通にローカルで動くプログラムでも得られるわけで、あまり意味がありません。
Functionsのプロジェクトを他のサービスに接続してみます。

 

プロジェクトのコンテキストメニュー(失敗)

ソリューションエクスプローラー>Functionsプロジェクト>コンテキストメニュー>追加>Connected Service

2016-12-03-1

追加用の画面が表示される
2016-12-03

Azure Storageを選ぶ
2016-12-03-2

既存を選ぶか、Create a New Storage Accountで新規に追加

2016-12-03-3

  1. Azure サブスクリプション を関連付けられているアカウントを選択
  2. サブスクリプションを選択
  3. Storage Account のURLになるものを入力
  4. お好みで料金体系・サービス体系を選択
  5. リソースグループを選択(ここで新規で作ることもできる)
  6. Locationを選択

Azure Storageの画面でAddとしてみると・・・

2016-12-03-4

NuGetのパッケージを追加できずにエラー。
というわけで、この方法ではだめな様子。
ひとまずフィードバックを送信。

functions の場合、プロジェクトの参照というよりは、bindingの定義があってという感じなのもあるかもしれないのでひとまずこの方法ではなさそう。

Functionsの追加から

試しにFunctionの追加から、
テンプレートは、FaceLocatorという、Blobストレージにある画像から顔がある四角形領域を返してくれるもの。

2016-12-03-5

ストレージアカウントの接続文字列を入力する欄が赤くなってますので、ポータルから引っ張ってくる。

2016-12-03-6

この接続文字列は絶対に公開しないように・・・
このように公開してしまった場合は、アカウントを消すか、接続文字列を再生成する必要が出てくる。その場合既存の接続文字列は使えなくなるので、いろいろ面倒。

追加した「FaceLocatorCSharp」の
function.json

{
  "bindings": [
    {
      "type": "blobTrigger",
      "name": "image",
      "path": "images/{name}.jpg",
      "connection": "DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xxxxxx;",
      "direction": "in"
    },
    {
      "type": "table",
      "name": "outTable",
      "tableName": "faceRectangle",
      "connection": "DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xxxxxx;",
      "direction": "out"
    }
  ],
  "disabled": false
}

このファイルにあるbindingsが、作ったfunctionsの入出力の定義そのものになっている。nameにある文字列がfunctionsのメソッドにある引数として以下のように

public static async Task Run(Stream image, string name, IAsyncCollector<FaceRectangle> outTable, TraceWriter log)
{
    ....
}

しかし・・・

F5デバッグ開始をしてみるもののエラーが発生してしまう。
かなり手詰まりではあるが、実際に動いているものがあるということはそこから得られるヒントがある・・・と信じて

ポータルから・・・

ポータルから生成したもののソースコードを見てみると

  {
  "bindings": [
    {
      "type": "blobTrigger",
      "name": "image",
      "path": "images/{name}.jpg",
      "connection": "functionappXXXX",
      "direction": "in"
    },
    {
      "type": "table",
      "name": "outTable",
      "tableName": "faceRectangle",
      "connection": "functionappXXXX",
      "direction": "out"
    }
  ],
  "disabled": false
}

といった形で、appSettings.jsonに設定されたものを指定しているようだ。
なので置き換えた。

それでもエラーはまだ残るため次に、テンプレート作成時には空となっていた
AzureWebJobsStorageおよびAzureWebJobsDashboardにも接続文字列を追加した

これは、ポータルで生成した場合は自動的に追加されているものだった。

FaceLocatorのキー

さらにわかったことがあって、テンプレート「FaceLocatorCSharp」では、VisionAPIを使うことになっているが、このための接続情報をappSettingsに追加してやる必要があった。

それがわかるコードはここで

        client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", Environment.GetEnvironmentVariable("Vision_API_Subscription_Key"));

「Vision_API_Subscription_Key」という設定値を必要としていたので、appSettings.jsonに追加した。

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xxxx",
    "AzureWebJobsDashboard": "DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xxxx",
    "Vision_API_Subscription_Key": "xxxxxxxxxxxxxxxxx",
    "functionapp": "DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xxxx"
  }
}

もちろんこれは使えるものではなく、
https://www.microsoft.com/cognitive-services/en-us/subscriptions
より取得する必要がある

 

 

Visual Studio の拡張機能として

まだ、このFunctionsの拡張機能はPreviewであり今後変わる可能性があると思うが、
現状動くポータルを正解としていけば動かす道は掴んでいけそうであることがわかった。

.funprojを覗いてみて・・・メモ

Visual Studioで読み込まれるプロジェクトファイルはXML形式で、ビルドするために何らかのtargetsファイルを読み込んでいたり、プロジェクトに設定されたファイルを記述していたりするので、のぞいてみた。

今後変わる可能性は十分にあるので、完全に自己満足or趣味

なんと!
ファイルはどれも関連づいていない。
プロジェクトのディレクトリにあるものはすべて一部となる様子。

ビルドの定義は、Micorosoft.AzureFunctions.targetsファイルにあるようで。
Debug|Any CPU
Release|Any CPU

内部の初期値では、.NET Framework 「v4.5.1」ただ、ビルドのログを見てる限りコンパイラが動いてなさそうなので、ダミーに近い。

MSBuildとしてのメインは、Publishなのかなぁという感じがした。

Publish

その中で
\bin
\obj
*.funproj
*.pubxml
*.user
に該当するファイル、フォルダーは対象外としている様子

デプロイするためのリソースは一時的
obj\PublishTemp\
に格納される
現状これは、パターンに該当しないファイル以外をコピーしている。

 

ソース管理

pubxmlファイルはデプロイ先の情報を持っているため、GitHubなどの公開されるソース管理では対象外としたほうがよさそうだ。

Visual Studio 用の Azure Functions拡張機能(Preview)

昨日、まだ出ないだろうと思ってとりあえずな記事書いたところで、
正式なFunctionsの拡張機能が出たようです。

https://blogs.msdn.microsoft.com/webdev/2016/12/01/visual-studio-tools-for-azure-functions/

 

注意点として

  • プレビューであること
  • Visual Studio 2015 Update 3用であること
  • Azure 2.9.6 .NET SDKがインストールされていること

プロジェクトテンプレート

FunctionApp1という名前で作ってみたところ、以下のようなファイルが

Properties
appsettings.json
FunctionApp1.funproj
host.json
Project_Readme.html

これだけだと、ファンクションそのものがないからの状態なんですが、
デバッグ開始(F5)してみると
Azure-Functions-Cliをダウンロードしてくるぞ?と聞かれました。
いいよとすると、コマンドプロンプトのように、ローカルホスト用であるfunc.exeが起動

Listening on http://localhost:7071/
Hit CTRL-C to exit...
Reading host configuration file 'c:\Projects\FunctionApp1\FunctionApp1\host.json'
Generating 0 job function(s)
Starting Host (HostId=sb-v2-functionapp1, Version=1.0.0.0, ProcessId=9404, Debug=False)
No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.).
Job host started
File change of type 'Created' detected for 'c:\Projects\FunctionApp1\FunctionApp1\data'
Host configuration has changed. Signaling restart.
Stopping Host
Job host stopped
Reading host configuration file 'c:\Projects\FunctionApp1\FunctionApp1\host.json'
Generating 0 job function(s)
Starting Host (HostId=sb-v2-functionapp1, Version=1.0.0.0, ProcessId=9404, Debug=True)
No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.).
Job host started
Debugger listening on [::]:5858

特に何もファンクションがないので、Jobは0となってます。

Functionsを追加

Blogに書かれているように
ソリューションエクスプローラー>プロジェクト>コンテキストメニュー>追加>New Azure Function

とすると、テンプレートがずらずらーっと並んでるので追加。
再びデバッグ開始で、

Listening on http://localhost:7071/
Hit CTRL-C to exit...
Reading host configuration file 'c:\Projects\FunctionApp1\FunctionApp1\host.json'
Generating 1 job function(s)
Starting Host (HostId=sb-v2-functionapp1, Version=1.0.0.0, ProcessId=7960, Debug=True)
Found the following functions:
Host.Functions.HttpTriggerCSharp

Job host started
Http Function HttpTriggerCSharp: http://localhost:7071/api/HttpTriggerCSharp

というわけで、ブレークポイントを設定してブラウザから
http://localhost:7071/api/HttpTriggerCSharp
にアクセスしてみると・・・

2016-12-02-1

おおー、変数展開、呼び出し履歴、タスク、診断ツール
と普通にいけてるじゃないですか!!
ローカル環境での実行なので、AzureFunctionsをデプロイしてなくてもいいし。
極端な話、ネットワークにつながってなくても書ける・・・かもしれない?

デプロイ

Blogに書かれているように
ソリューションエクスプローラー>プロジェクト>公開

AppServiceとしてを選ぶと、既存のFunctionsAppのみアイコン付きで出てきました。

2016-12-02-2

そのまま、AppServiceの感覚でデプロイ。

ここからは、せっかく書いた昨日の記事が生きてくるかもしれません。

 

 

Azure Functions をリモートデバッグしながら編集する on Visual Studio 2015

Azure FunctionsがGAしたところで、Visual StudioのFunctions向け拡張機能はまだ出てきていませんが、それまでにVisual Studio(拡張機能)が持っている便利な機能を何か使う方法はないか?ということで。

必要なもの

最初に・・・

Visual Studio 2015を起動していきなりサーバーエクスプローラーを起動します。
出てない場合は、メニュー>表示>サーバーエクスプローラー

資格情報の入力

Azureサブスクリプションが関連付けられているアカウントでログインしておきます。何も出ない場合は、(サーバーエクスプローラー>Azure>コンテキストメニューから)サブスクリプションの管理を開きチェック状態を確認します。
2016-12-01_03

リモートデバッグ

サーバーエクスプローラーのAzureノードから、AppService→「Function App」があるリソースグループ>Functionsのアイコンからコンテキストメニューを表示するとデバッガーのアタッチというメニューがあります。これを選択します。

2016-12-01_04

しばらく待ちます。これはAppService上でリモートデバッガを起動してそこを経由させてアタッチとなるので、少し時間がかかります。

2016-12-01_05

上の画像は、Kuduのプロセスで見た感じ。
リモートデバッグ用のプロセスが起動しています。
これはポータルでは、こんなところに相当します。

2016-12-01_06

上記はポータルのAppService上のアプリケーションの設定にある一部です。

さて、アタッチできて満足しててもよいのですが、
ブレークポイントで息の根・・・じゃなかった、プログラムをブレークしてみたいですね。

リモートファイルを開く

先ほどのサーバーエクスプローラーから、csxファイルを選んでコンテキストメニューを表示して、開くを選びます。

2016-12-01_07

さて開けたところで、デバッグへ。

デバッグ(ブレークポイント)

開いたファイルにブレークポイントを設定します。
2016-12-01_08

このとき、シンボル、モジュールが読み込まれていない状態になっていますが気にしないことにします。というのも、Functionsは常時起動しているわけではないからです。なので、アクセスさせてみましょう。

実行!(ポータル)

ポータルから、テスト実行ボタンを押してみます。
(このほうがリモートしてる感じ出るからね

2016-12-01_09

ポチっと

2016-12-01_10

きたーっ!!

2016-12-01_11

 

というわけで、ここまでです。

ここからデバッグした状態のままリモートファイルを編集することもできます。
インテリセンスは不完全ですが、テキストエディタよりはいいでしょう。
何よりデバッグした状態で、変数を確認することができますので、
想定で実装するよりも、ずっと捗るんじゃないかと思います。

※編集した場合、保存して、同期をしないとサーバーには反映されません。

アドベントカレンダーが始まって、盛り上がってきていますが、正式なToolには期待しつつも、どんなものか?触ることができたら、またきっかけになれば幸いです。

 

Visual Studio 2015 拡張機能 Cloud Explorer

Visual Studio 2017 RCが出ているところにあえて2015からある拡張機能の紹介ですが、この拡張機能は個人的に気に入ってます。

Cloud Explorer for Visual Studio 2015

イイところ

1.ツリー構造をリソースの種類、リソースグループ別でみることができる。

いろいろ試してとかやったり、目的があって作っていたりするときにリソースグループを使うことで、そこにデプロイしているリソースをグループのように見ることができます。後から一括削除とかできたりするので、リソースグループは使うと便利

2.操作するボタンが大きく、リモートデスクトップ環境(iPhone、Android、Mobile)などで操作しやすい

ただ、ほとんど同じことは、サーバーエクスプローラーからできます。
さらにサーバエクスプローラーでしかできないこともあります。
なので、これだけあればいいというものではないですね。

 

デモをするとか、見せるときは文字が大きく見やすいかも。
リソースグループをリソースの種類よりも上位の階層で分類してくれるってのは、いろいろ試してるときは結構助かります。

 

Visual Studio 2017 RC で csx C#スクリプトを読み込む

インテリセンスどころか、色も何もつかないのでどうしてかなーとVS2015ではできていたのにということで調べてみたところ、拡張機能が用意されてました。

https://marketplace.visualstudio.com/items?itemName=IgalTabachnik.AnyScriptCS

上の拡張機能をVS2017RC上から入れて、VS2017RCを再起動したところ無事に動きました。

追記
上記ツールは、MS純正のものではありません。

Azure Functions ローカル Git リポジトリ

Azure Functionsのソースを、ローカルGit管理にしてしまう方法

少し試してポータルで編集している分には、それはそれでいいのですが
慣れた馴染んだエディタで編集したいとき、ローカルマシン上に持っていきたいというときにいいのかな?ということで。

1.ポータルから ローカル Git リポジトリ 設定

ポータルから対象のFunction Appを開き、
Function App の設定>継続的インテグレーションの構成

2016-11-26-4

 

デプロイのブレードが表示されるのでセットアップ

2016-11-26-5

 

ローカル Git リポジトリを選択

2016-11-26-6

ユーザー名パスワードを求められたら、
入力して忘れないようにしておきます。
(2回目以降入力が省略された!

2.ローカルマシンでclone

gitが入っている前提で

[FunctionAppName]には、作成時に入力したFunctionAppの名前を入れます

>git clone https://[FunctionAppName].scm.azurewebsites.net/

2016-11-26-7

忘れないようにしていたユーザー名とパスワードを入力

Cloning into '[FunctionAppName].scm.azurewebsites.net'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
Checking connectivity... done.

 

[FunctionAppName].scm.azurewebsites.net
というディレクトリが作成されていたらできあがり!

vscodeで開いた状態
ちゃんとコミットできる状態になってた

2016-11-26-8

注意点

ローカルGitリポジトリを設定すると、ポータルから編集できなくなります。

その場合、新しい関数を追加したいとき地道にファイルを追加するか。
一度ローカルGitリポジトリを無効にするか。
Azure-Functions-Cliを使う必要がありそうです。

※ローカルGitの切断・セットアップを繰り返しているうちに何かおかしくなった
※Visual Studio拡張機能が待ち遠しい

 

azure-functions-cli installと実行を試してみた

azure-functions-cliとはなんぞや?となるかもしれませんが、
Azure FunctionsがGAされたアナウンスの中でツールについての話がありました。

announcing-general-availability-of-azure-functions

We now have support for creating, running, and debugging Functions locally on Windows, with the beta Azure Functions CLI. For JavaScript Functions on NodeJS, the CLI integrates with Visual Studio Code and sets up debug targets automatically. While the CLI currently only works on Windows, we’re working on support on Mac and Linux.

ということで、NodeJSで動くものですよと。
ひとまずWindowsは動くからと。
私自身NodeJSをほとんど扱ったことがありませんので、何か変なところがあれば教えてください。
というわけで、まずは入れてみました。

1.NodeJSのインストール

nodejs.org からダウンロード。ひとまずv6.9.1 LTSを入れた。
特に何かあるわけでもなく。

2.npmでインストール

npm i -g azure-functions-cli

しばらくまって、完了。

 

3.CLI funcコマンド

まずは、公式に通り「func」「azfun」「azure-function」
のうち短いのでfunc

>func
Azure Functions Cli (1.0.0-beta.5)
Function Runtime Version: 1.0.0.0
Usage: func [context] [context] <action> [-/--options]

Contexts:
azure        For Azure login and working with Function Apps on Azure
function     For local function settings and actions
functionapp  For local function app settings and actions
host         For local Functions host settings and actions
settings     For local settings for your Functions host

Actions:
init    Create a new Function App in the current folder. Initializes git repo. Aliases: init, create
run     Run a function directly

1.0.0-beta.5というバージョン情報、それからこの先に渡すコンテキストの情報が出てきました。

4.作る

最初にフォルダーを作り、カレントディレクトリにして

>func init
Writing .gitignore
Writing host.json
Writing appsettings.json
Initialized empty Git repository in C:/******/Source/samples/.git/

という感じで、gitリポジトリとして初期化され、
host.jsonとappsettings.jsonができてます。

次にfunctionを作ります。

>func function create
     _-----_
    |       |    ╭──────────────────────────╮
    |--(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:

という形でyeomanが起動しました。

1)ですべてのテンプレート
2)で開発言語別のテンプレート
3)で種別のテンプレート
のようです。

2を選ぶと

? Select an option... List templates by language
There are 8 languages available
? Select a language...
  1) Batch
  2) C#
  3) F#
  4) JavaScript
  5) Python
  6) Php
  7) PowerShell
  8) Bash
  Answer:

こんな感じに、4) JavaScriptを選びました。

? Select from one of the available templates...
  FaceLocator-JavaScript
  GenericWebHook-JavaScript
  GitHubCommenter-JavaScript
> GitHubWebHook-JavaScript
  HttpGET(CRUD)-JavaScript
  HttpPOST(CRUD)-JavaScript
  HttpTrigger-JavaScript
(Move up and down to reveal more choices)

ひとまず GitHubWebHookを選ぶ

? Enter a name for your function... (MyAzureFunction)

名前を聞かれるので、とりあえず「GitHubWebHookSample」と入れた
そうすると「GitHubWebHookSample」というディレクトリができてました。
中はこんな感じ

function.json
index.js
sample.dat

5.動かす

>func host start

とすると、権限確認のダイアログが出て続けると以下のような状態に

Listening on http://localhost:7071/
Hit CTRL-C to exit...
Reading host configuration file '***\Source\samples\host.json'
Generating 1 job function(s)
Starting Host (HostId=44d3feb53b1b49439bf13fdc57c64832, Version=1.0.0.0, ProcessId=29564, Debug=True)
Found the following functions:
Host.Functions.GitHubWebHookSample

Job host started
Http Function GitHubWebHookSample: http://localhost:7071/api/GitHubWebHookSample
File change of type 'Changed' detected for '***\Source\samples\data\functions\sampledata'
Host configuration has changed. Signaling restart.
Stopping Host
Job host stopped
Reading host configuration file '***\Source\samples\host.json'
Generating 1 job function(s)
Starting Host (HostId=44d3feb53b1b49439bf13fdc57c64832, Version=1.0.0.0, ProcessId=29564, Debug=True)
Found the following functions:
Host.Functions.GitHubWebHookSample

Job host started
Debugger listening on [::]:5858

一度ホストが上がって、ファイルの変更を検出して再び動いているようです。
この後、いろいろいじってみるとそのたびに起動しなおしたりしてました。

vscodeを起動して、デバッグを構成

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Attach to Process",
            "type": "node",
            "request": "attach",
            "port": 5858
        }
    ]
}

デバッグにアタッチで成功。
ブレークポイントを設定して、
「http://localhost:7071/api/GitHubWebHookSample」にアクセスしてみます

すると・・・

2016-11-26-2

 

 

無事に動きましたとさー
ほっ・・・

Azure Functions を使ってみる

Microsoft Azureのサブスクリプションを持ってる人

https://functions.azure.com/signin

 

ポータルから作る

https://portal.azure.com/#create/Microsoft.FunctionApp

Microsoft Azureのサブスクリプションを持っていない人(1時間限定の無償お試し)

https://functions.azure.com/try

※Microsoftアカウント、Google、 Facebook いずれかのアカウントが必要