tech.guitarrapc.cóm

Technical updates

LINE BOT API で緊急避難情報を返すボットのβバージョンを公開しました

熊本地震災害に遭われた方、その関係者の皆様の無事を祈っております。

少しでも力になれることがないかと、LINE BOT API で緊急避難情報を返すBOTを作成したので公開します。

まだLINE BOT API がβバージョンのため、友達上限が50人と苦しい制限があるのが心苦しいです。

目次

ソースコード

Githubで公開していますので、ライセンスの元、ご自由にお使いください。

github.com

使い方

次の手順で利用できます。

  1. BOTと友達になる
  2. LINE で「位置情報」をBOTに送る
  3. BOT から応答がきます

見ていきます。

BOT と友達になる

公開した BOT とは、QR コードで友達になることができます。

QRコードでの友達のなり方は、いくつかのサイトで紹介されています。

appllio.com

LINE で「位置情報」をBOTに送る

BOT とのチャット画面で、位置情報を送ってください。(英語、日本語に対応)

https://help-life.net/?p=1111help-life.net

BOT から応答がきます

BOT が共有された位置情報の緯度/経度を元に 近くの緊急避難所を探します というサービスのURL を返します。

「近くの緊急避難所を探します」ってサービスを、九州の方が使ってくれたらしい

もし共有された位置情報が熊本県の場合ナビタイム災害情報 のページも返します。

近くの緊急避難所を探しますはこのような地図サービスです。

ナビタイムは、避難情報に加えて交通情報なども教えてくれます。

テキストやスタンプを送ると、説明が返ってきます。

2016/4/17 追記

安否情報などが集まっているので、Google クライシスレスポンス情報もBOT応答に足しました。

Public Alerts Help

まとめ

少しでもみなさんの役に立てばと幸いです。

LINE BOT API がβで友達が50人というのは正直かなり厳しいので、なんとか追加してくれるとうれしいのですが.... Slack や Gitter で 公開するのもありかと思います。

Azure Functions - C# を活用するために気をつけていることをまとめてみる

Azure Functions たのしいです。今回は、現時点で グラニにおいて Azure Functions を展開するにあたり気をつけていることをメモしておきたいと思います。

現時点で、リリースされて2週間程度に加えて、プレビュー版なので今後変わる可能性が高いです。

が、いったんのまとめということで。

目次

サンプルコード

Azure Functions に関する記事で扱った内容は、Github にあげています。参考になれば幸いです。

github.com

API Gateway + Lambda ほど API的な利用はできない

これはコンセプトの違いなので、よくも悪くもないです。

API Gateway + Lambda

API Gateway を AWS Lambda の前面におくことで、RESTful API のように展開ができます。

dev.classmethod.jp

これの何が嬉しいかというと、GET や POST などの 各種HTTP Method を自由に組み合わせたり、API共通の Token を設けたり Request Header や Response Header をいじったり、エンコーディング触ったりと、いい感じにフロントエンド(API Gateway)で加工してからロジック(Lambda) に渡せます。カスタムドメインを割り当てたりアクセスURLも統一的に扱えて、バージョニング、デプロイタイミングまで自在です。つまり、本当に Managed RESTful API なんですね。

URL もこのようにAPI Gateway で管理して、Lambda は API ごとに割り当てます。複数の処理も常に統一したアクセスURL で提供できるのがいいです。

https://<gatewayname>.apiname.ap-northeast-1.amazonaws.com/<stage>/<apiname>
https://<customdomain>/<stage>/<apiname>

とはいえ、手元の環境からいい感じでデプロイ、C# サポートがない、など今後にまだまだ期待を持っています。

Azure Functions

ではAzure Functions はどうかというと、あくまでも入力に対して何かをしてくれる関数 であり、関数ごとに個別にURL + tokenを付与したものです。

そのため、次のような URL が発行されます。

https://<FunctionAppName>.azurewebsites.net/api/<FunctionName>?code=<Functionごとに一意な文字列>

外から叩くときも、POST メソッドで application/json しか受け付けられません。雑に叩くとこんな感じです。

gist.github.com

ちなみに PowerShell でInvoke-RestMehotdを使って叩くと、エンコーディングが utf8 じゃないので日本語が化けます。HttpClientを使いましょう。

gist.github.com

Function ごとに一意の文字列が付与されることも含めて、API Gateway + Lambda ほどは RESTful として統一的なアクセスは難しいということです。しかし、似た処理を1つのFunction App にまとめることでアクセスをある程度統一的にできないことはないです。

性質からすると、比較的 Webhook 処理を任せたり、Azure のリソースをイベント発火点としてFunction起動するのが初めの一歩としても役割としても活用しやすいでしょう。

tech.guitarrapc.com

tech.guitarrapc.com

実装において気をつけていること

単純なことです。

#load を活用する

Azure Functions が実行を保証していない以上、処理をつなげるのに Azure Functions を内部で次々と呼び出すネスト構造は不向きです。

そこで、多段 Azure Functions の呼び出しをやめて #load に寄せる のが効果的です。

tech.guitarrapc.com

機微情報は App Settings を使う

コード生埋めは避けましょう。System.Configuration.ConfigurationManager.AppSettings[<string>] で取得できるので、違和感なく扱えるはずです。

tech.guitarrapc.com

拡張メソッドを利用する

拡張メソッドが利用できるかは使い勝手に直結します。積極的に使っていくといいでしょう。

私は、拡張メソッドを Function App の上位階層に配置して、必要に応じて#load で読み込んでいます。こうすることで、再利用性があがっていい感じえす。

tech.guitarrapc.com

tech.guitarrapc.com

安定性の向上

パフィーマンスチューニングのしようがほぼないので、少しだけ設定で気をつけることです。

メモリを増やすと実行が安定する

Azure Functions は、SLA 100% のような必ず実行される というものではありません。実際、グラニでは128MB では50回の実行で 5回程度は失敗を計測しています。

Azure Function を安定的に動かすには、処理によってですが メモリを 128MB から 256MB 程度に増やすのも有効です。

メモリを256MB に増やした後は実行がこけることなく安定するようになったように見えるので、今後も計測監視です。

32-bit Platform のままにする

Azure Functions は、Azure Web Appsなので32bit64bit でプラットフォームが選択可能です。デフォルトが 32bit ですが、現在のところ 64bit にしないことが推奨です。

Azure Functions の父であるDavid Ebbo が質問に解答してくれました。

stackoverflow.com

デプロイ

CI 大事です。

本番系は CI を組む

Azure Functions が、AWS Lambda + API Gateway より圧倒的に楽なのが CI です。特に Github CI は、PRベースとかなり相性が良く最強感あります。

かならず、本番系はCI を組むことを推奨します。Azure Portal と開発環境を可能な限り分離するのは当然あるべき状態です。

tech.guitarrapc.com

テスト環境を用意する

もう1つ大事なのが、テスト環境です。残念ながら API Gateway と違ってステージの考えを持たないため、別に Function App を用意しましょう。

私はこの環境は CI しないことで、好きに触ったり本番を再現したりしています。

開発環境

私はVSCodeLinqPad を使っています。

code.visualstudio.com

https://www.linqpad.net/

本番を Github CI しているので、Visual Studio から直接 Publish というのはなしです。

Visual Studio を使った リモートデバッグ周りの情報が乏しいので、次はその辺ですね。

わからないことは気軽に質問する

公式の推奨は、MSDNフォーラム か StackOverflow(azure-functions タグ) に質問を投げることです。

Msdn forums - Azure Functions

stackoverflow.com

実際、私も StackOverflow に質問を投げてますが、中の人から超速でアドバイスが来ます。すぎょい。

stackoverflow.com

現在は、なぜか Azure Functions の記事を公開すると Azure Functions の中の人に補足されています。そのお陰か Twitter でつぶやくと質問に解答が来たりします。

とりあえずオススメは、ふと調べて疑問に思ったら Twitter で英語でつぶやく + StackOverflow で質問 です。

今後の期待

Azure Functions も AWS Lambda 同様にちょくちょく実行が失敗するします。

そのため、モニター機能が待ち望まれます。GA することで、SLA も少し来るかもしれませんね。

まとめ

現時点で気をつけていることを簡単にまとめました。日々良くなっていっているので、使える機能や面白い活用が思いついたら記事にしたいと思います。

Azure Functions で Monitoring (監視)機能が利用可能になったようで実は?

まだリリースに関する告知がないのですが、Azure Functions で リリースが待たれていた Monitoring Functionality (監視機能) が先ほど利用可能になりました?

azure.microsoft.com

早速見てみましょう。

目次

Monitoring Functionality

ずっと待ち望んでいた機能です。つまり、Function App の実行結果を追うことができそう....?

Monitoring への アクセス

Monitoring には、確認したいFunction App を選択して、Monitoring を選択することでアクセスできます。

何ができるのか

まだごく限られた操作しかできません。ドキュメントが無いので正確ではないかもしれませんが、ぱっと見た感じは以下のとおりです。

操作 内容
閲覧範囲 現在時刻から 過去 24時間が見れます。
期間の操作 結果表示の期間を伸ばす、指定するなどの期間操作はできません。
計測単位 実行ユニット単位です。つまり、ファンクションの実行回数ではありません。
計測対象 個別の Function ではなく、指定したFunction App 全体です。
精度 かなり抜けがあるように見えます。
実際、一日100回以上実行されていますが足りてません。
例えば、22:05、22:08 と実行していますが表示されていません。
ほしいMonitoring はまだリリースされていない

気づかれたでしょうか?そう、Function App の各 Function ごとに Monitor があるということに。

そう、本当にほしい個別のFunctionの実行回数などの監視 が実装されるとしたらこちらでしょう。早速みられるか確認すると?

正座待機!

まとめ

現状の、Function App 全体の Monitoring はちょっと使い物になっていないので待ちましょう。

まぁ Coming Soon ですよ。期待です。

どうしてもほしいなら、適当に Monitoring.csx を作って、New Relic などにAPI で実行記録を投げればいいでしょう。暫定版ですが、どのみち 1min 単位の計測になりそうなので十分でしょう。

Azure Functions - C# で安全に機密情報を渡そう

Azure Functions は、本当に各所で活用できるポテンシャルがあり、すでに多くの実績をグラニで積んでいます。実際グラニでは、プロダクト投入に加えてインフラにおける中心となりつつあります。活躍できるシーンが多く思いつくため、どんどん実装が追加されています。

さて本番投入ということで、検証ステージを超えると気になるのが機微情報(機密情報)です。

「慣れるため、開発中」などいろいろな理由でついついパスワードやToken などをコードに埋め込んでしまうことが多いと思います。

そんな時に、Linux では環境変数にexport Hoge="foo" などとしてコードから分離するのが王道ですが、Azure Functions でどうやってコードと分離するか考えてみましょう。

目次

目標

次のことができるように目指します。

  • Github や Bitbucket をはじめとする、ソースコードのバージョン管理システムに機微情報を含めない
  • CI で同一環境にデプロイする (Immutable に新たに Azure Functions を作成しなおすということはしない)
  • デプロイしたコードから機微情報へアクセスして利用できること

この目標のため、ソースコード内への生埋め込み、app.config などは利用できません。

AWS でもリソースアクセスはInstance Role *1 で制御が可能ですが、悩ましい問題です。

Azure Functions は Web Apps

Azure Functions ではどうするといいでしょうか?実体がWeb Apps、ということはつまり Application Settings (== 環境変数)が利用できます。

Application Settings に機微情報を埋め込む

Web Apps も Azure Functions も、IaaS ではなく PaaS です。とはいえ、Kudu 経由でシェルも触れるのですが、環境変数はシェルからは設定しません。PaaS ということはインスタンスの実体は隠蔽されており、いつ別インスタンスに変わるかはおまかせだからです。

シェルで設定 = 設定したインスタンスでしか参照できずインスタンスが変わると再設定が必要

ということはご理解いただけると思います。そこで利用するのが、App Settings です。これを利用することで、Web Apps が管理するインスタンスが何になっても、共通で参照する環境変数を定義し、インスタンスから参照できます。

さっそく Azure Functions で、App Settings にアクセスしてみましょう。

Function app settings > Settings > Application settings > App Settings

この App settings にKey/Value で環境変数を設定します。今回は、FooKey に対してFooValue です。

App Setting を読み込む

コードからは、App.config を読み込む際と同様に、System.Configuration.ConfigurationManager.AppSettings["<Key>"] で取得が可能です。

1つだけ注意点として、#r "System.Configuration" を追加しておきます。アセンブリが足りないため、System.Configuration;名前空間が参照できないためです。

あとはコードを実行してみます。

gist.github.com

予定どおり、FooKey に設定した FooValue が取得出来ていますね。

また App Settings は、#load "読み込みたい.csx" で指定した外部 .csx ファイルでも読めます。これは、.csx が Function のディレクトリではなく、WWWRoot にある場合でも問題ありません。

まとめ

今回の外部 App Settings 参照も、Github に追加しておきました。

github.com

機微情報をコードから除外できるのは、ソース管理から見るととても大きいです。もちろん Amazon Key Management SystemAzure Key Vault で、暗号化、復号化をするのもいいのです。

が、まぁ、App Settings を使うのが、Azure Functions では妥当ではないでしょうか。やりすぎず、必要十分は確実に満たす方法が用意されているのはいいですね。

*1:つまり IAM Role

Azure Functions - C# で外部.csx ファイルをファンクションにロード可能になりました

Azure Functions で、ファンクション本体の run.csx から、外部の .csx を呼び出せるようになりました!

これは相当大きな改善なので早速見てみましょう。

あ、あと、Azure WebJobsAzure Functions をどう選択するか、中の人の神記事があるので読んでおきましょう。

stackoverflow.com

目次

何がこまっていたのか

AWS Lambda や Azure Functions で少しもんにょりするのが、各種ラムダ処理、ファンクション処理で共通で呼び出すときにどうするかです。これまでどうしていたかというと「それぞれの処理用にラムダ/ファンクションを作って呼び出し」しました。つまり、ラムダ/ファンクションの多段処理(ネスト)です。

ネストの厄介なポイント

ネストを行うと1つのやりたいことのために、リクエストが多重化されます。

それに加えて、AWS Lambda も Azure Functionsも100% 実行が保証されているわけではない、ということが前提にあるため多段にしているとどこで失敗したのか追跡が厄介です。*1

改善に伴う情報

この C# Script (.csx)で外部の .csxファイルを読み込む仕組みがあります。それが、#load キーワードです。#rでは独自アセンブリのリファレンスが可能ですが、#load では 外部.csx ファイルの読み込みが可能になります。

Azure Functions でこの機能を使いたいというIssue がこれです。

github.com

そして、6日たったのでまだかなぁとつぶやくと、安定の中の人から今デプロイした連絡がありました。

外部.csx の参照

さっそく、外部 .csx を配置して参照、呼び出してみましょう。

.csx の配置

参照先の .csx は、Visual Studio Online や Github CI で配置しましょう。

ここでは、Visual Studio Online で配置します。

Visual Studio Online へは、Function app settings > Tools > Visual Studio Online で移動できます。

作ったファンクションと同じディレクトリに test.csxを配置します。

上位のディレクトリにEnumerableExtensions.csx を配置します。

もう1つ上位のディレクトリにNuGetSample.csx を配置します。これは、NuGet パッケージを参照した .csx です。

もし外部 .csx で NuGet パッケージを参照する場合、呼び出し元の Function の project.json でそのパッケージを追加してあげれば問題ありません。

配置した外部 .csx の参照と呼び出し

実際に利用するファンクションで、外部に配置したtext.csxEnumerableExtensions.csx を取り込みます。

この時に利用するのが、#load <対象の.csxファイル名> 構文です。

#load is used to execute a script file. Variables from the loaded script will shadow previously defined script variables in the new script. Example: #load "myScriptContext.csx"

github.com

ではサンプルです。ファンクションのエントリポイントである run.csx で外部 .csx の読み込みを追記します。

  • #load "test.csx"
  • #load "..\EnumerableExtensions.csx"
  • #load "..\NuGetSample.csx"

run.csx で外部.csx で定義したメソッドも呼び出せるようになります。

gist.github.com

コンパイルが成功したことが確認できます。

ちなみに、#load でみるパスを間違えたり、project.json にNuGet追加忘れ、参照やメソッドが足りなければコンパイルエラーが表示されます。安心ですね!

実行してみると?うまく実行されましたね!

まとめ

今回の外部 .csx 参照も、Github に追加しておきました。

github.com

これで Azure Functions のネストがすべて解消されました!非常に素直で極めて強力です。

外部 .csx で NuGet パッケージを参照したければ、ファンクション側の project.json にパッケージを追加すればいいのもわかりやすくていいですね。

Azure Functions いよいよ使える機能が揃いました。残りは、モニター と 実行が時々コケる件ですね。コケるのは、自動的に再実行してくれると嬉しいのですが。

*1:1つのラムダ/ファンクション処理だけなら単純なリトライでいいのですけどね