ごった煮

色々な事を書いてます

Azure App Configurationがアナウンスされました

Azure App Configurationというサービスのパブリックプレビューがアナウンスされました。

このサービスは、アプリケーション設定の管理を便利にしてくれるサービスです。

サービスの概要

App Configurationは、以下のようなことを提供してくれます。

  • 設定のバージョン管理
  • 設定のキーをラベル付けして管理
  • データの保存・転送中の暗号化
  • AzureマネージドIDによるアクセス管理
  • 設定のインポート・エクスポート
  • 設定の動的な変更
  • 二つの設定の比較

変更履歴が管理されているため、アプリケーションのロールバックを行って設定も戻したいといった場合にロールバックを簡単に行うことができます。 現在の仕様では、変更履歴は、7日間保持されるようです。

設定のインポート・エクスポート機能では、jsonyaml、Propertiesファイルの3種類に対応しており、例えば.NETでは、settins.jsonをそのままインポート・エクスポート出来たりと 既存システムからの移行が簡単にできます。

提供されているクライアントライブラリ

現在は、以下の環境向けにクライアントライブラリが提供されています。

それ以外の環境で使用する場合は、REST APIを経由して使用できます。

リソースを作ってみる

App Configurationをとりあえず作成してみましょう。

ポータルで、App Configurationで検索すると出てくるアプリ構成というリソースです。 f:id:papemk2:20190228184310p:plain

名前とリージョンを設定するだけですぐ作成できます。 現在対応しているリージョンは、

  • 西ヨーロッパ
  • 東南アジア
  • 米国西部
  • 米国中西部
  • 米国中部
  • 米国東部

になります。

f:id:papemk2:20190228184537p:plain

作成してリソースに移動すると以下のような画面です。 f:id:papemk2:20190228214707p:plain

各機能へのアクセスは、以下のような感じです。

  • キー値のエクスプローラー : アプリケーション設定の編集
  • 設定の比較 : 二つのアプリケーション設定の比較
  • インポート/エクスポート : 設定のインポート/エクスポート
  • イベント : EventGrid関連の機能(現在は、このリソースでは、このリージョンのイベントはまだはサポートしていません。」のメッセージが表示されて何もできないと思われる)

またアクセスキーは、読み書き可能なキーと読み取り専用キーの両方が提供されます。

まとめ

第一印象で、アプリケーション設定をApp Configurationに移してしまえば、App Configurationの接続文字列だけで設定の共有ができるようになるため、チーム開発で 開発環境の設定を共有したりといったことが簡単に出来そうだなと感じました。

また、App Configurationの接続文字列をKey Vaultに格納してやれば、従来よりもより安全に機密情報を管理出来そうな予感がしたり、個人的にすぐ実践投入したいサービスかなという印象です。

ターゲットフレームワークとServicePointの値に乖離がある場合に考えること

前回の続き。 プロジェクトのターゲットフレームワーク.NET Framework 4.6.x以上なのにServicePointManagerが返す値がそれ以下になることがあったので、そのメモです。

本題

.NET Frameworkで、どのバージョンを使用するかは、プロジェクトのプロパティからターゲットフレームワークを指定することで変更可能です。 例えば4.6.2を指定すれば、アプリケーションは、.NET Framework 4.6.2で動作するようになります。

この設定の注意点として、Web.configのhttpRuntimeは、プロジェクト設定のターゲットフレームワークと連動しません。 なので、ターゲットフレームワークが4.6.2でも元々プロジェクトを作ったときのバージョンがそれ以前だったりすると、httpRuntimeのtargetFrameworkがもっと古くなっており 4.5.2相当の動きをすることがあります。

<httpRuntime targetFramework="4.5.2" enableVersionHeader="false" />

なので、バージョン変更したい場合は、しっかりここも確認しましょう。

まとめ

これにて一件落着

.NET FrameworkでTLS1.2の通信エラーが出た場合の対処方法

最近TLS1.2を強制してくるサービスが増えてきています。

.NET Frameworkのバージョンによっては、デフォルトでTLS1.2が使えないものがあるのでその場合の対処方法のメモです。

使えるプロトコルの確認

ServicePointManager.SecurityProtocol

SecurityProtocolを見ると、使えるプロトコルが分かります。

.NET Framework 4.6.2で、Windows10 17763.253の場合は、Tls, Tls11, Tls12になります。 4.5.2の場合は、Ssl3, Tlsになります。

ここにTls12の記載がない場合、TLS1.2を強制するサービスとの通信ができません。

Tls12をで通信をしたい場合は、SecurityProtocolにTls12を追加する必要があります。

Tls1.2のみにする場合は、

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

とします。

ですが、この場合、ほかのプロトコルが使えなくなるので以下のような感じで他も使えるように設定します。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

まとめ

これにて一件落着

Visual Studio 2019 Preview 1.1のLibrary Managerでライブラリが入れられない際の対処方法

VS2017 15.9.1で入れられていたライブラリが、VS2019 Preview 1.1のLibrary Managerだとすんなり入らなかったので備忘録です。

現象

今回入れたいライブラリは、Materializeです。 VS2017のLibrary Managerの場合、ライブラリをインストールしようとすると以下のjsonがlibman.jsonに出力されます。

{
  "version": "1.0",
  "defaultProvider": "cdnjs",
  "libraries": [
    {
      "library": "materialize@1.0.0",
      "destination": "wwwroot/lib/materialize/"
    }
  ]
}

このjsonならそのままライブラリがインストールされます。

ですがVS2019 Preview 1.1の場合、以下のjsonがlibman.jsonに出力されます。

{
  "version": "1.0",
  "defaultProvider": "cdnjs",
  "libraries": [
    {
      "ProviderId": "cdnjs",
      "DestinationPath": "wwwroot/lib/materialize/",
      "IsUsingDefaultProvider": true,
      "IsUsingDefaultDestination": false,
      "Name": "materialize",
      "Version": "1.0.0"
    }
  ]
}

このjsonの場合、LIB006のエラーが出ます。

https://github.com/aspnet/LibraryManager/wiki/Error-codes エラーコードリストを見ると

libraryの項目がundefinedの場合のエラーとわかるのでlibraryの項目を追加します。

{
  "version": "1.0",
  "defaultProvider": "cdnjs",
  "libraries": [
    {
      "ProviderId": "cdnjs",
      "library": "materialize@1.0.0",
      "DestinationPath": "wwwroot/lib/materialize/",
      "IsUsingDefaultProvider": true,
      "IsUsingDefaultDestination": false,
      "Name": "materialize",
      "Version": "1.0.0"
    }
  ]
}

追加するとLIB005のエラーが出ます。 LIB005は、destinationがundefinedの場合のエラーなのでdestinationを追加します。

{
  "version": "1.0",
  "defaultProvider": "cdnjs",
  "libraries": [
    {
      "ProviderId": "cdnjs",
      "library": "materialize@1.0.0",
      "destination": "wwwroot/lib/materialize/",
      "DestinationPath": "wwwroot/lib/materialize/",
      "IsUsingDefaultProvider": true,
      "IsUsingDefaultDestination": false,
      "Name": "materialize",
      "Version": "1.0.0"
    }
  ]
}

とりあえずこれでエラーが出なくなるのでライブラリが復元できます。

まとめ

destinationに入ってほしい値が、DestinationPath、libraryに入ってほしい値がNameとVersionに入ったので今後jsonの記述方法が変わるとかな気がするんですが、 軽くググっただけだといまいちピンとくる情報に当たらなかったので謎です。 とりあえずこれで一旦一件落着

ASP.NET Core用のLINEログイン拡張を作りました。

ASP.NET Coreには、Twitterなどのサービスを使用した外部ログインを行うためのミドルウェアが提供されていますが、 その中にLINEログイン用のミドルウェアは、含まれていないので今回実装しました。

概要

以下のリポジトリに公開してあります。 github.com

気が向いたらNuGetに公開します。

使い方は、TwitterFacebook、MSアカウントなどと同じでStartup.csのConfigureServicesの中で、下記のように設定するだけです。

services.AddAuthentication()
    .AddLineAccount(options =>
    {
        options.AppId = Configuration["Authentication:Line:AppId"];
        options.AppSecret = Configuration["Authentication:Line:AppSecret"]; ;
    });

この設定、ASP.NET Core MVCの認証を実装したテンプレートにセットすると、以下のようにTwitterFacebookなどのログインボタンが出るところにLineボタンが表示されます。 f:id:papemk2:20190104191041p:plain

これだけでLINEログインを使用したアカウント作成、ログイン処理を実装できます。

最後に

基本的なテストしかしてないので何か見つけたらプルリクください。

Azure MonitorでApp Serviceのモニタリングアラートを飛ばす

この記事は、Microsoft Azure Advento Calendar 2018の13日目の記事です。

https://qiita.com/advent-calendar/2018/azure

はじめに

Azureのサービスを実運用で使用する場合、メトリック監視、ログ分析、アラートといったことを行うかと思います。 その中で今回は、アラート機能についてピックアップしてみようと思います。

以前から存在するApp Serviceに存在するアラート機能(クラシックアラート)は、Azure Monitorと統合され、2019年6月に廃止されることがアナウンスされています。 そのためクラシックアラートを使用している場合は、2019年6月までにAzure Monitorに移行する必要があります。(クラシックアラートからAzure Monitorへの移行ツールの提供作業が進行中とのこと)

Azure Monitorは、Azureのリソースをまとめてモニタリングできる機能になっているので、色々なサービスでアラート設定が分散するといったことがなくなります。

そこで今回は、Azure Monitorを使用してApp Serviceのメトリック監視・アラート処理にする方法について触れてみようと思います。

アラートを構築する前に

今回は、Function Appで例外を出し、アラート受取用のFunction Appでアラートの受け取りを行う構成を作ってみます。 なのでFunction Appを一つ作成し、その中に例外を吐き出す用の関数とアラートを受け取る用の関数を作成します。 アラートを受け取る用の関数は、Httpトリガーである必要があるので、アラート受取用は、必ずHttpトリガーを作成してください。

自分の環境は、2つともHttpトリガーを作成しました。

アラート受取用

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    
    log.LogInformation(requestBody);

    return (ActionResult)new OkObjectResult(requestBody);
}

例外発生用

#r "Newtonsoft.Json"

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
    throw new Exception();
}

またFunction Appのアプリケーション設定に下記の設定を追加してください。

Key Value
AzureWebJobsSecretStorageType Files

アラートを構成する

早速簡単なアラートを構成してみます。 Azure Monitorは、ポータルでモニターの項目からアクセス出来ます。

f:id:papemk2:20181212083755p:plain:w150

モニター内の、アラート > 新しいアラートルールを選択するとアラート作成に移動します。

f:id:papemk2:20181212084124p:plain

アラート作成画面では、 * アラート対象のリソース * アラート条件 * アクショングループ(後述) * アラート内容の詳細

を設定します。 まず最初にリソースを設定します。

f:id:papemk2:20181212084903p:plain

この画面では、サブスクリプションを一番上に、その下にぶら下がるリソースが一覧で表示されます。 最初は、サブスクリプションしか表示されないので「リソースの種類でフィルター」の部分でリソースをフィルターします。

それによりターゲットのリソースが表示されるようになるので監視対象にしたいリソースを選択します。

f:id:papemk2:20181212085217p:plain

ここで設定できるリソースは、1アラートに対して1リソースになります。

次にアラートの条件を設定します。

f:id:papemk2:20181212085723p:plain

アラートのトリガーにできる条件を指定します。 メトリック、アクティビティログなどから条件を指定してトリガーに設定できます。 今回は、簡単に実行出来るように Http Server Errorを使用します。 アラートの条件は、エラー回数が1回以上になったら実行の設定にします。

f:id:papemk2:20181212090420p:plain

次にアクショングループを設定します。

f:id:papemk2:20181212090719p:plain

アクショングループでは、複数のアクションを設定します。 アクションタイプを選択するとそれぞれのアクションタイプに対応した設定画面が表示されます。 今回は、Function Appにアラートを送るように設定するのでAzure Functionを選択します。

Azure Functionの設定項目では、リソースグループ、Function App、Function Appの中の関数を選択します。

f:id:papemk2:20181212091254p:plain

作成が完了したら、「既存の選択」で先ほど作成したアクショングループを選択します。

最後にアラートの詳細を記入してアラートルールの作成を選択します。

f:id:papemk2:20181212092421p:plain

アクショングループについての補足

アクショングループは、通知を送る対象をまとめたものになります。 現在は、下記のサービスと連携することができます。

  • 電子メール
  • SMS
  • Azureアプリのプッシュ通知
  • 音声通話
  • Azure Functions
  • Azure Logic App
  • Webhook
  • ITSM
  • Automation Runbook

ITSMは、Service Now、Provance、Cherwell、System Center Service Managerに接続可能です。

クラシックアラートでは、メールの送信対象に複数のメールアドレスを区切り文字で指定できましたが、Azure Monitorでは、 現状複数メールアドレスを区切り文字で指定できないので、アクションを各メールアドレス分作成するか、通知用のメーリングリストを使用しましょう。

アラートを受け取る

先ほど作成した例外発生用の関数を実行して数分待つとアラート受取用関数が実行されます。

アラート受取用関数が実行されるとRequest Bodyの中に下記のjsonが送られてきます。 最終的に何か処理をする場合は、送られてきたjsonを基に処理を分岐させる形になります。

{
    "schemaId": "AzureMonitorMetricAlert",
    "data": {
        "version": "2.0",
        "properties": null,
        "status": "Deactivated",
        "context": {
            "timestamp": "2018-12-11T15:36:42.4343490Z",
            "id": "/subscriptions/30bc1c24-7c50-471e-97c4-b86a3d9cedb1/resourceGroups/Qiita/providers/microsoft.insights/metricAlerts/%E3%83%86%E3%82%B9%E3%83%88",
            "name": "テスト",
            "description": "",
            "conditionType": "SingleResourceMultipleMetricCriteria",
            "severity": "3",
            "condition": {
                "windowSize": "PT5M",
                "allOf": [
                    {
                        "metricName": "FunctionExecutionCount",
                        "metricNamespace": "Microsoft.Web/sites",
                        "operator": "GreaterThanOrEqual",
                        "threshold": "1",
                        "timeAggregation": "Total",
                        "metricValue": null,
                        "dimensions": [
                            {
                                "name": "ResourceId",
                                "value": "qiitamonitoreception.azurewebsites.net"
                            }
                        ]
                    },
                    {
                        "metricName": "Http5xx",
                        "metricNamespace": "Microsoft.Web/sites",
                        "operator": "GreaterThan",
                        "threshold": "1",
                        "timeAggregation": "Total",
                        "metricValue": null,
                        "dimensions": [
                            {
                                "name": "ResourceId",
                                "value": "qiitamonitoreception.azurewebsites.net"
                            }
                        ]
                    }
                ]
            },
            "subscriptionId": "30bc1c24-7c50-471e-97c4-b86a3d9cedb1",
            "resourceGroupName": "Qiita",
            "resourceName": "QiitaMonitorEception",
            "resourceType": "Microsoft.Web/sites",
            "resourceId": "/subscriptions/30bc1c24-7c50-471e-97c4-b86a3d9cedb1/resourceGroups/Qiita/providers/Microsoft.Web/sites/QiitaMonitorEception",
            "portalLink": "https://portal.azure.com/#resource/subscriptions/30bc1c24-7c50-471e-97c4-b86a3d9cedb1/resourceGroups/Qiita/providers/Microsoft.Web/sites/QiitaMonitorEception"
        }
    }
}

送信済みアラートの管理

Azure Monitorでは、送信したアラートの一覧、内容などを管理する機能が提供されています。 アラートが発生した場合は、この画面でアラートの確認、ステータス変更を行えます。

ステータスは、 * 新規 * 確認済み * クローズ済み

の3種類のステータスがあります。

ステータスを適切に管理すれば、アラートの取りこぼしといったことを減らせるなどのメリットがあります。

まとめ

Azure Monitorのモニタリング機能でクラシックアラートよりも柔軟にアラートの作成や管理ができるようになりました。 クラシックアラートの廃止もすぐにやってくるので、今からアラート設定を行う場合は、必ずこちらを使いましょう。

App Service 以外でも実運用をしようとすると必ずと言っていいほど使うサービスになると思うので是非使いこなしてみてください。

C#のモデルクラスからDictionaryを生成する

タイトルの通り 個人的なメモ程度の簡単な実装です。

使う場面的には、扱ってるAPIがフォームのPOSTしか受け付けてないみたいな仕様の場合に、モデルクラスからリクエストBodyを生成するみたいなことを想定しています。

public static Dictionary<string, string> ToDic<T>(this T model)
{
     var dictionary = model.GetType()
     .GetProperties()
     .Where(t => t.GetValue(model, null) != null)
     .Select(i => (i.Name, i.GetValue(model, null)?.ToString()))
     .ToDictionary(x => x.Item1, x => x.Item2);

     return dictionary;
}

プロパティにクラスとかが入るともうちょっと複雑になりますが割愛

まとめ

json使いたいですね