Azureの小ネタ (改)

~Azureネタを中心に、色々とその他の技術的なことなどを~

管理対象サービスID で簡単にAzure Key Vaultにアクセスする

管理対象サービスID 「 Managed Service Identity (MSI)」というのを使うとAzure Key Vaultへのアクセスが簡単になるので、その備忘録。

MSI(インストーラではありません)は、VMやWebAppsなど各種Azure プラットフォーム(VMやWebAppsなど)でサポートしており、ADと連携しているリソースへのアクセスが簡単になります。

これを有効にしておくと、アプリからKey Vaultへのアクセスすると楽になります。

現時点でPreviewですが以下のパッケージを入れます(とKey Vaultも)

例えばアクセスする側のプログラムは以下。

var azureServiceTokenProvider = new AzureServiceTokenProvider();
var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
var keys = client.GetKeysAsync("https://hogekeyvault.vault.azure.net/").Result;
foreach(var key in keys)
{
    Debug.WriteLine(key.Kid);
}

Tokenとってきて、Key Vaultに投げてアクセスさえてもらうという感じになりますが、VMに何も設定してないと当然エラーになるわけですが。

VM側の設定

構成から管理対象サービスIDをオンにします。構成という汎用度の高いメニュー名なので、よく見失います。

f:id:StateMachine:20180310105153p:plain

これを設定すると、ADにこのVMのサービスプリンシパルが登録されます。そして(というこもともと)、localhostに以下のリクエストを投げるとTokenが取得できるようになります。

Invoke-WebRequest -Uri http://localhost:50342/oauth2/token -Method GET -Body @{resource="https://vault.azure.net"} -Headers @{Metadata="true"} 

このTokenをKey Vaultに投げて承認してもらうと、Key Vaultへのアクセスが可能になるわけです。

Key Vaultの設定

アクセスポリシーからアクセスポリシーを追加します。プリンシパルには、VM名を指定します。アクセス許可する範囲は適宜。

f:id:StateMachine:20180310105834p:plain

選択したのち最後に保存します。(よく保存を忘れるので気を付けて)

実行

ここまで設定すると先ほどのアプリが実行できるようになります。

つづく

CreateDocumentQueryAsync メソッドがない

DocumentDBネタが続きます。

クエリを書いていると、Document自身のCRUD操作は非同期になっているのに、クエリは同期メソッドしか用意されていません。

ということで調べていたらIssueが、以下にあがってました。

github.com

現状まだOpenですね。

        static async Task Test(DocumentClient client)
        {
            var query = client
                .CreateDocumentQuery<TestDoc>(UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId))
                .Where(doc => doc.Key1 == "hoge").AsDocumentQuery();

            var list = new List<TestDoc>();
            while (query.HasMoreResults)
            {
                list.AddRange(await query.ExecuteNextAsync<TestDoc>());
            }
        }

中の人が言うには、ExecuteNextAsync をぐるぐるしろってことで、うえのようなコードになりますが、ちょいとださい。フレームワーク側で吸収してほしいなと思う感じです。Open中なので、しばしウォッチしていこうと思います。

DocumentDBのクエリ制限的なもの

Document DBのクエリ制限は、以下の書かれてます。

azure.microsoft.com

翻訳は以下。

https://blogs.technet.microsoft.com/jpitpro/2015/10/05/azure-documentdb/

  • ANDは20個まで
  • ORは10個まで
  • JOINは5個まで
  • UDFは2個まで
  • クエリページ毎に取得できるアイテムが無制限になった

まあ、通常使うキモはAND、OR、JOINの数でしょうか。JOINの数が5までってことは、6階層以上の深さをもつスキーマにクエリかけられないことを意味してる気がします。

あと地味にひっかかったが、JOINした要素に対してORDER BYがサポートされていないことでした。

{
  "id": "hoge",
  "items": [
    {
      "no": 3,
      "name": "hoge"
    },
    {
      "no": 2,
      "name": "fuga"
    },
    {
      "no": 1,
      "name": "baka"
    }
  ]
}

こんなデータがあったとき、

SELECT item.name FROM c 
JOIN item in c.items
WHERE c.id = "hoge"
ORDER BY item.no

Noでソートできません。 Order-by over correlated collections is not supported というエラーで怒られます。stackoverflow でもちらほら似た質問が散見されますからみな同じところで引っかかるんでしょうね。